Hiding and showing files on OSX

OSX Mountain Lion hides a lot of files that were visible in previous versions. You make them visible in the finder with a single line of code in the Terminal.

For example, this line makes the contents of the /usr directory visible.

sudo chflags -R nohidden /usr

And this one makes your Library folder and its contents visible.
sudo chflags -R nohidden ~/Library

And this one makes the main Library folder and its contents visible.
sudo chflags -R nohidden /Library

If you are setting up Apache on you computer so you can test websites before deployment, you might want to make the private folder visible.
sudo chflags -R nohidden /private/

The first part of the command, sudo, just means that you will be prompted for your computer password before the command is executed.

Sometimes I want to see all the files in the Finder so I enter this line in the terminal.
sudo defaults write com.apple.Finder AppleShowAllFiles TRUE
Restart the Finder with
killall Finder
or use Force Quit to relaunch the finder.
After I’ve done whatever it was that required access to all the files, I usually turn them back off by changing TRUE to FALSE

Audacity on OSX Mountain Lion

Audacity is a free and open sound editor that works on many platforms, including OSX. It is capable of recording and editing vocals and music. However, because of the broken patent system in the US, you cannot open or save files in MP3 or M4A format. The workaround is to download the encoders from a country where the patent system isn’t broken and install them on your computer. The download process is simple. From the Preferences-Libraries section of Audacity click on the Download button for either of the Libraries. It should take you to this page. Follow the links to the download site and install the libraries. Unfortunately, Audacity doesn’t find the new libraries when using Mountain Lion (and I suspect the same is true on Lion). And when you try to find them manually, you can’t see the /usr directory where they are located. There is a simple fix that requires a single line in the terminal.

Open the terminal and you’ll see a command prompt. It should look something like this.
macintosh-users-computer$
Copy text after the $ on the line below and past it after the $ in the terminal.
macintosh-users-computer$ sudo defaults write com.apple.Finder AppleShowAllFiles TRUE
You will get a prompt for your password. Enter your user password for the Mac.
Now restart the finder by going to the Apple in the top left of the screen and clicking on Force Quit option. Click on Finder and then choose Relaunch. The screen will go blank and all the icons will disappear. When they return open the Preferences-Libraries section of Audacity, click on the Locate button to locate the MP3 library and browse to the folder /usr/local/lib/audacity/. You’ll see a file called libmp3lame.dylib. Choose it. Restart Audacity and both the MP3 and FFmpeg libraries should show up.

Now go back to the finder and use the up arrow key to show the previous line. Backspace to change TRUE to FALSE and hit Return. Restart the finder and everything will be back the way it was.

Ternary operator

Ternary operators are a concise way to write conditional statements that have two possible outcomes. Rather than writing a longer series of if/then/else statements you can write one line that makes it clear what the two choices are.

In this example from iOS, I use a string for direction—either clockwise or counterclockwise—and translate it to a number for use in the formula. That way I don’t have to remember whether -1 is clockwise or counterclockwise when calling the method. I can use natural language to call the method and let the ternary operator take care of the conversion to the value I need in my formula. And I can change my formula at a later date without having to go back and find all the method calls.

Here’s the method call and the operator


