Comments On Code

Sep 4, 2013

Predict Fertility in iCal

calendarsAnyone that knows us in real life, knows we're committed Catholics with a large family. We follow Church teaching and avoid contraception and artificial birth control. Having tried several methods of NFP, I have come to the conclusion that at this point in time, a binary system works best for us.

We've tried a few iOS apps, but find their algorithms suspect at best.  CycleBeads are simple and very straightforward. For women whose cycles fall in the range of 26-32 days, the fertile period should fall somewhere in the days 8-19 range. If you're open to adding to your family, use those days. If you're not able at this time, don't. The system has been widely tested and available for many years. It is used effectively in the third world, and claims at least 95% effectiveness.

My history falls well within the requirements for accuracy in the CycleBeads system. But with a large family, a budding new business and in school myself full-time, I need something accurate and obvious. I can't trust myself to move a marker daily, and don't have time to sit and recount nightly.

So, I've created a way to make it even more dead simple using AppleScript, Automator and Calendar (iCal).  On cycle Day 1, I can run an app that automatically enters events for days 8-19 into Calendar, with alerts which tell me which day I'm currently on at 8:00am every morning.

Here's how:

First, create a calendar to hold the cycle data.  Use Command + Space bar to open Spotlight and start typing 'Calendar'.  Hit enter when the Calendar App appears highlighted.  Open the File drop down from the Calendar menu and click "New Calendar".   Name the Calendar 'Fertile'.  Make sure the Calendar sidebar is open on the left of the window.  If it isn't, click the 'Calendars' button at the top left corner of the window.  Click the new calendar you created and hit Command + I to open the Get Info dialog.  Click the color box to choose a suitable color for your events in this calendar.  I chose a spring green for new life/growing.  Click 'OK'.

Now that we have the calendar set up, we'll shut off the default settings for alerts so that we can designate only the alerts that we set.  Open the Calendar drop down from the Application menu and click 'Preferences'.  Click the Alerts tab and set the All Day Events default to 'None'.  Note: if you have created other events with the default setting on, you will need to go in and manually set desired alerts on each event.  Alternatively, you can also choose one of the other options in the default preferences and skip adding alerts in the next step.

Now for the fun stuff.  Open Applescript (Command + Space and start typing 'Applescript', hitting enter when the App name is highlighted).  Type or copy and paste the following script:

tell application "Calendar"

tell calendar "Fertile"

set theDate to current date

