Services to sum or subtract highlighted numbers and calculate equations

Years ago, I discovered the convenience of treating the Spotlight search as a calculator.  If you paste in an equation, the top result will be what the calculator app produces given the math you’ve typed or paste in.  I take a lot of notes in my work and frequently have a simple equation to calculate or numbers to sum or subtract.  It’s easy enough to copy and paste an equation into spotlight or paste a set of numbers (with some manual clean-up) to Excel or even search & replace with plus or minus signs & paste into spotlight, but you’d be surprised how much more efficient it feel to do this automatically.  You can even have it paste the result after the end of the highlight.

Combine this with the fact that many text editing apps allow you to select columns of text, and it becomes a trivial matter to do things with masses of numbers in any text and any app.

The sum & subtract automator services also conveniently strip out non-number characters, so you can highlight any numbers that have text in between and sum or subtract them.

Sum Service

Let’s start with the Sum service.  Here’s an example of how it works:

sum_demo.gif

As seen above, you simply:

  1. Select text with the numbers you want to sum
  2. Right-click the selection, and
  3. Select Services->Sum.

The numbers are parsed and added using Spotlight.  In the demo above, I simply tap the escape ket to exit spotlight after seeing the result.  But, you could select & copy the result to use it how you wish, directly from the spotlight result listing.

Subtract Service

The subtract service works the same way as the Sum Service above, but instead of adding all the numbers, it simply takes the first number and subtracts all the rest.  Both services ignore non-numbers and can handle decimals.  It even knows the difference between hyphens in words versus negative numbers.  However, they may have some trouble with non-standard hyphen characters and periods in full sentences.

Calculate (& Append Result) Service(s)

The Calculate Service (or “Calculate & Append Result”) will take any equation that Spotlight (i.e. the Calculator app) can handle and compute the result.  And if you know already that you will want to append the result after the highlighted text in the form of ” = answer”, you can alternatively select the “Calculate & Append Result” Service.  Here is a demo using the service:

calc_demo.gif

Installation

  1. Go to the github gist containing the Applescript code for each service
  2. Copy the code from one of the 3 files in the github gistcopygistcode.png
  3. Open Automator.appautomatordock.png
  4. Select service “Service”/gear icon from the dropdown sheet & click “Choose”selectservice.png
  5. Drag the “Run AppleScript” action into your workflowautomatorapplescript.gif
  6. Replace the purple code in the Run AppleScript action with the code you copied in step 1
  7. Save the workflow and name it however you would like it to appear in the services contextual menu (E.g. “Calculate & Append Result.workflow” – the extension will not appear in the menu)
  8. Repeat for the remaining 3 services.

The workflows/services will be saved automatically to your Library/Services directory in your home directory.  If you right-click the file name at the top of the window in Automator, you can select the Services folder to reveal it in the Finder.  You can then copy that file and send it to any other computer you would like to also have that service.

Have fun!

Disclaimers: These services are only intended as a quick and dirty solution to work in any context, & any app.  If you have a repeated common use-case, consider other solutions.  Note also that any application which reserves the arrow keys for some function when the shift key is held down, other than modifying the most recent selection, this service will fail.  Some applications, such as java applications, modify selections using shift-arrow navigation differently, depending on the direction of the mouse drag during text selection.  This can produce unexpected results.  A work-around for both such issues can be to use the strategy used for Terminal.app, but this would required modification to the code.  A few of the features in the script rely on some tricks such as statically set delays and command-line calls, necessary to either wait for an application to respond or to control the focus of various windows.  If your computer is very busy or has any configuration issues, the proper functioning of these services may be disrupted.  These services were developed and tested on macOS High Sierra, 10.13.4.  They may or may not work in other macOS versions.

Advertisements

Automator Services for finding coordinates in DNA/AA strings

Do you write code to analyze or modify DNA or proteins?  Do you do your work on a Mac?  If so, I have a few Automator Services, written in AppleScript, that you may find very handy:

  1. Get the sequence (& alignment) length of a selected nucleotide string
  2. Get the sequence length of any selected string (e.g. protein or quality string)
  3. Show where a coordinate is in any selected string (including white-spaces)
  4. Show where a coordinate is in a selected sequence (e.g. protein or quality string)
  5. Show where a nucleotide coordinate is in a selected sequence
  6. Show where an alignment coordinate is in a selected nucleotide sequence
  7. Get the reverse complement of a selected nucleotide sequence
  8. Guess the barcodes present in a FastQ file *NEW

