Successfully using a Python module from Applescript?

I’m trying to have an Applescript determine the direction and the altitude of the sun in the sky, according to my location (static coordinates, no live tracking). I determined that the mathematics involved would be far too complicated for writing in Applescript, especially when this script is supposed to be run 1-5 times a day. I tried to look for an online API to send a request to, but I didn’t really find one; only services that give you the sunset and sunrise times etc. but this doesn’t help me to determine the altitude or azimuth.

Then I came across a Python module that does just that. Unfortunately, I practically have no experience with constructing Python myself, and the documentation is clearly directed for people who already know perfectly well what they’re doing, i.e. understand the vocabulary and other such references. Reading instructions isn’t very helpful if we don’t first have a common language to begin with.

I installed Python 3 to my computer although I recall that at some point before I have installed at least some version of Python and according to terminal, it wasn’t 3. I installed Pysolar from terminal by using pip3. I have no idea what I’m doing but it worked. Entering the lines below to the terminal one by one does return me an answer with the sun’s altitude in this demo location:

So, something is managing to utilize the newly installed module, it exists.
In terminal, I see a path /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/pysolar
But now I haven’t got the slightest clue of how to call this from Applescript! Trying to mimic the syntax of examples that I can find (not easy to come by), I get various error messages, one of which is “ImportError: No module named pysolar.solar”. How should I really translate this then? :o

Before we begin we need to make sure that AppleScript is using the right version of Python. What are the results of the following script?


set loc to do shell script "whereis python"

set ver to do shell script "python -c 'import platform; print(platform.python_version())'"

display dialog "Python version " & ver & " is installed in " & loc

Ah thanks, we’re going somewhere.

Returns “Python version 2.7.10 is installed in /usr/bin/python”.

So, while terminal correctly uses the newly installed 3.6.1 version, Applescript doesn’t seem to know about this change. How do I tell it where to look, preferably, permanently? Assuming that there is no benefit in using old versions of Python in the future.

Excactly…

do shell script "/Library/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python -c 'from pysolar.solar import *
import datetime
d = datetime.datetime.now()
print(get_altitude(50.000, -50.000, d))'"

Does this code work?

Beautiful, yes it does, thank you!
Replacing the demo lat/long with my own actual coordinates and checking with a completely unrelated solar modeling website, I’m getting realistically correlating degree numbers as the sun’s current altitude.
Now I’ll just head back to reading about basic Applescript stuff because I surely don’t need to know the altitude degrees in the format that has 15 decimal places. :cool: But I’ll be able to take it from here, thank you so much for help!

Yeah. Sometimes the python executable is replaced by an link to /Library/Frameworks/Python.framework/Versions/3.6/Resources/Python.app/Contents/MacOS/Python in the /usr/bin folder. Therefore I wanted you to execute the script to see what version is installed where by default. I know the path looks ugly so you can still move the python executable and create an link to the python3.6 binary. Then the script doesn’t need to use the full path to the executable. It’s only to make the code look better not that it will be better in functionality so it’s up to you :slight_smile:

Keep in mind that coercing a string to an real the localization settings is used by the system. So an float from python as string to an AS real coercion can go wrong in many locale settings can go wrong. Format in my language is 1.000,00 for example to write down thousand while in the US it is 1,000.00.

Well that reference line to path isn’t a massive addition so maybe I can let it be. I’ll just have to remember that I need to do this. On the other hand, I also might not run into it for quite a long time.

Oh yes, as we speak, I’m pulling my hair out because Applescript can’t make [value] into type number of course :smiley: Thanks for the hint, I couldn’t have guessed that the system region has something to do with it. In the language&region tab, my number format would appear to be 1 234,56. The Applescript response uses a period as a decimal marker so now it’s even more confusing.

I’ll post my final solution just for the closure. The solution was simpler than I thought that it’d be, but here it is.
Mere conversion of . to , wasn’t enough: Some of the values retrieved by this python script are negative numbers, and if I tried to give it some arguments in the form “x is larger than y is true”, it didn’t handle the negatives correctly… So also conversion to real was necessary. Now it’s fine.

-----------------------------------------------------
# Handler for replacing characters of any kind by others, pasted to the beginning of a script
-----------------------------------------------------
on replace_chars(this_text, search_string, replacement_string)
	set AppleScript's text item delimiters to the search_string
	set the item_list to every text item of this_text
	set AppleScript's text item delimiters to the replacement_string
	set this_text to the item_list as string
	set AppleScript's text item delimiters to ""
	return this_text
end replace_chars

---HERE WOULD BE THE PYTHON SCRIPT WITH ONE'S OWN GEOCOORDINATES

-----------------------------------------------------
# Converting the python-retrieved values into numbers that you can do maths and comparisons with
# Assuming that you have set the retrieved values as variables called Azimuth, Radiation, and Altitude
-----------------------------------------------------

				set Altitude to replace_chars(Altitude, ".", ",")
					set Azimuth to replace_chars(Azimuth, ".", ",")
					set Radiation to replace_chars(Radiation, ".", ",")
					set Altitude to Altitude as real
					set Azimuth to Azimuth as real
					set Radiation to Radiation as real