/dev/trouble
Eric Roller's Development Blog

General

General development topics.

When the NumberFormatter() is asked to output Decimal/NSDecimalNumber values with more than 15 fractional digits, the output is rounded (apparently to the precision of Double numbers). Example:

14 decimals: 3.14159265358979
15 decimals: 3.141592653589793
16 decimals: 3.1415926535897900
17 decimals: 3.14159265358979000
18 decimals: 3.141592653589790000
19 decimals: 3.1415926535897900000
20 decimals: 3.14159265358979000000

Note the trailing zeros which are not expected.

Note that Decimal numbers support a precision of 38-decimals. Example: Decimal.pi.description

3.14159265358979323846264338327950288419

Code to reproduce the rounding problem:

import Foundation

var number = Decimal.pi
let formatter = NumberFormatter()

for width in 10 ... 38 {
    formatter.maximumFractionDigits = width
    formatter.minimumFractionDigits = width
    print(String(width) + " decimals: " +
            (formatter.string(from: number as NSDecimalNumber) ?? ""))
}

Apple feedback ID: FB9835108

The calculation for 256^8 using Doubles works as expected:

(lldb) po pow(Double(256), Double(8))
1.8446744073709552e+19

However, trying to convert the result into a Decimal crashes:

(lldb) po Decimal(pow(Double(256), Double(8)))
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been returned to the state before expression evaluation.

Decimals should handle values with up to 38 digits as mantissa with exponents from –128 through 127.

Apple feedback id: FB7706665

Quite often I find myself in the Terminal and want to open Xcode with the project in the current directory:

% open CurrentProject.xcodeproj

This works just fine, of course, but with the following alias (added to ~/.cshrc), I don't need to know the name of the project, assuming there is always only one project in the current directory:

% alias xcode '\ls | grep xcodeproj | xargs open'
% xcode

N.B. The use of \ls ignores the alias that I have for 'ls'. Instead of ls *.xcodeproj, the pipe via grep avoids errors like "ls: No match.".

P.S. Knowing the name of the project is actually not the problem; since there are multiple items named "Current" or "CurrentProject" in the same folder, the issue is that I can't just type open SHIFT+C<TAB><CR> (where pressing TAB autocompletes the name); instead, I have to type: open SHIFT+C<TAB>SHIFT+P<TAB>.x<TAB><CR>.

Update

The Xcode text editor invocation tool xed can achieve much the same thing; just type:

% xed .

Similar to what I have been doing with subversion, I now also create backups for my git repositories.

Note that the git repositories on the backup host are local repositories (not cloned ones) and that they are named ".git".

From /etc/periodic/monthly/mine.monthly:

if [ -d /Library/Repositories ]; then
  cd /Library/Repositories
  for i in *.git ; do
    # Not a local git repository? Ignore it.
    if [ ! -f "$i/HEAD" ]; then
        continue
    fi
    line="/tmp/monthly-$i.out"
    # File: /Volumes/Backups/Attic/git-file-2016-08-10.bundle
    name="git-`basename $i`-`date +%F`.bundle"
    dump="/Volumes/Backups/Attic/$name"
    if [ ! -f "$dump" ]; then
      echo "Bundling git repository: $name"
      { cd "$i"; git bundle create "$dump" --all; } >& "$line"
      # Change the user for the dump file.
      chown gollum:gollum "$dump"
      # Only output the last stderr line then delete the file.
      tail -1 "$line"
      rm "$line"
    else
      echo "Warning: Dump already exists: $name"
    fi
  done
else
  echo "Error: Repositories directory not found."
fi

The weekly backups are much the same, except that only the three most recent repositories are backed up. Thus, the for loop in /etc/periodic/weekly/mine.weekly changes to:

  for i in `ls -1t *.git | sed '3 q'` ; do
    [...]
    line="/tmp/weekly-$i.out"
    [...]

N.B. I still use TrashLater to keep files for only 6 months in the Attic folder.

Blog Reboot: First Post

- Posted in General by

I have decided to switch my blog to a different backend; one that is easier to maintain and doesn't rely on MySQL (which I always found overkill and difficult to backup). Now I only need to extract my old blog posts from that last database dump file...

Update: Having worked through the dump file in a text editor, I found hundreds of duplicate entries marked as 'inherit' and 'nnn-revision-m'. These entries may be the result of multiple edits of a post. This is exactly the kind of data bloat that I strive to avoid. The current solution stores all entries in simple text files. Easy to back up. Easy to index. No duplication.

Just added a new section to /etc/periodic/monthly/mine.monthly in the attempt to create monthly backups of my subversion repositories, using compressed dump files:

[Update: Now using quoted variable names.] [Update: Now checking "format" file.]