With these, you can highlight a sequence anywhere in any application and either get the selection length or show where a supplied coordinate is in the selected sequence.

Each service, once installed, will show up in the contextual menu that shows up anytime you right-click any selected text, system-wide on your mac, under the services sub-menu, e.g.:

countntsservicemenu.png

Here are the full details of how to use each service and what it does:

1. Get the sequence (& alignment) length of a selected nucleotide string

Name: Count Nucleotides

countntsoutput.png

This service does a bit more than count nucleotides.  As seen in the example on the right, it reports the number of nucleotides in the selection (sequence length), the length of the selected alignment, the number of discrete & ambiguous nucleotides, and a breakdown of all case-insensitive sequence characters (including gaps and ambiguous nucleotides).

Spaces, tabs, newlines, carriage returns, numbers, or any other non-sequence characters are completely ignored, so you can select any sequence, even if it is formatted & displayed with coordinates.  Only the sequence found inside the highlighted text is considered.  The first selected sequence character is coordinate 1.

2. Get the sequence length of any selected string (e.g. protein or quality string)

Name: Count Sequence Characterscountnonwschars.png

This service counts every character selected except for spaces, tabs, newlines, and carriage returns.  It’s good for getting the length of selected unaligned protein sequences (with no formatted coordinates in the selection) or of quality strings.  Note, there is currently no service for aligned amino acid sequences, but if you would like such a service, let me know in the comments and I’ll whip one up.  I work mostly with DNA, thus I haven’t had much need for aligned protein coordinate determinations.

3. Show where a coordinate is in any selected string (including white-spaces)

Name: Select N Characters

This service works only on “solid sequence” (i.e. having no whitespaces, hard returns, or for that matter: any non-sequence characters).  See services 4-6 for sequence-specific functions.  The way this service shows where a coordinate is, is by changing the length of the selection.  The resulting last character of the selection after the length modification is the length supplied by you, the user.  For example, if you tell it to select 4 characters in this string you selected: ATGCCGTAG, the selection will end up as: ATGCCGTAG.

lengthprompt.png

There are 2 ways to supply the coordinate.  The default way is to grab the coordinate from the clipboard, so all you have to do is copy the number you want to use to set the selection length.  However, if the content of the clipboard is not a number, a popup window will appear to ask you to enter the desired selection length.

 

To use this service:

  1. [Optional] Copy a number/length indicating the amount of the sequence you want to select.
  2. Select any length of sequence from the start position (position 1)
  3. Right-click the selection and select Services -> Select N Characters
  4. [If you didn’t do step 1] Enter the length of sequence you want to select

This script alters the selection length of the selected text you right-clicked on in the window in which you clicked on the sequence, regardless of application.  However, if you are in Terminal.app, it displays the selection result in a popup window instead of in the Terminal itself.  This is because the modification of the selection length is accomplished by shift-arrow keystroke emulation and this is not a means by which you can modify a selection in the Terminal app.  This has 1 side effect.  Normally, if the entered length is longer than the selection, in any other app, that’s not a problem and the selection just expands, but in Terminal’s popup result window, all the service has access to is the selected text, so placeholder ‘N’s are appended to show the desired sequence length.

lengthresult-terminal.pngThere are other drawbacks to this Terminal selection-length work-around.  The font is not fixed-width and the width of the popup window is fixed at a fairly narrow size, thus large sequences cannot be displayed very well.

Since the selection modification happens via emulated keystrokes, it takes a little time for the final selection to be made, but you’ll see how fast it goes as you watch the selection being made.  Since it’s not instantaneous, the script will either adjust the selection from the end or select anew from the beginning for efficiency.

4-8. New services

Names: Select N Sequence Characters, Select N Nucleotides, Select N Alignment Characters, Reverse Complement, & Guess barcodes

These services operate just like Select N Characters, but take the character type into account.