set newEvent to make new event at end with properties {summary:"Day 8:Fertile", start date:theDate + 8 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 9:Fertile", start date:theDate + 9 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 10:Fertile", start date:theDate + 10 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 11:Fertile", start date:theDate + 11 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 12:Fertile", start date:theDate + 12 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 13:Fertile", start date:theDate + 13 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 14:Fertile", start date:theDate + 14 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 15:Fertile", start date:theDate + 15 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 16:Fertile", start date:theDate + 16 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 17:Fertile", start date:theDate + 17 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 18:Fertile", start date:theDate + 18 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

set newEvent to make new event at end with properties {summary:"Day 19:Fertile", start date:theDate + 19 * days, allday event:true}

make new display alarm at end of display alarms of newEvent with properties {trigger interval:480}

end tell

end tell

Save it as 'Cycle'.  Since AppleScript for Calendar reads mostly like English, it is fairly straightforward what the script is doing.  Note that if you named your calendar something other than 'Fertile' you need to adjust the code to suit.  Also, if you have chosen the default alerts, you can remove each line that begins "make new display alarm".  What if you want your alert to appear at a time other than 8AM?  Simply set the time in minutes after 'trigger interval': 60 minutes in an hour, 8 * 60 = 480, therefore, 8AM.  Also, you may use negative numbers to set the alert to display for a designated number of minutes before the event.

As a final step, we'll make this script into an app.  Use spotlight (Command + Space bar) to open Automator.  Choose Application as the file type.  Scroll down the Actions menu until you find the 'Run AppleScript' action.  Double click or drag and drop into the box on the right.  Highlight the line in the parentheses and paste in the script.  If you made changes to the script I included, make sure to copy and paste your own version.  Name it 'Cycle' and save in your Applications folder.

Now, when you run the app, it will create all-day events with reminders between 8 and 19 days from the current date.

Resources:

Aug 21, 2013

Mac Tip: Virtual Keyboard

twins on my laptop
My twins after I left my laptop closed but unattended.

I'm an avid coffee drinker and mother of twins. This spells inevitable disaster. About a year ago, my husband upgraded to a Macbook Pro (the subject of my previous post). He gave me his perfectly good, but underpowered for his needs, Macbook. I had a Windows laptop at the time, but knew it was on its last legs. After only using it for a week, my twins knocked my coffee over the keyboard. Not knowing any better, I dried it as best I could and kept using it. When the delete and enter keys started giving me problems, I did what I should have done immediately, and shut it down to dry completely. The delete and enter keys are gone, but everything else functions perfectly well.

Initially, I tried to find some way to remap those keys to different buttons, but I haven't found any success. What I did discover, is that there is a virtual keyboard that can be accessed through the system preferences in OS X. Wherever your cursor is, the virtual keyboard will interact with it, just like the physical one does.

To turn it on, access System Preferences from the Apple menu. Click Keyboard and check the 'Show Keyboard & Character Viewers in menu bar' box. Now there is a new icon in the menu bar near the clock, with an asterisk and rows of dots. Click that button and select 'Show Keyboard Viewer'. A resizable virtual keyboard now floats on top of your windows. I shrink mine as small as it can go and shove it off the left side until I can just see the delete and enter buttons.

This keyboard can also display hints for special characters. While holding the option key, it will display which special characters are associated with which keys.

Aug 20, 2013

Macbook Pro Woe

So, you're in the middle of converting video into a format that Adobe likes to work with, and .....

Exactly. Nothing. Complete freeze up. You force quit and restart. And all you get is the white Apple screen and endless circling wheel.

Now it's your heart that's stopped.

So went my weekend. My husband's year and a half old Macbook Pro needed immediate resuscitation. But more troubling was all the data that hadn't been backed-up yet.

Enter good old friend Google.

Diagnosing the Problem

The first step to a solution is identifying the problem. Without a specific known error, you're swinging with your eyes shut hoping to make contact. First step is to start up in an alternate mode--verbose mode. Verbose mode removes the loading graphic, the Apple screen, and prints the start up processes onscreen. When the boot up hangs, you'll get a text error with which you can plug a search string into Google and hopefully find repair tips.

To enter verbose mode, simply press and hold the Command+V keys while starting up. So, shutdown the mac by holding the power button or Command+Control+power. Hold Command + V and hit the power to start. You will see a black screen with white print. At some point the start up text will display errors. Note what the error says so you can do an internet search for a solution.

With my husbands laptop, he was getting a disk0s2 I/O error, which indicates a harddrive failure.

Rescuing Data

My immediate concern was rescuing the several hours worth of video footage that he had been working on, and the family photos which had not yet been backed up. I could not even start the OS in Safe Mode (Shift + Command + V) or Single User Mode (Command + S). I could boot to the recovery partition--holding Command + R on boot.

In recovery mode, I ran Disk Utility to verify the disk. Frustratingly it said it was okay, nothing to fix. I needed to reinstall the OS, but I didn't want to potentially lose important data.

Here and there I found tutorials on using Firewire or other direct networking to transfer files. I didn't have a firewire and couldn't boot to the modes which would allow peer-to-peer networking. I do have an external hard drive and a USB flash drive. And I discovered that you can access terminal in recovery mode. Also, you can still mount removable drives, like an external hard drive or USB drive.

In recovery mode, the menu bar includes a Tools drop down, which offers a few more tools than the pop up screen shows. You'll find terminal in there.

Commands to Use

Even if you are a complete Terminal novice, and this stuff seems way over your head, you can do this. If you are reading this, likely your system is already in jeopardy. And nothing we are going to do in Terminal is at all even the slightest bit destructive. Our goal is simply to make a copy of your files onto a removable media device so that you can recover them. Two important tips to remember are to type each command accurately, carefully noting spaces and cases. If a file or directory name is two words, use quotation marks around the name. Hit enter to activate the command.

  • The mount command will display the mount path of your external device.
  • The ls command will display everything within the directory (i.e. folder) you are in.
  • The cd to move into different directories.
  • The rsync command to copy the data to a removable device through USB.

Steps

On each of the screenshots, what you type is highlighted in yellow or written after # in the caption. The output is highlighted in blue.

Step 1: Use mount to display the path to your removable device. Look for the text starting /Volumes/... My device has two partitions, so it displays as both /Volumes/MEDIA and /Volumes/DATA. I'll be using the /Volumes/MEDIA partition. Write down your path for future reference.

mount
# mount

Step 2: Use ls to locate the directories that need to be recovered. I believe that Terminal in Recovery Mode drops you into the root directory, so that's what I'll show you. See the directory named Users? That's where we're going next.

mac root drive
# ls

Step 3: Use cd to change directories and navigate around your directory tree. If you know where you are going, you can do this all in one line, but if this is your first time we'll do this in stages. Because we are in terminal as the root user, there is no visual queue that we changed directory, so I also immediately repeated the ls command.

users
# cd Users
# ls

Step 4: We're almost to our home directory. As you can see in the screenshot, my username is max, but yours is likely different. Make sure you use your username and not mine in this next step. It's just a repeat of the previous step, only cd to your username.

your user home folder
# cd [your username]
# ls

Step 5: Now you should be seeing a list of folders you are familiar with. If you are a typical user, you likely have data on your desktop, in your documents folder, and in your pictures folder. Maybe you also have music and movies. You can copy as much as you have space for on your removable device. I'll show how to copy the entire directories, for simplicity. I'll be using the Pictures directory.

Use the rsync command, followed by the -rv options. The r (recursive) instructs the computer to move the named directory, plus all its contents. The v (verbose) is just the same as we used before when diagnosing the error; it displays all the files names so you can see what is being moved. It will work without the v, but will appear to be doing nothing.

Next, we add the path to the directory we want to copy. Remember to change max to your own username. Finally, type the path to your removable device that you noted earlier. If you forgot, you should be able to scroll up and locate the path if you haven't closed the Terminal. Note: if you have an existing folder with the same name, your files will be copied into that folder. If you want to keep it separate, add backup to the end of the command: /Volumes/MEDIA/backup.

Then you simply repeat the same process changing the word Pictures to whatever other directory name you wish to move next.

rsync files to removable device
# rsync -rv /Users/[your username]/Pictures /Volumes/[your device name]

Step 6: This step is optional. If you used the verbose option, you can see the files as they are transferred. But you can also confirm their arrival by cd-ing to the drive. Use the cd command and type the same path to which you have been copying all the files. And there it is among the already existing directories.

successful transfer of Pictures directory
# cd /Volumes/[your device name]
# ls

Repair

After you've recovered your data, you can take whatever steps necessary to fix the problem without worries of data loss. Note that this applies only to actual files and data stored in your file system. Saved passwords and bookmarks are beyond the scope of this post, but if you can locate where they are stored via an internet search (probably in an application library), copying them over would be a repetition of the steps above.

In our case, after I recovered what was vital to us, I chose the option to install the OS from the popup menu. In fact, this did not erase personal data, only rewrote actual operating system files. Had this step not worked, I would have had to wipe the hard drive and then install the OS again, which would have resulted in the loss of all personal data.

Sources: