Friday, September 14, 2018

Python Environment (Shell and IDEs)

Python Environment (Shell and IDEs)

Python Environment (Shell and IDEs)

The Python Environment

Python is an interpreter that runs its own environment. At a unix/linux/macos shell prompt if you use the 'python' command with a file name python loads the file, interprets the file (providing output if it has been programmed to) and then returns to the shell. This is how python was used in the introductory blog post "Introduction to python: first steps".

If you don't use any argument (filename or otherwise) and just run the 'python' command, you will be taken into the python shell environment. Now you can still load files into the python shell and execute them in what looks like any other linux shell environement command prompt. To test this functionality out change the hello world script so that it creates a function instead of executing immediately. Call that script hello1.py

#!/Users/tmcguire/anaconda3/bin/python
def hello(str):
  print(str)

Now go into python and import the hello1 script. If you started in the right directory when you called the python command you will not need to supply a pathname. The python shell uses the directory it's started in as the current working directory. Notice when you go into the shell environment python responds with 3 greater than signs: '>>>'. This is python's default prompt and python uses it to indicate it's your turn to enter a command. Now load the script usinge the 'import' commadn and try to execute the function hello:

$ python
Python 3.6.0 |Anaconda 4.3.1 (x86_64)| (default, Dec 23 2016, 13:19:00) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello1
>>> hello('Hello World')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'hello' is not defined
>>> hello1.hello('Hello World')
Hello World
>>> 

Notice the error when you try to simply execute the 'hello' function. This is because of how python creates and handles what are called namespaces. Python prepends the name of the function with the file name or library it came from. This is a naming convention so that as modules are added the names of individual functions can be access unambiguously. So in the above example python couldn't find a function called "hello" but it could find the function "hello1.hello".

Using the Python Shell Environment

I can refactor the previous python scripts (from the previous blog post) to take advantage of the python environment. This will get rid of the while loop and the interactive input statement because the function can just be called by name with the number that used to be input as an argument and python will take care of rest. An example script that use to use a while loop was the quick and easy squareroot function:

#!/Users/tmcguire/anaconda3/bin/python
import math

def squareroot(x):
  if x >= 0:
    return math.sqrt(x)
  else:
    print(x,' does not have a real square root')
    return 0
$ python
Python 3.6.0 |Anaconda 4.3.1 (x86_64)| (default, Dec 23 2016, 13:19:00) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqrt1
>>> sqrt1.squareroot(25)
5.0
>>> sqrt1.squareroot(2)
1.4142135623730951
>>> math.sqrt(25)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>> import math
>>> math.sqrt(25)
5.0
>>> sqrt1.sqrt(2)
1.4142135623730951
>>> 

So with the function in place, just calling it at the command prompt with different arguments accomplishes what the while loop was doing. The import statement in the file sqrt1.py while valid for the code in the file does not get set globally. So trying to use the math library function "sqrt" directly fails because the python environment can't find it. It is hidden inside the function "squareroot". But use import on the python command line to bring in the math library and now the 'sqrt' function is available directly.

Is sqrt really hidden or did python just append the name sqrt1 to it? Namespaces are wierd entities and different language interpreters have all sorts of rules behind their use. Not being aware of the complete functionality of namespaces in python I wondered. Did python just prepend a sqrt1 to the math library imported in the file? This means it's really available for use but python changed the name a little. So rather than pour through manuals lets just test out the theory directly in the environment.

$ python
Python 3.6.0 |Anaconda 4.3.1 (x86_64)| (default, Dec 23 2016, 13:19:00) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqrt1
>>> sqrt1.math.sqrt(25)
5.0
>>> math.sqrt(25)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'math' is not defined
>>> 

In the above session, python has been reloaded to clear all the imports. If sqrt1.math.sqrt() is used the function is found by python. However maybe it was left over some how from the previous session. math.sqrt was run just to show that the environment is indeed cleared from before when the math library was imported.

Important Programming Point!

You should read the manuals available on python. But here is an important point about programming. Just because you read the manual doesn't mean you fully understand how python (or any interpreter or computer language) is going to respond. Test it out in a real python environment to make sure your understanding of the 'theory' of how python works is actually the way python works in real life.

Important Debugging Point!

When you come across what look like discrepancies, there is either a bug in the interpreter, an error in your program, an error in the manual, or an error in your judgement.

Important Corollary to the Important Debugging Point!

When in doubt of where the problem lies, start with your judgement and work backwards from there.

More Scripts to Fix and Run

# Program: divisors.py
# This loops through values 2 to number, and finds all divisors of the number
# No computer magic just loop through all values and test them with the
# modulo operator (%) which returns 0 if the number is a divisor
def divisors(x):
  print('The divisors of ',x,' are: ')
  for divisor in range(2,x):
    if (x % divisor)==0:
      print(divisor)

$ python
Python 3.6.0 |Anaconda 4.3.1 (x86_64)| (default, Dec 23 2016, 13:19:00) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import divisors
>>> divisors.divisors(12)
The divisors of  12  are: 
2
3
4
6
>>> divisors.divisors(18)
The divisors of  18  are: 
2
3
6
9
>>> 
# solve quadratic equation ax^2 + bx + c = 0
# accept a,b,c from the user
#
# Program: quadratic.py
#
import math