Select N Sequence Characters doesn’t include whitespace characters such as spaces, tabs, and newlines in the calculation of a coordinate in a string.

Select N Nucleotides doesn’t include non-nucleotide characters such as white spaces, gap characters, numbers, etc. in the calculation of a coordinate in a string.

Select N Alignment Characters behaves just like Select N Nucleotides but includes gap characters in the calculation of a coordinate in a string as the one exception.

Guess Barcodes allows you to right-click on a file and find out what the likely barcodes are.  It takes a little bit to run and makes some common assumptions, but if you think the results are wrong, you are given the opportunity to tweak the parameters and run again.

Installation

  1. Go to the github gist containing the Applescript code for each service
  2. Copy the code from one of the 3 files in the github gistcopygistcode.png
  3. Open Automator.appautomatordock.png
  4. Select service “Service”/gear icon from the dropdown sheet & click “Choose”selectservice.png
  5. Drag the “Run AppleScript” action into your workflowautomatorapplescript.gif
  6. Replace the purple code in the Run AppleScript action with the code you copied in step 1
  7. Save the workflow and name it however you would like it to appear in the services contextual menu (E.g. “Count Non-Whitespace Characters.workflow” – the extension will not appear in the menu)
  8. Repeat for the remaining 6 services.

The workflows/services will be saved automatically to your Library/Services directory in your home directory.  If you right-click the file name at the top of the window in Automator, you can select the Services folder to reveal it in the Finder.  You can then copy that file and send it to any other computer you would like to also have that service.

Just try your new services out by right-clicking on selected text anywhere.selectncharsexample.gif

And as you can see from the example above, Select N Characters works on any text.

Have fun!

Disclaimers: These services are only intended as a quick and dirty solution to work in any context, & any app.  If you have a repeated common use-case, consider other solutions.  Note also that any application which reserves the arrow keys for some function when the shift key is held down, other than modifying the most recent selection, this service will fail.  Some applications, such as java applications, modify selections using shift-arrow navigation differently, depending on the direction of the mouse drag during text selection.  This can produce unexpected results.  A work-around for both such issues can be to use the strategy used for Terminal.app, but this would required modification to the code.  A few of the features in the script rely on some tricks such as statically set delays and command-line calls, necessary to either wait for an application to respond or to control the focus of various windows.  If your computer is very busy or has any configuration issues, the proper functioning of these services may be disrupted.  These services were developed and tested on macOS Sierra, 10.12.6.  They may or may not work in other macOS versions.

Automatically create iOS reminders based on events added to a subscribed google calendar

My wife just got a new job which has an irregular schedule and long hours.  Unfortunately, I’d gotten accustomed to the fact that she always took care of feeding the cat and scooping her litter before I ever even thought about it.  Now, a few weeks into this new job, I’m getting myself in trouble when I forget to feed the cat or scoop the litter.  I imagine I’ll eventually get used to it, but until I do, I devised a clever way to get automatic reminders without me having to ask my wife her schedule every week and manually create the reminders, which means I’ll be less likely to forget.  Hopefully, I’ll start to get used to the routine and I’ll be able to delete this reminder scheme, but until then, here’s how I managed to do it.

Continue reading

Turn your Computer into an iBeacon and Make it Trigger Reminders, Part 2

I’m one of those that does not normally restart my computer, however lately, the power in my office has been going out on a somewhat regular basis, which got me looking into finally automating the starting up of my iBeacon broadcasting.  I had initially created a very quick automator app long ago by recording the 3 clicks it took to start the app, clcik the broadcast button, and then hide the window, but I found that, while it worked when I manually ran it, it always failed upon login (when set as a login item) with this error:

I was able to reproduce this error simply by messing around with (clicking) the mouse as the workflow ran, so I figured that had to have been the problem.  Usually when I log in, I get asked for passwords and such and am rearranging windows on desktop spaces they’d been pulled from as a result of the logout.  I sent a complaint via apple feedback regarding this issue:

Automator won’t run properly as a Login Item

