As my experimentation continues, I wanted to get Visual Studio Code
installed on a mac, and wanted to use python as the language of choice - main reason for the mac is to understand and explore the #ML libraries, runtimes, and their support on a mac (both natively and in containers - docker).
Now, Microsoft has a very nice tutorial
to get VSCode setup and running on a mac, including some basic configuration (e.g. touchbar support). But when it comes to getting
python setup
, and running, that is a different matter. Whilst the tutorial is good, it doesn’t actually work and errors out.
Below is the code that Microsoft outlines
in the tutorial for python. It essentially is the HelloWorld using packages and is quite simple; but this will fail and won’t work.
1
2
3
4
5
6
| import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 20, 100) # Create a list of evenly-spaced numbers over the range
plt.plot(x, np.sin(x)) # Plot the sine of each x point
plt.show() # Display the plot
|
When you run this, you will see an error that is something like the one outlined below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
| 2019-01-18 14:23:34.648 python\[38527:919087\] -\[NSApplication \_setup:\]: unrecognized selector sent to instance 0x7fbafa49bf10
2019-01-18 14:23:34.654 python\[38527:919087\] \*\*\* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-\[NSApplication \_setup:\]: unrecognized selector sent to instance 0x7fbafa49bf10'
\*\*\* First throw call stack:
(
0 CoreFoundation 0x00007fff521a1ecd \_\_exceptionPreprocess + 256
1 libobjc.A.dylib 0x00007fff7e25d720 objc\_exception\_throw + 48
2 CoreFoundation 0x00007fff5221f275 -\[NSObject(NSObject) \_\_retain\_OA\] + 0
3 CoreFoundation 0x00007fff52143b40 \_\_\_forwarding\_\_\_ + 1486
4 CoreFoundation 0x00007fff521434e8 \_CF\_forwarding\_prep\_0 + 120
5 libtk8.6.dylib 0x000000011523031d TkpInit + 413
6 libtk8.6.dylib 0x000000011518817e Initialize + 2622
7 \_tkinter.cpython-37m-darwin.so 0x0000000114fb2a0f \_tkinter\_create + 1183
8 python 0x0000000101836ba6 \_PyMethodDef\_RawFastCallKeywords + 230
9 python 0x00000001019772b1 call\_function + 257
10 python 0x0000000101974daf \_PyEval\_EvalFrameDefault + 45215
11 python 0x0000000101968a42 \_PyEval\_EvalCodeWithName + 418
12 python 0x0000000101835867 \_PyFunction\_FastCallDict + 231
13 python 0x00000001018b9481 slot\_tp\_init + 193
14 python 0x00000001018c3441 type\_call + 241
15 python 0x0000000101836573 \_PyObject\_FastCallKeywords + 179
16 python 0x000000010197733f call\_function + 399
17 python 0x0000000101975052 \_PyEval\_EvalFrameDefault + 45890
18 python 0x0000000101836368 function\_code\_fastcall + 120
19 python 0x0000000101977265 call\_function + 181
20 python 0x0000000101974daf \_PyEval\_EvalFrameDefault + 45215
21 python 0x0000000101968a42 \_PyEval\_EvalCodeWithName + 418
22 python 0x0000000101835867 \_PyFunction\_FastCallDict + 231
23 python 0x0000000101839782 method\_call + 130
24 python 0x00000001018371e2 PyObject\_Call + 130
25 python 0x00000001019751c6 \_PyEval\_EvalFrameDefault + 46262
26 python 0x0000000101968a42 \_PyEval\_EvalCodeWithName + 418
27 python 0x0000000101836a73 \_PyFunction\_FastCallKeywords + 195
28 python 0x0000000101977265 call\_function + 181
29 python 0x0000000101974f99 \_PyEval\_EvalFrameDefault + 45705
30 python 0x0000000101836368 function\_code\_fastcall + 120
31 python 0x0000000101977265 call\_function + 181
32 python 0x0000000101974f99 \_PyEval\_EvalFrameDefault + 45705
33 python 0x0000000101968a42 \_PyEval\_EvalCodeWithName + 418
34 python 0x0000000101836a73 \_PyFunction\_FastCallKeywords + 195
35 python 0x0000000101977265 call\_function + 181
36 python 0x0000000101974f99 \_PyEval\_EvalFrameDefault + 45705
37 python 0x0000000101968a42 \_PyEval\_EvalCodeWithName + 418
38 python 0x0000000101836a73 \_PyFunction\_FastCallKeywords + 195
39 python 0x0000000101977265 call\_function + 181
40 python 0x0000000101974daf \_PyEval\_EvalFrameDefault + 45215
41 python 0x0000000101968a42 \_PyEval\_EvalCodeWithName + 418
42 python 0x00000001019cc9a0 PyRun\_FileExFlags + 256
43 python 0x00000001019cc104 PyRun\_SimpleFileExFlags + 388
44 python 0x00000001019f7edc pymain\_main + 9148
45 python 0x0000000101808ece main + 142
46 libdyld.dylib 0x00007fff7f32bed9 start + 1
47 ??? 0x0000000000000003 0x0 + 3
)
libc++abi.dylib: terminating with uncaught exception of type NSException
\[Done\] exited with code=null in 1.017 seconds
|
The main reason this fails is that one has to be a little more explicit with matplot (the library that we are trying to use). Matplot has this concept of backends
, which essentially is the runtime dependencies needed to support various execution environments - including both interactive and non-interactive environments.
For matplot to work on a mac, the raster graphics c++ library that it uses is based on something called Anti-Grain Geometry (AGG)
. And for the library to render, we need to be explicit on which agg to use (there are multiple raster libraries).
In addition on a mac OS X there is a limitation when rendering in OSX windows (presently lacks blocking show() behavior when matplotlib is in non-interactive mode).
To get around this, we explicitly tell matplot to use the specific agg (“TkAgg in our case) and then it will all work. I have a updated code sample below, which adds more points, and also waits for the console input, so one can see what the output looks like.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| import matplotlib
matplotlib.use("TkAgg")
from matplotlib import pyplot as plt
import numpy as np
def waitforuser():
input("Press enter to continue ...")
return
x = np.linspace(0, 50, 200) # Create a list of evenly-spaced numbers over the range
y = np.sin(x)
print(x)
waitforuser()
print(y)
waitforuser()
plt.plot(x,y)
plt.show()
|
And incase you are wondering what it looks like, below are a few screenshots showing the output.
To get everything working, make sure you setup the Linting
, debugger
, and the python environment
properly. And of course, you can go nuts with containers
!
Happy coding!