Skip to main content

files and directories - What kind of check does DirectoryQ exactly perform?


I'm using Mathematica 9.0.1 on Windows XP and my drive letters are assigned as follows: C: and D: are hard local disks, while E: is assigned to some removable media. Now, the situation is as follows


DirectoryQ[# <> ":\\"] & /@ {"c", "d", "e"}


returns {True,True,True}, even when an optical disk isn't in the drive.


To outflank the problem I use a directoryQ function, defined in the code below.


However, it obviously fails against a full hard disk or when I don't have write access. Therefore, I' m wondering about the kind of check DirectoryQ basically performs. Is there a better solution to fix the problem?


   directoryQ[unit_]:=Module[
{root,file,ret},
ret=False;
root=unit<>":\\";
file = FileNameJoin[{root, "testFile.txt"}];
If[
DirectoryQ[root],

Quiet[Export[file,"test","Text"]];
If[
FileExistsQ[file],
DeleteFile[file];
ret=True
];
];
Return[ret];
];


directoryQ["c"]
directoryQ["e"]

Answer



Since Mathematica is written in the C programming language, it is likely that any file-system status operation is doing nothing more than calling C's built-in functions. In this case, that would be stat.


So let's test what stat does on Windows. According to the C language documentation, stat is given the name of something in the file system, and returns a C structure whose fields describe the properties of that thing. In particular, the st_mode field seems relevant:



st_mode: Bit mask for file-mode information. The _S_IFDIR bit is set if path specifies a directory; the _S_IFREG bit is set if path specifies an ordinary file or a device. User read/write bits are set according to the file's permission mode; user execute bits are set according to the filename extension.



I wrote a simple test program in Microsoft Visual C that tests the stat function. Drive C: is my Windows system drive; drive E: is my DVD drive, which currently doesn't have anything in it. Here's what I found:


stat("C:\\WINDOWS") returns success and sets _S_IFDIR

stat("C:\\WINDOWS\\SYSTEM32\\NOTEPAD.EXE") returns success and does not set _S_IFDIR
stat("C:\\") returns success and sets _S_IFDIR
stat("E:\\") returns success and sets _S_IFDIR
stat("W:\\") returns failure

So we can conclude from this that Windows, or at least the stat function on Windows, considers empty DVD drives to be "there." I also have a flash memory stick that I can plug into a USB slot, which I have mapped to drive W, but that "isn't there" when it's unplugged.


This is consistent with what Windows Explorer shows me when I click on "My Computer". I see drive C: with a name, and I see drive E:, even though I get an error message when I double-click on it. I don't see drive W: (my flash memory stick) after I pulled it out of the socket. So Windows does consider an empty DVD drive to be present, which is probably why stat says it's a valid directory.


I have no idea how to find out whether a DVD drive is full or empty in C, much less in Mathematica. But at least we can see the core of the problem.


Comments

Popular posts from this blog

mathematical optimization - Minimizing using indices, error: Part::pkspec1: The expression cannot be used as a part specification

I want to use Minimize where the variables to minimize are indices pointing into an array. Here a MWE that hopefully shows what my problem is. vars = u@# & /@ Range[3]; cons = Flatten@ { Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; Minimize[{Total@((vec1[[#]] - vec2[[u[#]]])^2 & /@ Range[1, 3]), cons}, vars, Integers] The error I get: Part::pkspec1: The expression u[1] cannot be used as a part specification. >> Answer Ok, it seems that one can get around Mathematica trying to evaluate vec2[[u[1]]] too early by using the function Indexed[vec2,u[1]] . The working MWE would then look like the following: vars = u@# & /@ Range[3]; cons = Flatten@{ Table[(u[j] != #) & /@ vars[[j + 1 ;; -1]], {j, 1, 3 - 1}], 1 vec1 = {1, 2, 3}; vec2 = {1, 2, 3}; NMinimize[ {Total@((vec1[[#]] - Indexed[vec2, u[#]])^2 & /@ R...

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

How to remap graph properties?

Graph objects support both custom properties, which do not have special meanings, and standard properties, which may be used by some functions. When importing from formats such as GraphML, we usually get a result with custom properties. What is the simplest way to remap one property to another, e.g. to remap a custom property to a standard one so it can be used with various functions? Example: Let's get Zachary's karate club network with edge weights and vertex names from here: http://nexus.igraph.org/api/dataset_info?id=1&format=html g = Import[ "http://nexus.igraph.org/api/dataset?id=1&format=GraphML", {"ZIP", "karate.GraphML"}] I can remap "name" to VertexLabels and "weights" to EdgeWeight like this: sp[prop_][g_] := SetProperty[g, prop] g2 = g // sp[EdgeWeight -> (PropertyValue[{g, #}, "weight"] & /@ EdgeList[g])] // sp[VertexLabels -> (# -> PropertyValue[{g, #}, "name"]...