I created an Automator “app” called “Toggle iBeacon Broadcasting”. I created it using the record feature. All it does is click on the BeaconOSX app in my dock, click the “startBroadcasting” Button, and finally, clicks the yellow hide button of the window. I put it as a Login Item so that my Mac would always be broadcasting an iBeacon signal. However, every time I log in, I get this uninformative error: [The action “Watch Me Do (Toggle iBeacon Broadcasting)” encountered an error. Check the actionʼs properties and try running the workflow again.] And every time I run it there-after, it runs fine. However, I was able to reproduce the error by clicking the mouse while it ran, so perhaps automator should detect stuff like that and pause with a dialog asking if it should proceed? Just a thought.

So since the recorded automator workflow had problems with mouse interference, I decided to try an applescript. The first problem I encountered was obtaining the app interface (and you’ll see this ends up being a recurring issue on multiple fronts).  I have a handy applescript called getAppInterface that elucidates an app’s “accessibility” features, and the applescript language necessary to get to them, but I got an error from the system saying that Fastscripts (the menu-bar app I use to run scripts) didn’t have “assistive access” (despite it being in there already):

Error Number:System Events got an error: FastScripts is not allowed assistive access.
-25211

I’ve encountered this issue before.  Apparently, if you edit a script or an app you’re developing, assistive access must be refreshed.  So you have to remove and re-add it from the security preferences pane.  More on enabling assistive access below, however something about Fastscripts must be changing, and I didn’t want to get into it.  Running the script from applescript however worked and I was able to get the handles I needed to write the applescript that will start up the app, start broadcasting, and hide the window.  It’s a pretty simple script:

tell application “BeaconOSX” to activate

tell application “System Events”

tell application process “BeaconOSX”

try

click button “Start Broadcasting iBeacon” of window “BeaconOSX”

on error

try

click button “startAdvertising” of window “BeaconOSX”

end try

end try

click button 3 of window “BeaconOSX”

end tell

end tell

Note that the BeaconOSX app, as written, sometimes changes the button text of the start broadcasting button, so we try both if the first attempt does not work.  If the button text is “Stop Advertising”, nothing will happen.

I added the applescript directly to my login items, but upon testing, I eventually concluded that the script was either not running or quietly failing.  Regardless, I suspected that the accessibility security features could be again interfering with the functioning of the script and that perhaps Apple just had not built in a way to allow individual scripts assistive access.  I didn’t want to deal directly with that, so I sent Apple another piece of feedback:

Too many hoops for login item scripts to get it to work

I had an automator-created recording that was not working (for unrelated reasons), so I wrote an applescript to start an app called BeaconOSX & click it’s broadcast button. The script runs fine manually, but adding it to my login items results in it quietly failing, after which the BeaconOSX window weirdly disappears. (Sometimes I can glimpse it in Mission Control by right-clicking the app in the dock & selecting show All Windows, but it promptly disappears for good once I select it.) Then I tried running it embedded in an automator app set as a login item. Finally I got asked to grant the app access in the security prefs upon login, after which, it worked, albeit very slowly (perhaps 20 seconds after login). The applescript should have worked without the automator wrapper.

Note, the feedback mentions another oddity: the disappearing of the iBeacon window.  I do not believe this had anything to do with iBeacon itself, but rather the windowing system losing track of the window – perhaps because of the assistive access issue.  Again, I didn’t want to deal with it – I just wanted something that would allow me to start up the broadcast reliably.

To get around this, as I alluded to in the feedback, I returned to Automator to embed the script in an app for which I could enable assistive access.  Here’s how to do it:

Create a new automator application (not the default workflow) and drag the “Run Applescript” action from the main library to the pane on the right side and in between the “on run” / “end run” lines, replace whatever’s there with the above applescript.  Save that as “StartiBeacon.app” and then add the app to your login items (System Preferences -> Users & Groups -> Current User (left pane) -> Login Items (tab)) by dragging it into the list of login items.

Then go to System Preferences -> Security & Privacy -> Privacy (tab) -> Accessibility (left pane)and add your app there as well.  If you do not perform this step, the next time you log in, you will get the following error/notification combo:

Clicking the “Open System Preferences” button will bring you to this preference pane:

All you have to do is check the checkbox next to the StartiBeacon app listed there. Though you may need to unlock the preferences pane by clicking the lock icon in the lower lefthand corner.  If you do that, you’ll be asked for your password:

