In this chapter, we'll go over some Python programming basics and common Python first- and third-party libraries used in Python development. In this chapter, we'll be working on Python Tools for Visual Studio, which works well for new Python developers, using standard 2.7 CPython. It will be fine if you're working on Mac, Linux Eclipse, or an editor of your choice. We will be using pip and easy_install in Visual Studio, but I will include notes for Mac and Linux commands as well.
Let's start with creating a project in Visual Studio with Python Tools (VSPT). Go to File | New Project, then Python | Python Application, and call this solution Chapter2
, as shown in the following screenshot:
Next, navigate to Solution Explorer and click on Add/Remove Environments. You'll see the prompt as shown in the following screenshot. If you have multiple Python installs, you'll be able to select which one you want to specify. Click on the Python 2.7 environment and click on OK.
So what does this do? A common problem with Python development is that libraries installed on your host system using pip or easy_install are kept outside your project files. This makes using Python scripts with different libraries installed on one system unable to run on another system without the exact same setup. It will also update Visual Studio's IntelliSense for any Python libraries installed as best as it can.
Now look at your Solution Explorer. You'll see that Python 2.7 has been added under Python Environments. You can see where the copied environment is saved in your project by right-clicking on Python 2.7 and clicking on Open Folder in File Explorer. You'll see a Lib
folder with a subfolder called site-packages
that has been created with its own lib structure for third-party modules and libraries.
Now let's write some code by starting with the canonical Hello World application for Python. Type in the following code in your editor and click on Start at the top:
print("Hello, World") #This will execute the quickest and fastest, but doesn't scale well in Python.
Many small Python scripts are written this way with no structure or containment. This can be an issue as your application gets bigger. Let's wrap this in a function. Type the following code in your editor again, and click on Start at the top:
#A simple python function. def main(): print("Hello, World") main() #Called after main() is loaded into memory.
Here, we have created a function called main()
and included our print
statement inside it. On the next line, we called main()
to trigger the console to print Hello World
. If you're coming from a C# or JavaScript background, this may look a little funny, and you're right to think so. Python is a very loose languageāthere are no braces wrapping the function and no semicolons to terminate a line of code.
This keeps typing to a minimum, which is great, but for those who have never coded Python before, this can cause issues. Python is very specific on how its code is structured in order for it to work. Remember that at the start of the book, errors like these can trip up development. Let's look at an example:
#A simple python function. def main(): print("Hello, World") '''A function needs to be indented and not be further away more than one line break.''' main()
By using an IDE like Visual Studio or Eclipse, we can see issues like these, whereas a simple text editor might not show these issues. The following is Visual Studio showing an indent issue. Move the mouse over the print()
method and you'll get help on what the issue is.
So far, this is working well for a small Python script, but let's start moving our code to a more object-oriented structure. Now, we want to wrap our main()
function and have it trigger with one of our Python built-in script events, specifically, our __main__
event. Note the double underscores, which indicate that it's a built-in event in Python. Here's an example of the __main__
event being triggered on the main()
function:
#Same function as before. def main(): print("Hello, World") if __name__ == '__main__': #Here Python checks if the runtime event __main__ is called if so run the code below. main()
You can see that we check the __name__
event for __main__
; if it is present, the function or functions are executed. This is similar to a private void
function in C# or window.onload
in JavaScript. It's also important to wrap functions this way should you want to create your own Python module library, so that each can be called only when the module is fully loaded and not before.
Now, let's add a parameter so we can reuse our main()
function. Here, I'll add the username to the main()
function so I can pass a string to our Hello
print
statement:
#Main function with passed in parameter. def main(readersname): print("Hello, " + readersname) if __name__ == '__main__': main('Chad')
Note that you can append strings using +
just as when using JavaScript or C#. You also have the option of string formatters in Python. Here's the preceding code with a string formatter passing in our readersname
parameter:
#Here we use string formatting to better construct our strings. def main(readersname): print("Hello, %s" % readersname) if __name__ == '__main__': main('Chad')
Let's add another parameter to our main()
method. This time, we will use a number, specifically an integer. Let's pass the number 35
as a set number of pages the reader has read and update our print()
statement to include both:
#Main function with two passed in parameters. def main(readersname, amt): print("Hello, " + readersname + ", you have read " + str(amt) + " pages.") if __name__ == '__main__': main('Chad', 35)
Run the script and the output will be Hello, Chad, you have read 35 pages.
. Next, let's use string formatting here rather than using string concatenation. I've changed the string concatenation to a string formatter using %i
to indicate that the format is an integer:
#Here we use string formatting to better construct our strings. def main(readersname, amt): print("Hello, %s, you have read %i" % (readersname, amt)) if __name__ == '__main__': main('Chad', 35)
String formatting can also help parameters output in unique ways. Let's say we wanted to show 35
as a float with decimal points. We can change our string integer formatter %i
to a float formatter, %f
. Look at this example:
#Let's format the string to output a float with decimal places. def main(readersname, amt): print("Hello, %s, your total pages read are %f." % (readersname, amt)) if __name__ == '__main__': main('Chad', 50)
If we run the Python script, you'll see the output Hello, Chad, your total pages read are 50.000000.
. As we can see, the integer value we passed is now 50.000000
with our float formatter modifying our string without any conversion code. Now what if we wanted this to display only two decimal points? Well, we can tweak our modifier and specify how many decimal points as shown in the following code:
#Let's format the string to output a float with two decimal places. def main(readersname, amt): print("Hello, %s, your total pages read are %0.2f." % (readersname, amt)) if __name__ == '__main__': main('Chad', 50)
If we run the Python script now our output looks like this: Hello, Chad, your total pages read are 50.00
.
Formatters work on floats to integers as well; look at this code sample:
def main(readersname, amt): print("Hello, %s, your total pages read are %i." % (readersname, amt)) if __name__ == '__main__': main('Chad', 50.652)
Now, let's look at our result: Hello, Chad, your total pages read are 50.
. We notice that it removed the decimal places and even though the .652
value should round our 50 integer to 51, it didn't. The integer formatter simply trimmed the value and didn't round up the value. This is very important to keep in mind for integer formatters.
This is great. Now we have a quick and easy way to convert values to floats (decimal points) and back to integers again should we need to convert values in our charts later on. Remember that Python is a dynamically-typed language, meaning that all variables can be any type without specification, and the Python interpreter assigns a type based on what's available. Now that we have a handle on functions and strings, let's take a look at some common libraries to help us understand file inputs and outputs.
What we've covered so far could work for very small Python scripts, but we want to use premade libraries and functions to take full advantage of Python to allow us to write maintainable code. In this section, we'll review importing existing Python modules and libraries and using those functions in our code.
Recall that in Chapter 1, Setting Up Your Development Environment, we covered installing pip and easy_install. Well, pip at least is a Python library, but one thing you may not recollect is that in that chapter, we in fact installed many libraries and modules. If you recall, we also installed the Python language interpreter and tools from https://www.python.org/. Our install came with hundreds of bundled libraries to be used. These are considered the general release libraries for Python. These are common language libraries used in Python development and tested by the Python Software Foundation for cross-platform development, which removes the need for OS-specific development in the core language.
Let's try importing the sys
module. The sys
module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter.
To import a module, type in the following on the topmost line of your Python script.
import sys
Have a look at this step in the following screenshot:
In Visual Studio, you can call up IntelliSense while you type by pressing Ctrl + Space bar. You can see IntelliSense filter more and more as you type. Also, whatever is highlighted will show Python docstrings that are written for that file to provide help and notes to the developer implementing those libraries.
If you're in Eclipse, the Eclipse PyDev also provides code hinting, just like IntelliSense. Even the keyboard shortcut is the same, Ctrl + Spacebar. Now let's test our import. Since sys
can look up Python arguments and environment variables, let's check what platform we're running. Type in the following in your editor:
import sys platform = sys.platform; print("%s" % platform)
Now run the script and if you're in a Windows-based OS, your output would be win32
; if you're on Mac OS X, your output would be darwin
(this is referring to the FreeBSD Apple implementation of FreeBSD, which is the core of OS X). If you're on a Linux OS like Ubuntu, your output will be linux2
.
Next, let's check the version using sys.version_info
. The version_info
list returns an array of what the current version used for this script, a major release number (int), a minor release number (int), and a micro release number (int). To test this, let's run the script shown in the following code:
import sys pyversion_major = sys.version_info[0]; pyversion_minor = sys.version_info[1]; pyversion_micro = sys.version_info[2]; print("Python version: %s.%s.%s" % (pyversion_major, pyversion_minor, pyversion_micro))
Run the script and your output should be Python version: 2.7.6
or a newer version of Python 2.7. Now that we have a grasp on imports, let's start with the basics of Python file I/O using the os
module with its user and path functions.
A core skill when working with Python is understanding input and output. If you're coming from a client-side web development background, where file access is not possible, take extra note in this section, because when creating charts, we will need to be able to save our charts to our hard drive.
The os
module is one of the most used modules in Python mostly because of how it handles getting common filepaths cross-platform. Let's demonstrate how we can read files. Create a text file called PyREADME.txt
and save it to your project's directory. Copy the following text in the PyREADME.txt
file and save the file:
Hello Reader, This copy is being read in Python, and saved as a string to a variable.
Once saved, it should look like the following screenshot:
Now, in your Python editor, we will import the os
module by including import os
on the topmost line and then add the following code. Be sure your PyREADME.txt
file is in the same directory as your running Python script.
import os #Open the file to be read. openFile = os.open('PyREADME.txt', os.O_RDONLY ) #Save the file's inner content to a Python variable string. This take two parameters, the file to be opened and how many characters to read. readmeText = os.read(openFile, 100) print(readmeText)
If everything is successful, your output window should show what's in the next figure.
Now let's review our code. We open our file using the open()
function, and we have two parameters: our file name with an extension and an r
string. The r
string tells the open()
method what permissions we have when working with the file. After we open the file, we read the file and print it to the console. Lastly, we close our openFile
; this keeps us from having a potential memory leak, since our file I/O won't close until we tell it to close.
Next, let's create a text file. We will have Hello World
as its content, and name it content.txt
. Replace your Python file with this bit of code:
import os txtContent = 'Hello World' openFile = open('content.txt', 'w') #Open the file to be written. readmeText = openFile.write(txtContent) #Write the file's inner content to the text file. openFile.close() #Close the file.
If successful, you should have a new text file with Hello World
written in the file, as shown in the next screenshot. You can find the file in the same directory as your Python script. Let's review the code. You'll notice that we changed our open()
permission's parameter to w
, which means write-only, and we've set the filename to content.txt
to indicate the name of the file (even if it doesn't exist prior to running the script). Beyond that, the only code that's changed is because we've swapped openFile.read()
with openFile.write()
, telling Python to write a content string to the file rather than the output from a file.
Now that we understand imports and reading and writing a file to the hard drive of our computer, let's generate an image with some text. The first thing to be done is downloading an imaging library to use since Python doesn't include one by default. The most common of these is the Python Imaging Library (PIL). PIL allows text input to be printed as an image and is very commonly used for CAPTCHA password systems.
To install PIL, we will need to use easy_install. If you have Mac OS X or Linux, the command is as follows:
sudo easy_install PIL
On Windows, you can run the following in the command line as the administrator in the Python directory:
easy_install PIL
Better yet, if you're using Visual Studio as your editor, set your project to Python 2.7 and click on Install Python Package under the Python Environments 2.7 instance. Type in pil
under easy_install and check Run as Administrator as shown in the following screenshot:
If successful, you should be able to see pil
included in your environments, as shown in the following screenshot:
In other environments such as Eclipse, you can check your import by using the following command:
from pil import *
This will import all modules from the PIL library. Now that we have that set, we are going to reuse the content.txt
file we created earlier and generate an image with its content. Since this is a bit more complicated, I'll move both steps into their own functions, as shown in the following code:
from pil import * import Image import ImageDraw import os def readcontent(): '''Open the file to be read. Note the file's permission is set to read-only.''' openFile = open('content.txt', 'r') '''Save the file's inner content to a Python Variable string.''' readmeText = openFile.read() '''Close the file to save memory.''' openFile.close() '''Return the results to each as a reference variable.''' return openFile, readmeText def generateImage(): '''Create our references.''' img = Image.new("RGBA", (100, 80), "white") '''Draw the images size and background to the screen.''' draw = ImageDraw.Draw(img) '''Position the text with an x/y of 10 x 10, assign it the text value and text color of red.''' output = draw.text((10, 10), readmeText, fill=(255,0,0,255)) '''Draw the text to the screen.''' draw = ImageDraw.Draw(img) '''Save the image.''' img.save("output.png") '''Return the results to each as a reference variable.''' return draw, img, output '''trigger the read content function.''' openFile, readmeText = readcontent() '''Generate our image.''' draw, img, output = generateImage()
We should now have a simple image like the one shown in the following screenshot. Feel free to modify the content.txt
file for different results if you want to set the font size and font.
There is a bug in the current version of PIL through easy_install. Some of the C-based code doesn't install properly. You may want to check out pillow (a bundled version of PIL), which you can download here: https://code.google.com/p/rudix/downloads/detail?name=pillow-1.7.7-0.pkg&can=2&q.
3.17.154.139