# Function definitions:
def quadratic(a,b,c):
  if (a==0) and (b==0):
    print('The equation is degenerate')
  else:
    if a == 0:
      print('the only root is ', -c/b)
    else:
       if c == 0:
         print('the roots are ', (-b/a),' and 0')
       else:
         re = -b / (2 * a)
         discriminant =  (b*b) - 4 * a * c
         im = math.sqrt(abs(discriminant))/(2*a)
         if discriminant >= 0:
           print('the roots are ', re+im, ' and ', re - im)
         else:
           print('the roots are complex: ', re,' + j',im,' and ', re, '- j',im)
$ python
Python 3.6.0 |Anaconda 4.3.1 (x86_64)| (default, Dec 23 2016, 13:19:00) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import quadratic1
>>> quadratic1.quadratic(0,0,7)
The equation is degenerate
>>> quadratic1.quadratic(0,10,2)
the only root is  -0.2
>>> quadratic1.quadratic(2,3,0)
the roots are  -1.5  and 0
>>> quadratic1.quadratic(1,5,6)
the roots are  -2.0  and  -3.0
>>> quadratic1.quadratic(1,1,1)
the roots are complex:  -0.5  + j 0.8660254037844386  and  -0.5 - j 0.8660254037844386
>>> 

That's just to show how to use the rest the previous programs will run in the python shell environment

Python Distributions and IDE

There are different python distributions and there are many IDEs (Integrated Development Environments). Distributions usually differ in how many libraries they prepackage with python. Rather than try to catolog them I will just discuss the one I use breifly.

Anaconda3 python

I happen to have the anaconda distribution of python because of it's integration with Jupyter Notebook (which is a web tool that creates notebooks of text and runnable python code). I came across the Anaconda3 distribution of python because Martin Saurer made a Jupyter Notebook implementation for the J programming language. Jupyter Notebook is not quite an IDE but it is a good prototyping platform where you can mix text code and pictures to produce a runnable notebook mixing python with text comments. It's easy to use, not to difficult to setup but it does need to run a local server application so it requires some minimal knowledge of how to set up network programs.

IDEs

There are python plugins that are available for the 2 major Java IDEs: Netbeans and Eclipse. This would be for the Java developer that now needs to use python for access to a popular python library.

If you are using a apple Mac as your programming environment then Apple's Xcode IDE can be set up to edit python programs. A google search seems to imply that like the other IDEs there is a process you have to go through to get XCode to work the way it should with python programs. I don't do a lot of XCode IDE delvelopment so I didn't bother to set it up. In the references I put a 2016 set of directions for getting XCode to use Python 3.5. If you're interested you can probably work through the same steps to get the latest Python version in place.

Anaconda3 provides 2 IDEs in their distribution. One is Microsoft's Visual Studio and the other is Spyder. I haven't use Microsoft VS in a while so I didn't bother with this IDE. The more compelling IDE is Spyder. It's written in Python itself so it has a design philosophy similar to the Java IDEs Eclipse and Netbeans have for Java. Spyder is just 'there' in the Anaconda3 distribution. There is some minor installation issues that will need to be address like upgrading Spyder to it's latest release. But the whole process amounts to:

  • Download the latest distribution of anaconda
  • Run anaconda-navigator and upgrade any highlighted packages (the version number will have an arrow in front of it and the arrow and version number will be colored blue)
  • type spyder at the command line to bring up the IDE

Spyder does your typical IDE sort of things like grouping programs into a project, debugging facilities, and of course a code editor that highlights the features of python code for easy reading. Now the nice thing about spyder as part of the anaconda distribution is that it give you easy integration into the data sciences libraries. Things like numpy the python mathematical extension library.

For now lets run one of the previous sample programs in Spyder:

  • Bring up a terminal window with a bash shell (or your favorite shell environment)
  • type 'spyder' at the command line

if you have installed Anaconda3 and updated Spyder your screen should look similar to:


Now use the file menu and open the program that calculates the square root


Click the green arrow button at the top list of controls to run the program. If all goes well you should see the correct output in the lower right hand corner of the IDE

Conclusion

There are many ways to develop in Python. If you prefer a command line environment then the vi editor or emacs are fine to edit code. Emacs will have a language module so you get the nice highlighting of an IDE. There are the legacy IDEs Netbeans, Eclipse, Visual Studio, XCode you can use. These may be preferred if your development spans multiple languages. But if your just looking for something to do python in that is easy to install and use Spyder. By the way I don't have a screen shot showing you but that console for output is a full ipython shell which means you can type python statements directly in at the 'In' prompt and ipython will execute them. So you can try things in real time and then move them easily back to your code in the IDE.

References

  1. python anaconda distribution: https://www.anaconda.com/
  2. spyder ide: https://www.spyder-ide.org/
  3. Jupyter Notebook: https://jupyter.org/
  4. numpy package for scientific computing: http://www.numpy.org/
  5. XCode integration by Erica Sadun: https://ericasadun.com/2016/12/04/running-python-in-xcode-step-by-step/
  6. Martin Saurer J Jupyter notebook page at J Software site: https://code.jsoftware.com/wiki/Guides/Jupyter

Author: Nasty Old Dog

Validate