After doing this, the next time you log in, your beacon should start broadcasting automatically, though I noted that it didn’t run for me until about 10-20 seconds after logging in.

This post is more of a description of what I went through to get this all to work.  if there is a desire for a simple step-by-step how-to, please request it in the comments.  I still have not managed to figure out how to tweak the iBeacon settings to get notifications at the expected distance, though I will say that one thing I’ve learned that is non-intuitive is that the higher you set the power, the better the accuracy of the distance measure.  I believe, if I recall correctly, there’s a default distance that’s pretty short, though I’m still very vague on the details.  That’ll be part 3 if I ever get it refined to go off just as I get into my office.

Search Stickies with Spotlight – Hack

Stickies are not searchable by spotlight

I keep a bunch of cheat-sheets & other various notes in Stickies.app, but I have less frequently needed notes in various other kinds of text files and it seemed that whenever I needed to find a certain command that I was sure I’d recorded somewhere, I could never find it.  Well, I discovered the other day that Spotlight does not search the contents of Stickies notes.  I read a lot about it in various blogs.  I even tried to use a set of XCode 4.2 instructions in XCode 6 to create a Spotlight Importer for the Stickies database, but quickly discovered I was in over my head, so I set about constructing a hack to easily save all the stickies as backup text files that would be indexed and searchable by Spotlight.

The catch to this trick is the fact that I have various Sticky Notes bound to specific Mission Control desktops (some of which I hide under the dock with a huge font – to use as desktop labels) and the code for grabbing the stickies content required access to the visible window.  I had first experimented with cycling through the desktops with key code trickery, but discovered a more efficient way – the Window menu item!  Selecting a window in the window menu changes desktops implicitly, so I used the getAppInterface.scpt script (google shows that it’s not out there anymore, so if anyone requests it, I’ll post) to elucidate the menu interface and came up with this script.

set fileName to “”

set stickyNum to 0

set windowMenuListStart to 8

set destFldr to (choose folder with prompt “Choose a destination folder:”) as text

set mydestFldr to POSIX path of destFldr

tell application “Stickies” to activate

tell application “System Events”

tell process “Stickies”

set winMenuList to name of every menu item of menu 1 of menu bar item “Window” of menu bar 1

repeat with winMenuItemNum from windowMenuListStart to (count winMenuList)

click menu item winMenuItemNum of menu “Window” of menu bar item “Window” of menu bar 1 of application process “Stickies” of application “System Events”

delay 0.5

set awindow to name of front window

set noteContent to value of text area 1 of scroll area 1 of window awindow

set stickyNum to stickyNum + 1

set fileName to “stickies” & “_” & stickyNum & “.txt” as string

set theFile to mydestFldr & fileName

do shell script “/bin/echo ” & quoted form of noteContent & ” > ” & quoted form of theFile

end repeat

end tell

end tell

A few notes about the script…  It needed a delay in order for mission control to be able to keep up with the script getting the front window.  If you end up with duplicated and skipped notes, you might need to increase the number of seconds in the delay.

You can only run this script when the screensaver and screen lock is inactive, so putting it in a cron job is not a viable option.  It will cause mission control to change desktops and you may not end up on the desktop you started on when it’s all done.  I tried valiantly to find a way to determine the current desktop number but it looks like that is squirreled away in the code for the Dock and it very difficult to extract.  What you might do to somewhat automate this so that you don’t have to periodically run it manually is use something like ScriptSaver to run the script just before the screen saver comes on.  I have not tried this though and I don’t even know if ScriptSaver is still around.

One last note: if you try to debug an issue by adding dialog windows with messages, note that this will affect the “front window” function.

Once you’ve backed up your Stickies as text files and Spotlight has had time to index them, you will then see search results in the documents section with file names like “stickies_4.txt”.  If you don’t want to wait for Spotlight to do the indexing on its own time, you can go to the Terminal and have it index your newly created stickies backup files with commands like this:

mdimport -d1 stickies_4.txt

The end result is that spotlight searches now show the contents of the stickies you’ve backed up.  The caveat is that you have to occasionally run the script to keep them up to date.  If anyone figures out a better way to do this, I’m all ears – so please comment below.