- (void)spin:(NSString *)direction withDuration:(float)duration withScale:(float)scale {
    
    int rotation = ([direction isEqualToString:@"clockWise"] ? 1 : -1);

And then use rotation later to determine which way the object rotates


view.transform = CGAffineTransformRotate(CGAffineTransformScale(transform, 1.0, 1.0), rotation * 2*M_PI/3);

Here’s another example, where I want to pass in a value, but make sure that it isn’t less than one. In this case I’m passing in an integer and rather than doing a series of complicated if/then/else statements I just put the ternary operator in where the integer goes.


self.showRewards = [[ShowRewards alloc] initWithParentView:self.view withLevel:(rewardLevel > 0 ? rewardLevel : 1) ];

I also use it in PHP code for plurals. Something like this is what I use.

$text = "The update was successful. $recordsUpdated " . ($recordsUpdated > 1 ? 'records were updated.' : 'record was updated.');
echo $text;

And I use it to write one set of code that works for two inputs. In this case I have a page that displays all of the titles that are downloadable from Gumroad. Since people are only interested in the Mac or Windows version, I put them on two different pages—but I use the same code. The first part reads in the page type from the URL and puts up a title for Macintosh or Windows.


if ( isset($_GET['page']) ) { $MacWin  = mysql_real_escape_string($_GET['page']); }  else { $MacWin  = 'Win';} 

echo "<div id='wideMargins'>";
$MacintoshWindows = ($MacWin == 'Mac' ? 'Macintosh' : 'Windows');
echo "<h2 class='NewSection'>Download $MacintoshWindows Compatible Titles from Gumroad</h2>";

Then in the SQL statements I pull the appropriate titles. My column names are GumroadURL_Mac and GumroadURL_Win so the $MacWin variable is substituted into the SELECT statement.


$qry = "SELECT *
        FROM product, product_instance
        WHERE product.id = product_id
        AND GumroadURL_$MacWin IS NOT NULL
        ORDER BY name";

I use a full ternary operator to get the right column from the row.


for ($i = 0; $i < $numRows; $i++) {
    $row   = $res->fetch_array();
    $name = $row['name'];
    $tagline = $row['tagline'];
    $GumroadURL = ($MacWin == 'Mac' ? $row['GumroadURL_Mac'] :$row['GumroadURL_Win']);

As you can see, it makes the code much easier to read and in this example, I have one page of code that easily generates two web pages.

Make a file invisible.

On Unix-like systems (e.g. Linux and OSX) you can make a file invisible with the following command:
setFile -a V /Users/userid/Desktop/untitled\ folder

To make it visible again, just change the V to a lower case v.
setFile -a v /Users/userid/Desktop/untitled\ folder

In this example, from OSX, I typed setFile -a V and then dragged a folder from the desktop to the command line. userid is really my userid. Unless you changed it, it is the same as your command prompt i.e userid$. It’s a bit harder to make a file visible, since you can’t drag it in from the finder.

break;

This is another programming tool that I don’t recall ever using before. Normally in a loop I cycle through the elements and do something with each item. For example, this Objective C method loops through all the words in the shuffledWords array and returns a list of the words. The for loop in this case uses ‘fast enumeration’ to select each object in the array.


- (Word *)getAndOrButWord:(NSString *)group {
    Word *wordToReturn;
    for( Word *aWord in self.shuffledWords ) {
        if ( [group isEqual:aWord.group] ) {
            wordToReturn = aWord;
        }
    }
    return wordToReturn;
    
}

And this is part of a method that uses the more traditional for loop that explicitly loops through all of the items in an array.


for (NSInteger i = 0; i < [self.prefsCategory1 count]; i++) {
            if ( [[self.prefsCategory1 objectAtIndex:i] isEqualToString: @"1"]) {
                NSString *levelAndPart = [NSString stringWithFormat:@"PREFS01_NAME Part %i", i];
                [self.selectedCategories addObject:levelAndPart];
            }
        }

In both of these cases each item is looked at and appropriate action taken. However, you can break out of the loop early if you don’t need to look at each item. In this simplified example, I only need four items that match the criterion so there is no point in looping after I’ve found four.


for ( Word *gWord in wordsInGroup ) {
    [wordListToReturn addObject:gWord];
    if ( [wordListToReturn count] == 4 ) break;
}
NSLog(@"I've broken out of the loop");

Control goes out of the loop entirely, just as if all the items had been looked at.
Here is a real world example with multiple break statements. In this case I have an array of 200 objects (girls with colored backpacks) and I want four items from the array. The backpacks are colored and have a different colored stripe on them. In the game I ask the child to show me the backpack that is, for example, red and green. But I don’t want to display a green and red backpack on the screen since it would be confusing to the child. There are two breaks in this example. First I loop through the ‘wordListToReturn’ array to see if the backpack can be added. If it can’t then there is no point in looking at the rest of the items in the array so I break out. This takes me to the outer loop and I pick the next object in the backpack array. Once I get four items I don’t need to continue, so there is another break that takes me out of the loop entirely.


NSInteger wordsToReturnCount = 1;
    for ( Word *gWord in wordsInGroup ) {
        // Add the first item to the list
        if ( ![wordListToReturn lastObject]) {
            [wordListToReturn addObject:[wordsInGroup objectAtIndex:0]];
            NSLog(@"First Word added %@", [wordListToReturn objectAtIndex:0]);
        // Loop through after the first word in in the list
        } else {
            BOOL addWord = YES; // Assume you'll add the word unless there is a match
            NSLog(@"gword is %@", gWord.image);
            // Look through all the words in the return list and see if this word matches
            for ( Word *lWord in wordListToReturn) {
                NSArray *gWordColors =[NSArray arrayWithObjects:gWord.color1,   gWord.color2, nil];
                NSArray *lWordColors = [NSArray arrayWithObjects:lWord.color1, lWord.color2, nil];
                
                [gWordColors sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)];
                [lWordColors sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)];
                
                NSString *sortedgWordColors = [NSString stringWithFormat:@"%@ %@", [gWordColors objectAtIndex:0], [gWordColors objectAtIndex:1] ];
                NSString *sortedlWordColors = [NSString stringWithFormat:@"%@ %@", [lWordColors objectAtIndex:0], [lWordColors objectAtIndex:1] ];
                NSLog(@" gWord: %@, lWord %@", sortedgWordColors, sortedlWordColors);
                if ([sortedgWordColors isEqualToString:sortedlWordColors]) {
                    addWord = NO;
                    break;
                }
            }
            if (addWord) {
                [wordListToReturn addObject:gWord];
                NSLog(@"Word added");
                wordsToReturnCount++;
            }
            if (wordsToReturnCount == 4 ) break;
        }
    }