if [ -d /Library/Repositories ]; then
  cd /Library/Repositories
  for i in * ; do
    # Not a subversion repository? Ignore it.
    if [ ! -f "$i/format" ]; then
        continue
    fi
    line="/tmp/monthly-$i.out"
    # File: /Volumes/Backups/Attic/svn-file-2014-01-17.dump.gz
    name="svn-$i-`date +%F`.dump.gz"
    dump="/Volumes/Backups/Attic/$name"
    if [ ! -f "$dump" ]; then
      echo "Dumping subversion repository: $name"
      # Dump into a gzipped file; "Dumped revision n" into temp file.
      { /usr/bin/svnadmin dump "$i" | gzip -c -9 > "$dump"; } >& "$line"
      # Change the user for the dump file.
      chown gollum:gollum "$dump"
      # Only output the last stderr line then delete the file.
      tail -1 "$line"
      rm "$line"
    else
      echo "Warning: Dump already exists: $name"
    fi
  done
else
  echo "Error: Repositories directory not found."
fi

N.B. I also use TrashLater to keep files for only 6 months in the Attic folder.

For /etc/periodic/weekly/mine.weekly I only dump the most recently modified repository since I don't normally work on multiple projects. This is done with a different foreach loop, where we get just one repository file name:

if [ -d /Library/Repositories ]; then
  cd /Library/Repositories
  # List the dir by last modified and get the first entry only.
  for i in `ls -1t | sed '1 q'` ; do
    line="/tmp/weekly-$i.out"
    # [...as above...]
  done
else
  echo "Error: Subversion repositories not found."
fi

phpMyAdmin

- Posted in General by

I see from my web-server log that people like to guess the path to phpMyAdmin in all different variations, colours, shapes and sizes. Now, this is exactly why I have not installed it in a fashion that makes it visible to anyone other than me. Better yet, come to think of it, I have not installed it at all and I don't think I ever will. But if I do, you should probably search for all variations, colours, shapes and sizes of phpMyNeatlyStashedAwayAndHiddenInstallationOfMyAdmin.

While it is convenient to add applications to the Login Items* list, it is also annoying when it takes ages for all of them to launch before you can do any meaningful work.

(*) In the Settings applications, select Accounts, your account and then the Login Items tab.

It occurred to me that one or the other application does not need to be available at login, but it would be nice to load it later. For instance, I don't use Skype during the day, but more in the evenings to contact my friends. So how about launching Skype at 5 p.m.?

The following launchd specification will do exactly that: launch Skype at 5 p.m. (or when not possible, whenever you log in next time):





        Label
        com.skype.skype
        ProgramArguments
        
                /usr/bin/open
                /Applications/Skype.app
        
        StartCalendarInterval
        
                Minute
                0
                Hour
                17
        


Save this file as ~/Library/LaunchAgents/com.skype.skype.plist (note that the Label must correspond to the file name) and wait for magic to happen when you log in next time...

After having spent half an hour looking for a drawing program for vector graphics on the Mac, it occurred to me that I already had one: Keynote .

Obviously, it is aimed at creating stunning presentations, but there is no reason why it cannot be used for any other kind of drawing. When finished, a drawing can be exported as an image file (JPEG, PNG, or TIFF) or simply grabbed from the screen with a screen shot (just use shift-cmd-4 and draw a rectangle).

Keynote is bundles with all new Macs but it is also available separately from the Mac App Store ($20). This price compares well to other graphics applications like OmniGraffle (standard $100, pro $200).

Google Search Tips

- Posted in General by

Added this blog post to get that piece of scrap paper off my desk and also to remember these tips by means of typing them in.

apples oranges Search for pages with both apples and oranges.

apples OR oranges -worms Either or, not others.

"candied apples" Exact phrase.

+fruit filetype:ppt Only the exact word, in PowerPoint presentations.

~fruit site:meals.com Include synonyms, but only on that site.

define:egoism Search after definitions.

BMW 318...328 Search for ranges, e.g. not the bad 316 model.

link:macworld.com Search after sites linking to macworld.com.

info:www.apple.com/se Show information about apple.se.

related:cdon.com Search for similar sites.

**mac*** All words beginning with mac, e.g. macworld, macintosh.

ARN BSL Search for routes between airports.

Harry Potter For books with harry potter, select the book icon.

stocks:AAPL Stock information.

weather Stockholm Search for weather information.

time Cupertino Get the current time for other places.

sunrise Kuusamo Get the sunrise times, try also "sunset".

5*9+(sqrt 10)^3= Evaluate calculations.

10.5 cm in inches Unit conversions.

66 GBP in EUR Currency conversions.

**Shakespeare wrote *** Let Google fill in the blanks.

P.S. Of course, Google has its own help page on this topic.