Main Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations..

Illustrated Guide to Python 3: A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works

Introducing Your Guide to Learning Python Illustrated Guide to Learning Python is designed to bring developers and others who are anxious to learn Python up to speed quickly. Not only does it teach the basics of syntax, but it condenses years of experience. You will learn warts, gotchas, best practices and hints that have been gleaned through the years in days. You will hit the ground running and running in the right way. Learn Python Quickly Python is an incredible language. It is powerful and applicable in many areas. It is used for automation of simple or complex tasks, numerical processing, web development, interactive games and more. Whether you are a programmer coming to Python from another language, managing Python programmers or wanting to learn to program, it makes sense to cut to the chase and learn Python the right way. You could scour blogs, websites and much longer tomes if you have time. Treading on Python lets you learn the hints and tips to be Pythonic quickly. Packed with Useful Hints and Tips You'll learn the best practices without wasting time searching or trying to force Python to be like other languages. I've collected all the gems I've gleaned over years of writing and teaching Python for you. A No Nonsense Guide to Mastering Basic Python Python is a programming language that lets you work more quickly and integrate your systems more effectively. You can learn to use Python and see almost immediate gains in productivity and lower maintenance costs. What you will learn:

Distilled best practices and tips
How interpreted languages work
Using basic types such as Strings, Integers, and Floats
Best practices for using the interpreter during development
The difference between mutable and immutable data
Sets, Lists, and Dictionaries, and when to use each
Gathering keyboard input
How to define a class
Looping constructs
Handling Exceptions in code
Slicing sequences
Creating modular code
Using libraries
Laying out code
Community prescribed conventions
Volume: 1
Year: 2017
Edition: 2
Publisher: CreateSpace Independent Publishing Platform
Language: english
Pages: 257
ISBN 10: 1977921752
ISBN 13: 9781977921758
File: EPUB, 3.12 MB
Download (epub, 3.12 MB)

You may be interested in

 

Most frequently terms

 
 
writet
Непонятная книга, но читаем
26 July 2019 (20:10) 
You can write a book review and share your experiences. Other readers will always be interested in your opinion of the books you've read. Whether you've loved the book or not, if you give your honest and detailed thoughts then people will find new books that are right for them.
* * *





Treading on Python Series


Illustrated Guide to Python 3


A Complete Walkthrough of Beginning Python with Unique Illustrations Showing how Python Really Works


Matt Harrison


Technical Editors: Roger A. Davidson, Andrew McLaughlin

Version: Oct 2, 2017

Copyright © 2017

While every precaution has been taken in the preparation of this book, the publisher and author assumes no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.





Table of Contents


Introduction

Why Python?

Which Version of Python?

The Interpreter

Running Programs

Writing and Reading Data

Variables

More about Objects

Numbers

Strings

dir, help, and pdb

Strings and Methods

Comments, Booleans, and None

Conditionals and Whitespace

Containers: Lists, Tuples, and Sets

Iteration

Dictionaries

Functions

Indexing and Slicing

File Input and Output

Unicode

Classes

Subclassing a Class

Exceptions

Importing Libraries

Libraries: Packages and Modules

A Complete Example

Onto Bigger and Better

File Navigation

Useful Links

About the Author

Also Available

One more thing





Introduction


Are you ready to jumpstart your Python programming career? This book will arm you with years of knowledge and experience that are condensed into an easy to follow format. Rather than taking months reading blogs, websites, and searching mailing lists and groups, this book will allow a programmer to quickly become knowledgeable and comfortable with Python.

Programming is fun and Python makes it delightful. Basic Python is not only easy, but approachable for all ages. I have taught elementary students, teenagers, “industry” professionals and “golden years” folks the Python programming language. If you are willing to read and type, you are about to begin an exciting path. Where it ultimately takes you depends on how hard you are willing to work.

There are different levels of Python. Basic Python syntax is small and easy to learn. Once you master basic Python, doors will open to you. You should be able to read a lot of Python and understand it. From there, you can learn more advanced topics, specific toolkits, start contributing to open source projects written in Python, or use that knowledge to learn other programming languages.

A recommended approach for learning the language is to read a chapter and then sit down at a computer and type out some of the examples found in the chapter. Python makes it easy to get started, eliminating much of the hassle found in running programs in other languages. The temptation will likely be to merely read the book. By jumping in and actually typing the examples you will learn a lot more than by just reading.





Why Python?


Python is booming! It is the top language being taught in universities. Python developers are among the highest paid. With the boom in data science, Python is quickly becoming one of the most desired skills for analytics. Operations are also adopting Python to manage their backend systems. They are discovering what web developers using Python have known for a long time; namely, that Python will make you productive.

Python has crossed the tipping point. No longer are only small, agile startups relying on it. Looking to take advantage of its power and efficiency, enterprises have also converged on Python. Over the past year, I've taught Python to hundreds of seasoned developers with years of experience at large companies, who are moving to Python.

Python enables increased productivity. I came to Python as a Perl programmer. At work, I was assigned to a team with a co-worker who was well versed in Tcl. Neither of us wanted to jump ship though both of us were interested in learning Python. In 3 days our prototype was completed, much faster than we expected, and we both promptly forgot our previous “goto” language. What appealed to me about Python was that it fit my brain. I firmly believe if you have some experience in programming, you can learn the basics of Python in a few days.

Python is easy to learn. For beginning programmers, Python is a great stepping stone. Learning to write simple programs is pretty easy, yet Python also scales up to complex “enterprise” systems. Python also scales with age—I have personally seen people from 7-80+ learn basic programming skills using Python.





Which Version of Python?


This book will focus on Python 3. Python 2 has served us well over the years. The Python Software Foundation, which manages releases of the language, has stated that Python 2 is coming to an end. As such, after 2020 they will no longer support the language.

Python 3, has been out for a bit now and is somewhat backward incompatible with the 2 series. For green field development, you should move forward with Python 3. If you have legacy systems on Python 2, do not fret. In fact, most of the content in this book is perfectly applicable to Python 2. If you want to focus on Python 2, check out the prior version of this book.





Python installation


Python 3 is not installed on most platforms. Some Linux distributions ship with it, but Windows and Mac users will need to install it.

For Windows folks, go to the download area of the Python website 1 and find a link that says “Python 3.6 Windows Installer”. This will link to a .msi file that will install Python on your Windows machine. Download the file, open it by double-clicking it, and follow the instructions to finish the installation.

Note

On the Windows installer there is an option labeled "Add Python to PATH". Please make sure it is checked. That way, when you run python from the command prompt, it will know where to find the Python executable. Otherwise, you can go to System properties (click WIN+Pause, or run environ from the start menu), Advanced system settings, and click on the Environment Variables button. There you can update the PATH variable by adding the following:

C:\Program Files\Python 3.6;C:\Program Files\Python 3.6\Scripts



If you have UAC (User Account Control) enabled on Windows, then path is:

C:\Users\<username>\AppData\Local\Programs\Python\Python36





Likewise, Mac users should download the Mac installer from the Python website.

Note

Another option for installing Python is to use the Anaconda 2 distribution. This runs on Windows, Mac, and Linux, and also provides many pre-built binaries for doing scientific calculations. Traditionally, these libraries have been annoying to install as they wrap libraries written in C and Fortran, that require some setup for compiling.

Mac users might also want to look into the Homebrew version 3. If you are already familiar with Homebrew, it is a simple brew install python3 away.





Which editor?


In addition to installing Python, you will need a text editor. An editor is a tool for writing code. A skilled craftsman will invest the time to learn to use their tool appropriately and it will pay dividends. Learning to use the features of an editor can make churning out code easier. Many modern editors today have some semblance of support for Python.

If you are just beginning with Python and have not had much experience with real text editors, most Python installations include IDLE, which has decent Python editing features. The IDLE development environment also runs on Windows, Mac and Linux.

A feature to look for in editors is integration with the Python REPL 4. Later you will see an example with IDLE. Hopefully your editor of choice will have similar features.

Popular editors with decent Python support include Emacs, Vim, Atom, Visual Studio Code, and Sublime Text. If you are interested in more fancy editors that have support for refactoring tools and intelligent completion, PyCharm and Wing IDE are also popular.





Summary


Python 3 is the current version of Python. Unless you are working on legacy code, you should favor using this version. You can find the latest version on the Python website.

Most modern editors contain some support for Python. There are various levels of features that editors and IDEs provide. If you are getting started programming, give the IDLE editor a try. It is a great place to start out.





Exercises


Install Python 3 on your computer. Make sure you can start Python.



If you are used to a particular editor, do some investigation into its support for Python. For example, does it: Do syntax highlighting of Python code?

Run Python code in a REPL for you?

Provide a debugger for stepping through your Python code?





1 - https://www.python.org/download

2 - https://www.anaconda.com/download/

3 - https://brew.sh/

4 - REPL stands for Read, Evaluate, Print, and Loop. You will soon see an example using it.





The Interpreter


Python is commonly classified as an interpreted language. Another term used to describe an interpreted language is scripting language. To run a computer program on the CPU, the program must be in a format that the CPU understands, namely machine code. Interpreted languages do not compile directly to machine code, instead, there is a layer above, an interpreter that performs this function.



Difference between a compiled language and an interpreted language. A compiler runs to create an executable. An interpreter is an executable that loads code and runs it on top of itself.



There are pros and cons to this approach. As you can imagine, on the fly translating can be time consuming. Interpreted code like Python programs tend to run on the order of 10–100 times slower than C programs. On the flip side, writing code in Python optimizes for developer time. It is not uncommon for a Python program to be 2–10 times shorter than its C equivalent. Also, a compilation step can be time consuming and actually a distraction during development and debugging.

Many developers and companies are willing to accept this trade-off. Smaller programs (read fewer lines of code) take less time to write and are easier to debug. Programmers can be expensive—if you can throw hardware at a problem, it can be cheaper than hiring more programmers. Debugging 10 lines of code is easier than debugging 100 lines of code. Studies have shown that the number of bugs found in code is proportional to the numbers of lines of code. Hence, if a language permits you to write fewer lines of code to achieve a given task, you will likely have fewer bugs. Sometimes program execution speed is not that important and Python is sufficiently fast for many applications. In addition, there are efforts to improve the speed of Python interpreters such as PyPy 5.





REPL


Python has an interactive interpreter or REPL (Read Evaluate Print Loop). This is a loop that waits until there is input to read in, then evaluates it (interprets it), and prints out the result. When you run the python3 executable by itself, you launch the interactive interpreter in Python. Other environments, such as IDLE, also embed an interactive interpreter.



To launch the REPL, type python3 in the prompt and it will start a Python session



Note

This book generally starts Python 3 with the python3 executable. On Windows, the executable is named python. If you are on Windows, replace python3 with python. On Unix systems you shouldn't have to change anything.



When you start the interpreter, it will print out the version of Python, some information about the build, and some hints to type. Finally, the interpreter will give you a prompt, >>>.

Another option is to start IDLE, the editor included with Python, by typing python3 -m idlelib.idle.



To launch the REPL in IDLE, click on the IDLE icon or type python3 -m idlelib.idle



Note

Some Linux distributions do not ship with all of the libraries from the Python standard library. This is annoying, but justified by the idea that a server doesn't need libraries to create client side applications. As such, Ubuntu and Arch (among others) don't provide the gui libraries necessary for IDLE on the default installation.

If you see an error like:

$ python3 -m idlelib.idle ** IDLE can't import Tkinter. Your Python may not be configured for Tk. **



it is an indication you are missing the tkinter library.

On Ubuntu, you need to run:

$ sudo apt-get install tk-dev



On Arch, you need to run:

$ sudo pacman -S tk





A REPL example


Below is an example to show why the Read, Evaluate, Print Loop was given this name. If you typed python3 from the command line 6, or launched IDLE, you will see >>>.

Type 2 + 2 like shown below and hit enter:

$ python3 >>> 2 + 2 4 >>>



In the above example, python3 was typed, which opened the interpreter. The first >>> could be thought of as the read portion. Python is waiting for input. 2 + 2 is typed in, read, and evaluated. The result of that expression—4—is printed. The second >>> illustrates the loop, because the interpreter is waiting for more input.

The REPL, by default, prints the result of an expression to standard out (unless the result is None, which will be explained in a later chapter). This behavior is inconsistent with normal Python programs, where the print function must be explicitly invoked. But it saves a few keystrokes when in the REPL.

Note

The >>> prompt is only used on the first line of each input. If the statement typed into the REPL takes more than one line, the ... prompt follows:

>>> sum([1, 2, 3, 4, 5, ... 6, 7])



These prompts are defined in the sys module:

>>> import sys >>> sys.ps1 '>>> ' >>> sys.ps2 '... '



A later chapter will explain what modules are. For now, know that there are variables that define what the prompts look like.



The REPL ends up being quite handy. You can use the interactive interpreter to write small functions, to test out code samples, or even to function as a calculator. Perhaps more interesting is to go the other way. Run your Python code in the REPL. Your code will run, but you will have access to the REPL to inspect the state of your code. (You will see how to do this in IDLE soon).

The >>> is a prompt. That is where you type your program. Type print("hello world") after the >>> and hit the enter key. Make sure there are not any spaces or tabs before the word print. You should see this:

>>> print("hello world") hello world



If you see this, congratulations, you are writing Python. Consider yourself inducted into the world of programming. You have just run a program—“hello world”. Hello world is the canonical program that most people write when encountering a new language. To exit the REPL from the terminal, type quit(). Unix users may also type Ctl-D.

Note

Programming requires precision. If you were not careful in typing exactly print("hello world") you might have seen something like this:

>>> print("hello world File "<stdin>", line 1 print("hello world ^ SyntaxError: EOL while scanning string literal



Computers are logical, and if your logic does not make sense, the computer can warn you, perform irrationally (or at least what appears so to you), or stop working. Do not take it personally, but remember that languages have rules, and any code you write has to follow those rules. In the previous example, the rules that states if you want to print text on the screen you need to start and end the text with quotes was violated. A missing quote on the end of the line consequently confused Python.





IDLE will try to highlight where the error occurred. The highlight following world is supposed to indicate where the syntax error occurred. It is normally a salmon color.





Summary


As Python is an interpreted language, it provides a REPL. This allows you to explore features of Python interactively. You don't need to write code, compile it, and run it. You can launch a REPL and start trying out code.

For users who have used compiled languages, this might seem somewhat novel. Give it a try though, it can make development easy and quick. Also, don't be afraid to try out code from the REPL. I find that new Python users tend to be timid to use the REPL. Don't fear the REPL!

There are other REPLs for Python. One popular one is Jupyter, which presents a web-based REPL 7. Start using the REPL, then you can jump into other more advanced REPLs.





Exercises


Open the Python 3 REPL and run "hello world". Review the chapter to see what this one line program looks like.



Open the REPL IDLE and run "hello world".





5 - https://www.pypy.org

6 - From the Windows run menu, type cmd (or Win-R) to get a prompt. On Macs, you can quickly launch a terminal by typing command-space, the typing Terminal and return. If you have installed Python 3, you should be able to launch it now on either platform by typing python3.

7 - https://jupyter.org/





Running Programs


While using the interactive interpreter can be useful during development, you (and others) will want to deploy your program and run it outside of the REPL. In Python, this is easy as well. To run a Python program named hello.py, open a terminal, go to the directory containing that program and type:

$ python3 hello.py



Note

When running a command from the command line, this book will precede the command with a $. This will distinguish it from interpreter contents (>>> or ...) and file contents (nothing preceding the content).



Note

The previous command, python3 hello.py, will probably fail unless you have a file named hello.py.



In the previous chapter you used the REPL to run “hello world”, how does one run the same program standalone? Create a file named hello.py using your favorite text editor.

In your hello.py file type:

print("hello world")



Save the file, go to its directory, and execute the file (here execute and run have the same meaning, i.e. type python3 before the file name, and let the Python interpreter evaluate the code for you.)

Note

Typing python3 standalone launches the interpreter. Typing python3 some_file.py executes that file.



If you were successful at running hello.py, it would print out hello world.





Running from IDLE


You can also edit and run programs from IDLE. Start by launching IDLE, either by clicking on the application icon on your computer or by typing:

$ python3 -m idlelib.idle



When IDLE launches, you see the Shell window. This is a Python REPL. You can type code and Python will immediately evaluate it. To create a program you need to create a file with Python code in it. To do that, click on the “File” menu, and select “New File”. You should see a new window pop up. This window is not a Shell window, it is an editor window. You will notice that it is empty and there is no Python prompt in it. In this window, you will type Python code.



IDLE has been launched and a new editor window (Untitled because it has not been saved) has been opened



Type your code into the window. Since you are doing the hello world example, type:

print("hello world")



You'll notice that IDLE uses a different color for print and "hello world". This is called syntax highlighting and is meant to aid in understanding your code. Now, you need to run the code. The easiest way to do this is to hit the F5 key on your keyboard. Alternatively, you can click on “Run”, and select “Run Module”. IDLE will ask you to save your file. Save it as hello.py. IDLE will bring the shell window to focus, print a line stating that it has restarted the shell, and print out hello world.



Code typed into the editor window.



This might seem trivial, but the shell window now has the state of your code. In this case, you only printed to the screen, so there is not much state. In future examples, you will see how you can use the integration between the editor and shell to provide an environment where you can quickly try out code, see the results, and inspect the output of a program.



Result of running Hello World from IDLE



If you need help navigating from the command prompt check out the appendix.





Unixy embellishments


On Unix platforms (Linux and OS X among others), files such as hello.py are often referred to as scripts. A script is a program, but the term is often used to distinguish native code from interpreted code. In this case, scripts are interpreted code, whereas the output from the compilation step of a language that compiles to machine code (such as C) is native code.

Note

It is not uncommon to hear about shell scripts, Perl scripts, Python scripts, etc. What is the difference between a Python script and a Python program? Nothing, really it is only semantics. A Python script usually refers to a Python program run from the command line, whereas a Python program is any program written in Python (which run the gamut of small 1-liners to fancy GUI applications, to “enterprise” class services).



Unix environments provide a handy way to make your script executable on it is own. By putting a hash bang (#!) on the first line of the file, followed by the path to the interpreter, and by changing the executable bit on the file, you can create a file that can run itself.

To have the script execute with the Python interpreter found in the environment, update your hello.py file to:

#!/usr/bin/env python3 print("hello world")



Note

This new first line tells the shell that executes the file to run the rest of the file with the #!/usr/bin/env python3 executable. (Shell scripts usually start with #!/bin/bash or #!/bin/sh.) Save hello.py with the new initial line.



Tip

#!/usr/bin/env is a handy way to indicate that the first python3 executable found on your PATH environment variable should be used. Because the python3 executable is located in different places on different platforms, this solution turns out to be cross-platform. Note that Windows ignores this line. Unless you are absolutely certain that you want to run a specific Python version, you should probably use #!/usr/bin/env.

Using hardcoded hashbangs such as:

#!/bin/python3



#!/usr/bin/python3.3





might work fine on your machine, but could lead to problems when you try to share your code and others do not have python3 where you specified it. If you require a specific version of Python, it is common to specify that in the README file.



Now you need to make the file executable. Open a terminal, cd to the directory containing hello.py and make the file executable by typing:

$ chmod +x hello.py



This sets the executable bit on the file. The Unix environment has different permissions (set by flipping a corresponding bit) for reading, writing, and executing a file. If the executable bit is set, the Unix environment will look at the first line and execute it accordingly, when the file is run.

Tip

If you are interested in knowing what the chmod command does, use the man (manual) command to find out by typing:

$ man chmod





Now you can execute the file by typing its name in the terminal and hitting enter. Type:

$ ./hello.py



And your program (or script) should run. Note the ./ included before the name of the program. Normally when you type a command into the terminal, the environment looks for an executable in the PATH (an environment variable that defines directories where executables reside). Unless . (or the parent directory of hello.py) is in your PATH variable you need to include ./ before the name (or the full path to the executable). Otherwise, you will get a message like this:

$ hello.py bash: hello.py command not found



Yes, all that work just to avoid typing python3 hello.py. Why? The main reason is that you want your program to be named hello (without the trailing .py). And perhaps you want the program on your PATH so you can run it at any time. By making a file executable, and adding a hashbang, you can create a file that looks like an ordinary executable. The file will not require a .py extension, nor will it need to be explicitly executed with the python3 command.





Summary


Running Python programs is easy. There is no lengthy compilation step. You need to point Python to the program you would like to run. Many editors also have the ability to run Python code. It is worthwhile to investigate how to do it with your editor. With IDLE, it is simple: you hit F5.





Exercises


Create a file hello.py with the code from this chapter in it.



Run hello.py from a terminal.



Run hello.py from within IDLE.



If you have another editor that you prefer, run hello.py from it.



If you are on a Unix platform, create a file called hello. Add the hello world code to it, and make the appropriate adjustments such that you can run the code by typing:

./hello





Writing and Reading Data


Programs will typically have input and output. This chapter will show how to print values to the screen and allow the end user to type in a value. In Python, both of these are really straightforward.





Simple output


The easiest way to provide the user with output is to use the print function, which writes to standard out. Standard out is where the computer writes its output. When you are in a terminal, standard out is printed on the terminal

>>> print('Hello there') Hello there



If you want to print out multiple items, you can provide them separated by commas. Python will insert a space between them. You can put strings and numbers in a print function:

>>> print('I am', 10, 'years old') I am 10 years old



A later chapter will look at strings in detail. It will discuss how to format them to get output to look a certain way.





Getting user input


The built-in input function will read text from a terminal. This function accepts text which it prints out as a prompt to the screen and waits until the user types something on standard in and hits enter. Standard in is where the computer reads its input. In a terminal, standard input can be read from what you type in:

>>> name = input('Enter your name:')



If you typed the above into the interpreter (the spaces around the = are not required but convention suggests that you type them to make your code more readable), it might look like your computer is frozen. In reality, Python is waiting for you to type in some input and hit enter. After you type something in and press enter, the variable name will hold the value you typed. Type the name Matt and press the enter key. If you print name it will print the value you just typed:

>>> print(name) Matt



Note

The value entered into the terminal when input is called is always a string. If you tried to perform math operations on it, it might not give you the answer you want:

>>> value = input('Enter a number:') 3 >>> other = input('Enter another:') 4



If you try to add value and other right now, you concatenate them (or join them together) because they are strings:

>>> type(value) <class 'str'> >>> value + other '34'



If you want to add these strings as if they were numbers you need to change them from a string into a number type. To convert a string to another type like an integer (a whole number) or float (a decimal number), you will need to use the int and float functions respectively.

If you want to numerically add value and other, you have to convert them to numbers using int:

>>> int(value) + int(other) 7



A future chapter will talk more about strings and number types.





Summary


Python gives you two functions that make it really easy to print data out to the screen and read input from the user. These functions are print and input. Remember that when you call the input function, you will always get a string back.





Exercises


Create some Python code that will prompt you to enter your name. Print out Hello and then the name.



Create a program that will ask a user how old they are. Print out some text telling them how old they will be next year.





Variables


Now that you know about running programs via the interpreter (or the REPL) and the command line, it is time to start learning about programming. Variables are the basic building blocks of computer programs.

Variables are important in Python, because in the Python world, everything is an object. (This is not quite true, keywords are not objects). Variables allow you to attach names to these objects so you can refer to them in future code.





Mutation and state


Two important programming concepts are state and mutation. State deals with a digital representation of a model. For example, if you want to model a light bulb, you may want to store its current status—is it on or off? Other possibly interesting states you could store include the type of bulb (CFL or incandescent), wattage, size, dimmable, etc.

Mutation deals with changing the state to a new or different state. For the light bulb example, it could be useful to have a power switch that toggles the state and changes it from off to on.

How is this related to variables? Remember that in Python everything is an object. Objects have state, and might be mutated. To keep track of these objects, you use variables.

Once you have objects that hold state and are mutable, then you have opened a world of possibilities. You can model almost anything you want if you can determine what state it needs, and what actions or mutations need to apply to it.





Python variables are like tags


Variables are the building blocks of keeping track of state. You might think of a variable as a label or tag. Important information is tagged with a variable name. To continue the light bulb example, suppose that you want to remember the state of your light bulb. Having that data is only useful if you have access to it. If you want to access it and keep track of its state you need to have a variable to tag that data. Here the state of the bulb is stored in a variable named status:

>>> status = "off"



This requires a little more examination because there is a bit going on there. Starting from the right, there is the word "off" surrounded by quotes. This is a string literal, or a built-in datatype that Python has special syntax for. The quotes tell Python that this object is a string. So Python will create a string object. A string stores textual data—in this case, the letters off.

This object has a few properties of interest. First, it has an id. You can think of the id as where Python stores this object in memory. It also has a type, in this case, a string. Finally, it has a value, here the value is 'off', because it is a string.

The = sign is the assignment operator in many programming languages. Do not be afraid of these technical terms, they are more benign than they appear. The assignment operator connects or binds together a variable name and its object. It indicates that the name on the left of it is a variable that will hold the object on the right. In this case, the variable name is status.

When Python creates a variable, it tells the object to increase its reference count. When objects have variables or other objects pointing to them, they have a positive reference count. When variables go away (an example is when you exit a function, variables in that function will go away), the reference count goes down. When this count goes down to zero, the Python interpreter will assume that no one cares about the object anymore and garbage collects it. This means it removes it from its memory, so your program doesn't get out of control and use all the memory of your computer.

Note

If you want to inspect the reference count of an object, you can call sys.getrefcount on it:

>>> import sys >>> names = [] >>> sys.getrefcount(names) 2



Do note that as this count may seem high, the documentation for this function states:

Return the reference count of object. The count returned is generally one higher than you might expect, because it includes the (temporary) reference as an argument to getrefcount().



Even though Python gives you this ability, typically you don't worry about the reference count and let Python handle cleaning up objects for us.



This is a feature of Python, and typically Python does this for you automatically, without any prompting from a user. In other languages, you need to manually tell the program to allocate and deallocate memory.

To drive the point home, reading the code again from the left this time. status is a variable that is assigned to the object that Python created for us. This object has a type, string, and holds the value of "off".



Two steps of an assignment to a literal. First, Python creates an object. The object has a value, "off", a type, string, and an id (the location of the object in memory). After the object is created, Python looks for any variable named status. If it exists, Python updates what object the variable is pointing to, otherwise, Python creates the variable and points it to the object.





Cattle tags


My grandfather had a cattle ranch, so I will pull out a non-nerdy analogy. If you have a cattle ranch of any size, it makes sense to have a good foreman who will keep track of your cattle (your investment).

One way to keep track of cattle is to use cattle tags. These small tags attached to the ear of a cow can be used to identify and track individual cows.

To pull this back to programming, rather than running a cattle ranch, you are managing aspects of your program. A program can hold many distinct pieces of information that you want to remember or keep track of. This information is the state. For example, if you needed to track data pertinent to humans you might want to track age, address, and name.

Just like how ranchers tag their cattle to keep track of them, programmers create variables to keep track of data. Look at the example again:

>>> status = "off"



This tells Python to create a string with the contents of off. Create a variable named status, and attach it to that string. Later on, when you need to know what the status is, you can ask your program to print it out like so:

>>> print(status) off



It is entirely possible to create state and lose it to the ether if you neglect to put it in a variable. It is somewhat useless to create objects that you would not use, but again it is possible. Suppose you want to keep track of the bulb’s wattage. If you write:

>>> "120 watt"



It tells Python to create a string object with the content of 120 watt. This is problematic because you forgot to assign it to a variable. Now, you have no way of using this object. Python will only let you access data that is stored in variables, so it is impossible for you to use this item now. Objects are accessed by using their variable names. If this was information that you needed in your program, a better solution would be the following:

>>> wattage = "120 watt"



Later on, in your program you can access wattage, you can print it out, and you can even assign another variable to it, or assign wattage to another new value (say if your incandescent bulb broke and you replaced it with an LED bulb):

>>> incandescent = wattage >>> wattage = "25 watt" >>> print(incandescent, wattage) 120 watt 25 watt



Managing state is a core aspect of programming. Variables are one mechanism to manage it.





Rebinding variables


Much like cow tags, variables tend to stay with an object for a while, but they are transferable. Python lets you easily change the variable:

>>> num = 400 >>> num = '400' # now num is a string



In the above example num was originally pointing to an integer but then was told to point to a string.



This illustrates rebinding variables. Variables can be rebound to any type. Python makes no effort to prevent this or complain. When an object no longer has any variable pointing to it, it is cleaned up by Python, or garbage collected.



Note

The variable does not care about the type. In Python, the type is attached to the object.



There is no limit to how often you can change a variable. But you should be careful not to change a variable if you still need access to the old data. Once you remove all variables from an object, you are essentially telling Python to destroy (garbage collect is the proper geeky term) the object when it has the chance, to free up any internal memory it occupies.

Tip

This is a case where Python allows you to do something, but you probably don't want to do it in real life. Just because you can rebind a variable to a different type, doesn't mean you should. Changing the type of a variable is confusing to you when you read your code later. It is also confusing to others who are using your code. Don't use the same variable to point to different types.

This is a point of confusion for those who are new to Python. They sometimes reuse the same variable throughout their code because they mistakenly believe that it will save memory. As you have seen this is not the case. The variable itself is very lightweight. The object is what uses memory. Reusing a variable is not going to change how memory on the object is handled, but it will be confusing to those who have to read the code later.





Naming variables


Python is somewhat particular about naming variables. It has conventions that most Python programmers follow. Some of these are enforced, some are not. One that is enforced by the interpreter is a variable should not have the name of a keyword. The word break is a keyword and hence cannot be used as a variable. You will get a SyntaxError if you try to use it as a variable. Even though this code looks perfectly legal, Python will complain:

>>> break = 'foo' File "<stdin>", line 1 break = 'foo' ^ SyntaxError: invalid syntax



If you find yourself with a SyntaxError that looks like normal Python code, check that the variable name is not a keyword.

Note

Keywords are reserved for use in Python language constructs, so it confuses Python if you try to make them variables.

The module keyword has a kwlist attribute, which is a list containing all the current keywords for Python:

>>> import keyword >>> print(keyword.kwlist) ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']



Another method for examining keywords in the REPL is to run help(). This puts you in a help utility in the REPL, from which you can type commands (that aren't Python). Then type keywords and hit enter. You can type any of the keywords and it will give you some documentation and related help topics. To exit the help utility hit enter by itself.





Additional naming considerations


In addition to the aforementioned rule about not naming variables after keywords, there are a few best practices encouraged by the Python community. The rules are simple—variables should:

be lowercase

use an underscore to separate words

not start with numbers

not override a built-in function



Here are examples of variable names, both good and bad:

>>> good = 4 >>> bAd = 5 # bad - capital letters >>> a_longer_variable = 6 # this style is frowned upon >>> badLongerVariable = 7 # bad - starts with a number >>> 3rd_bad_variable = 8 File "<stdin>", line 1 3rd_bad_variable = 8 ^ SyntaxError: invalid syntax # bad - keyword >>> for = 4 File "<stdin>", line 1 for = 4 ^ SyntaxError: invalid syntax # bad - built-in function >>> compile = 5



Tip

Rules and conventions for naming in Python come from a document named “PEP 8 – Style Guide for Python Code” 8. PEP stands for Python Enhancement Proposal, which is a community process for documenting a feature, enhancement, or best practice for Python. PEP documents are found on the Python website.





Note

Although Python will not allow keywords as variable names, it will allow you to use a built-in name as a variable. Built-ins are functions, classes, or variables that Python automatically preloads for you, so you get easy access to them. Unlike keywords, Python will let you use a built-in as a variable name without so much as a peep. However, you should refrain from doing this, it is a bad practice.

Using a built-in name as a variable name shadows the built-in. The new variable name prevents you from getting access to the original built-in. Doing so essentially takes the built-in variable and co-opts it for your use. As a result, access to the original built-in may only be obtained through the __builtins__ module. But it is much better not to shadow it in the first place.

Here is a list of Python’s built-ins that you should avoid using as variables:

>>> dir(__builtins__) ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']





Tip

Here are a few built-ins that would be tempting variable names otherwise: dict, id, list, min, max, open, range, str, sum, and type.





Summary


In Python, everything is an object. Objects hold state, which is also called the value. To keep track of objects you use variables. Python variables are like cattle tags, they are attached to the object and have a name. But the object has the important data, the value and type of data.

This chapter also discussed rebinding of variables. Python allows you to do this, but you should be careful not to change the type of the variable, as that can be confusing to readers of the said code. Finally, the chapter discussed naming conventions for Python variables.





Exercises


Create a variable, pi, that points to an approximation for the value of π. Create a variable, r, for the radius of a circle that has a value of 10. Calculate the area of the circle (π times the radius squared).

You can do multiplication with * and you can square numbers using **. For example, 3**2 is 9.



Create a variable, b, that points to the base of a rectangle with a value of 10. Create a variable, h, that points to the height of a rectangle with a value of 2. Calculate the perimeter. Change the base to 6 and calculate the perimeter again.





8 - https://www.python.org/dev/peps/pep-0008/





More about Objects


This chapter will dive into objects a little bit more. You will cover three important properties of objects:

identity

type

value





Identity


Identity at its lowest level refers to an object’s location in the computer’s memory. Python has a built-in function called id that tells you the identity of an object:

>>> name = "Matt" >>> id(name) 140310794682416



When you type this, the identity of the string "Matt" will appear as 140310794682416 (which refers to a location in the RAM of your computer). This will generally vary from computer to computer and for each time you start the shell, but the id of an object is consistent across the lifetime of a program.

It is possible for a single cow to have two tags on its ears and it is also possible for two variables to refer to the same object. If you want another variable—first—to also refer to the same object referred to by name, you could do the following:

>>> first = name





This illustrates what happens when you bind a variable to an existing variable. They both point to the same object. Note that this does not copy the variable! Also note that the object has a value, "Matt", a type, and an id.



This tells Python to give the first variable the same id as name. Running id on either of the two variables will return the same id:

>>> id(first) 140310794682416 >>> id(name) 140310794682416



What is identity used for? Actually not much. When you program in Python, you typically are not concerned with low-level details such as where the object is living in the RAM of the computer. But identity is used to illustrate when objects are created and if they are mutable. It is also used indirectly for doing identity checks with is.

The is operator checks for identity equality and validates whether or not two variables point to the same object:

>>> first is name True



If you print either first or name at the REPL, it will print the same value because they are both pointing to the exact same object:

>>> print(first) Matt >>> print(name) Matt



If I had a cattle tag, I could take it off of one cow and attach it to another. Just like a cattle tag, you can take a variable and point it to a new object. I can make name point to a new object. You will see that the identity of name has changed. But first is still the same:

>>> name = 'Fred' >>> id(name) 140310794682434 >>> id(first) 140310794682416





Type


Another property of an object is its type. Common types are strings, integers, floats, and booleans. There are many other kinds of types, and you can create your own as well. The type of an object refers to the class of an object. A class defines the state of data an object holds, and the methods or actions that it can perform. Python allows you to easily view the type of an object with the built-in function, type:

>>> type(name) <class 'str'>



The type function tells you that the variable name points to a string (str).

The table below shows the types for various objects in Python.

Object Type

String str

Integer int

Floating point float

List list

Dictionary dict

Tuple tuple

function function

User-defined class (subclass object) type

Instance of class (subclass of class) class

Built-in function builtin_function _or_method

type type

Due to duck-typing, the type function is not used too frequently. Rather than check if an object is of a certain type that provides an operation, normally you try and do that operation.

Sometimes though you have data and need to convert it to another type. This is common when reading data from standard in. Typically it would come in as a string, and you might want to change it into a number. Python provides built-in classes, str, int, float, list, dict, and tuple that convert (or coerce) to the appropriate type if needed:

>>> str(0) '0' >>> tuple([1,2]) (1, 2) >>> list('abc') ['a', 'b', 'c']



Note

Duck typing comes from a saying used in the 18th century to refer to a mechanical duck. Much like the Turing Test, the saying went:

If it looks like a duck, walks like a duck and quacks like a duck, then it’s a duck



But I prefer the scene in Monty Python and the Holy Grail, where a lady is determined to be a witch because she weighs as much as a duck. (If this is confusing go watch the movie, I find it enjoyable). The idea is that because she had characteristics (her weight) that were the same as a duck’s, she could be considered a witch.

Python takes a similar approach. If you want to loop over an object, you put it in a for loop. You don't check first to see if it is a list or a subclass of a list, you just loop over it. If you want to use a plus operation, you don't check to see if the object is a number, or string (or another type that supports addition). If the operation fails, that’s ok, it is an indication that you are not providing the correct type.

If you are familiar with object-oriented programming, duck typing eases the requirement for subclassing. Rather than inheriting multiple classes to take advantage of behaviors they provide, you need to implement the protocols (usually by defining a method or two). For example, to create a class that adds, you need to implement a .__add__ method. Any class can define that method and respond to the plus operation.





Mutability


Another interesting property of an object is its mutability. Many objects are mutable while others are immutable. Mutable objects can change their value in place, in other words, you can alter their state, but their identity stays the same. Objects that are immutable do not allow you to change their value. Instead, you can change their variable reference to a new object, but this will change the identity of the variable as well.

In Python, dictionaries and lists are mutable types. Strings, tuples, integers, and floats are immutable types. Here is an example demonstrating that the identity of a variable holding an integer will change if you change the value. First, you will assign an integer to the variable age and inspect the id:

>>> age = 1000 >>> id(age) 140310794682416



Notice that if you change the value of the integer, it will have a different id:

>>> age = age + 1 >>> id(age) 140310793921824





This illustrates that when you try to change an integer, you will necessarily create a new integer. Integers are immutable, and you can't change their value.



Here is an example of changing a list. You will start with an empty list, and examine the id. Note that even after you add an item to the list, the identity of the list is unchanged, hence it is mutable. First, you will create a list and look at the id:

>>> names = [] >>> id(name) 140310794682432



Now, add a string into the list. There are a few things to note. The return value of the .append method didn't show anything (ie, it is not returning a new list). But if you inspect the names variable, you will see that the new name is in there. Also, the id of the list is still the same. You have mutated the list:

>>> names.append("Fred") >>> names ['Fred'] >>> id(name) 140310794682432





This illustrates that when you append an object into a list, you change the value of the list. The list is mutated. You can add and remove items from it, but the id of the list stays the same.



Mutable objects should not be used for keys in dictionaries and can present problems when used as default parameters for functions.





Using IDLE


At this point, it would be good to try this out in IDLE (or your favorite editor that has REPL integration). Because IDLE comes with a REPL, you could type in the previous code and inspect it from there. But you can also write code, run it, and then inspect it from the REPL. To try it, open a new file, and type the following code into it:

name = "Matt" first = name age = 1000 print(id(age)) age = age + 1 print(id(age)) names = [] print(id(names)) names.append("Fred") print(id(names))



Save this as a file, call it iden.py. Then run the file. In IDLE, you need to hit F5 to do this. In the REPL, you should see four numbers printed out. The first two should be different, illustrating that an integer is immutable. The last two numbers are the same. They are the same because even though the list, names, was mutated, the id is still the same. This by itself is nothing particularly novel.

The interesting part now is that if you type dir() in the REPL, it will show you the variables. You will see that the global variables from iden.py are now available.



This illustrates running code and then inspecting it from the REPL in IDLE. If you do not use IDLE, figure out how to do this from your editor.



From the REPL in IDLE you have access to all the global variables. You can inspect name or names. You can even call functions or methods like names.append("George").

The ability to inspect what just ran gives you the chance to quickly inspect the code, and try things out. It is not uncommon for experienced Python developers to write code in the REPL, paste it into a file, re-run the file, write more code in the REPL, and continue writing code in this manner.





Summary


In Python, everything is an object. Objects have three properties:

A Type - Indicates what the class is for the object.

A Value - The data that the object holds. When you test if an object is equal to another object (with ==), you are checking against the value.

An Id - A unique id for the object. In the Python version found at www.python.org, this is essentially the location in memory of the object, which will be a unique value. When you check whether two objects have the same identity (with is), you are checking whether the id is the same.



You also examined how mutable objects, such as lists, can change their value, while immutable objects, like numbers or strings, cannot be changed.





Exercises


Create a variable that points to a floating point number. Examine the id, type, and value of that number. Update the variable by adding 20 to it. Re-examine the id, type, and value. Did the id change? Did the value change?



Create a variable pointing to an empty list. Examine the id, type, and value of the list. Append the number 300 to the list. Re-examine the id, type, and value. Did the id change? Did the value change?





Numbers


This chapter will discuss manipulating numbers with Python. Integers (whole numbers like -1, 5, or 2000) and Floating Points (the computer’s approximation of real numbers like .333, 0.5 or -1000.234) are available in Python and provide easy numerical manipulation. Out of the box, Python provides support for addition, subtraction, multiplication, division, power, modulo, and more!

Unlike other languages, in Python, everything is an object, including numbers. Integers are of class int:

>>> type(1) <class 'int'>



Floating point numbers are of class float:

>>> type(2.0) <class 'float'>



Everything has a level of precision. It’s up to the user to determine if it is sufficient for their calculations. Python’s floats are represented internally using a binary representation (as per the IEEE 754 standard for floating point numbers). Floats have a certain amount of precision and rounding errors are possible. In fact, one should expect rounding errors. (If you need more precision, the decimal module provides a more precise albeit slower implementation).

As a quick example of precision, examine what happens when you perform this apparently simple subtraction operation:

>>> print(1.01 - .99) 0.020000000000000018



Tip

If you are interested in understanding more about floats and how computers represent them, Wikipedia 9 has more information on the subject.





Addition


The Python REPL can be used as a simple calculator. If you want to add two integers, type in the expression:

>>> 2 + 6 8



Note

The math example above did not bind the result to a variable. For a simple calculation printing out the result to the terminal may be sufficient. If you need the result after the fact, the Python interpreter stores the last result in a variable named _:

>>> 2 + 6 8 >>> result = _ >>> result 8





Note that adding two integers together results in an integer.

Likewise, you can also add two floats together:

>>> .4+.01 0.41000000000000003



This example illustrates once again that care is needed when using floating point numbers, as you can lose precision (the real result would be 0.41).

What happens when you add an integer and a float?

>>> 6 + .2 6.2



Python decided that because you are adding an integer and a float, you need floating point arithmetic. In this case, Python converts or coerces, 6 to a float behind the scenes, before adding it to .2. Python has given you the answer back as a float.

Note

If you have an operation involving two numerics, coercion generally does the right thing. For operations involving an integer and a float, the integer is coerced to a float.



Note

Coercion between strings and numerics does not occur with most mathematical operations. Two exceptions are the string formatting operator, and the multiplication operator.

When you use % with a string on the left side (the left operand) and any object (including numbers) on the right side (the right operand), Python performs the formatting operator:

>>> print('num: %s' % 2) num: 2



If the left operand is a string and you use the multiplication operator, *, Python performs repetition:

>>> 'Python!' * 2 'Python!Python!' >>> '4' * 2 '44'





Note

Explicit conversion can be done with the int and float built-in classes. (Although these look like functions they are really classes):

>>> int(2.3) 2 >>> float(3) 3.0





Subtraction


Subtraction is similar to addition. Subtraction of two integers or two floats returns an integer or a float respectively. For mixed numeric types, the operands are coerced before performing subtraction:

>>> 2 - 6 -4 >>> .25 - 0.2 0.04999999999999999 >>> 6 - .2 5.8





Multiplication


In many programming languages, the * (asterisk) is used for multiplication. You can probably guess what is going to happen when you multiply two integers:

>>> 6 * 2 12



If you have been following carefully, you will also know what happens when you multiply two floats:

>>> .25 * 12.0 3.0



And if you mix the types of the product you end up with a float as a result:

>>> 4 * .3 1.2



Note that the float result in these examples appears correct, though you should be careful, due to floating point precision issues, not to assume that you would always be so lucky.





Division


In Python (like many languages), the / (slash) symbol is used for division:

>>> 12 / 4 3.0



Python 3 also addressed what many considered to be a wart in prior versions of Python. The result of dividing two integers is a float:

>>> 3 / 4 0.75



Previously, Python performed integer division. If you want that behavior, you can use the // operator. What integer does Python use? The floor of the real result—take the answer and round down:

>>> 3 // 4 0





Modulo


The modulo operator (%) calculates the modulus. This is the same as the remainder of a division operation when the operators are positive. This is useful for determining whether a number is odd or even (or whether you have iterated over 1000 items):

# remainder of 4 divided by 3 >>> 4 % 3 1 >>> 3 % 2 # odd if 1 is result 1 >>> 4 % 2 # even if 0 is result 0



Tip

Be careful with the modulo operator and negative numbers. Modulo can behave differently, depending on which operand is negative. It makes sense that if you are counting down, the modulo should cycle at some interval:

>>> 3 % 3 0 >>> 2 % 3 2 >>> 1 % 3 1 >>> 0 % 3 0



What should -1 % 3 be? Since you are counting down it should cycle over to 2 again:

>>> -1 % 3 2



But when you switch the sign of the denominator, the behavior becomes weird:

>>> -1 % -3 -1



Python guarantees that the sign of the modulo result is the same as the denominator (or zero). To further confuse you:

>>> 1 % -3 -2



The takeaway here is that you probably do not want to do modulo with negative numbers on the denominator unless you are sure that is what you need.





Power


Python also gives you the power operator by using ** (double asterisks). If you wanted to square 4 (4 is the base, 2 is the exponent), the following code will do it:

>>> 4 ** 2 16



Exponential growth tends to let numbers get large pretty quickly. Consider raising 10 to the 100th power:

>>> 10 ** 100 10000000000000000000000000000000000000 00000000000000000000000000000000000000 0000000000000000000000000



Programs need to use a certain amount of memory to store integers. Because integers are usually smaller numbers, Python optimizes for them, to not waste memory. Under the covers, it can coerce system integers to long integers to store larger numbers. Python 3 does this automatically for you.

An analogy might be a scale. If you are always weighing small amounts, you might want a small scale. If you deal in sand, you will probably want to put the sand in a bag to make it easier to handle. You will have a bunch of small bags that you will use. But if you occasionally need to weigh larger items that do not fit on the small scale, you need to pull out a bigger scale, and a bigger bag. It would be a waste to use the bigger bag and scale for many of the smaller items.

Similarly, Python tries to optimize storage space for integers towards smaller sizes. When Python does not have enough memory (a small bag) to fit larger integers in, it coerces the integer into a long integer. This is actually desirable because, in some environments, you run into an overflow error here, where the program dies (or Pac-Man refuses to go over level 255—since it stored the level counter in an 8-bit number).

Note

Python includes the operator module which provides functions for common mathematical operations. When using more advanced features of Python such as lambda functions or list comprehensions, this module comes in handy:

>>> import operator >>> operator.add(2, 4) # same as 2 + 4 6





Order of operations


When you are performing math, you do not apply all the operations from left to right. You do the multiplication and division before the addition and subtraction. Computers work the same way. If you want to perform addition (or subtraction) first, use parentheses to indicate the order of operations:

>>> 4 + 2 * 3 10 >>> (4 + 2) * 3 18



As illustrated in the example, anything in parentheses is evaluated first.





Other operations


The help section from the REPL is pretty useful. There is a topic called NUMBERMETHODS that explains how all of the number operations work.





Summary


Python has built-in support for the basic mathematical operations. Addition, subtraction, multiplication, and division are all included. In addition, the power and modulus operations are available. If you need to control which order the operations occur, wrap parentheses around the operation that you want to happen first.

If you need a simple calculator, rather than opening a calculator application, give Python a try. It should be more than capable for most tasks.





Exercises


You slept for 6.2, 7, 8, 5, 6.5, 7.1, and 8.5 hours this week. Calculate the average number of hours slept.



Is 297 divisible by 3?



What is 2 raised to the tenth power?



Wikipedia defines leap years as:

Every year that is exactly divisible by four is a leap year, except for years that are exactly divisible by 100, but these centurial years are leap years if they are exactly divisible by 400. For example, the years 1700, 1800, and 1900 are not leap years, but the years 1600 and 2000 are.

—https://en.wikipedia.org/wiki/Leap_year



Write Python code to determine if 1800, 1900, 1903, 2000, and 2002 are leap years.





9 - https://en.wikipedia.org/wiki/Floating_point





Strings


Strings are immutable objects that hold character data. A string could hold a single character, a word, a line of words, a paragraph, multiple paragraphs, or even zero characters.

Python denotes strings by wrapping them with ' (single quotes), " (double quotes), """ (triple doubles) or ''' (triple singles). Here are some examples:

>>> character = 'a' >>> name = 'Matt' >>> with_quote = "I ain't gonna" >>> longer = """This string has ... multiple lines ... in it""" >>> latin = '''Lorum ipsum ... dolor''' >>> escaped = 'I ain\'t gonna' >>> zero_chars = '' >>> unicode_snake = "I love \N{SNAKE}"



Notice that the strings always start and end with the same style of quote. As illustrated in the with_quote example you can put single quotes inside of a double-quoted string—and vice versa. Furthermore, if you need to include the same type of quote within your string, you can escape the quote by preceding it with a \ (backslash). When you print out an escaped character the backslash is ignored.

Note

Attentive readers may wonder how to include a backslash in a string. To include a backslash in a normal string, you must escape the backslash with ... you guessed it, another backslash:

>>> backslash = '\\' >>> print(backslash) \





Note

Here are the common ways to escape characters in Python:

Escape Sequence

Output



\\

Backslash



\'

Single quote



\"

Double quote



\b

ASCII Backspace



\n

Newline



\t

Tab



\u12af

Unicode 16 bit



\U12af89bc

Unicode 32 bit



\N{SNAKE}

Unicode character



\o84

Octal character



\xFF

Hex character





Tip

If you do not want to use an escape sequence, you can use a raw string by preceding the string with an r. Raw strings are normally used two places. They are used in regular expressions, where the backslash is also used as an escape character. You can use regular expressions to match characters (such as phone numbers, names, etc) from text. The re module in the Python standard library provides support for regular expressions. Raw strings are also used in Windows paths where the backslash is a delimiter.

Raw strings interpret the character content literally (ie. there is no escaping). The following illustrates the difference between raw and normal strings:

>>> slash_t = r'\tText \\' >>> print(slash_t) \tText \\ >>> normal = '\tText \\' >>> print(normal) Text \





Python also has a triple quoting mechanism for defining strings. Triple quotes are useful for creating strings containing paragraphs or multiple lines. Triple-quoted strings are also commonly used in docstrings. Docstrings will be discussed in the chapter on functions. Below is an example of a multi-line triple-quoted string:

>>> paragraph = """Lorem ipsum dolor ... sit amet, consectetur adipisicing ... elit, sed do eiusmod tempor incididunt ... ut labore et dolore magna aliqua. Ut ... enimad minim veniam, quis nostrud ... exercitation ullamco laboris nisi ut ... aliquip ex ea commodo consequat. Duis ... aute irure dolor in reprehenderit in ... voluptate velit esse cillum dolore eu ... fugiat nulla pariatur. Excepteur sint ... occaecat cupidatat non proident, sunt ... in culpa qui officia deserunt mollit ... anim id est laborum."""



A nice benefit of using triple-quoted strings is that you can embed single and double quotes inside it without escaping them:

>>> """This string has double " and single ... quotes ' inside of it""" 'This string has double " and single\nquotes \' inside of it'



Unless they butt up to the end of the string, then you will need to escape the final quote:

>>> """He said, "Hello"""" File "<stdin>", line 1 """He said, "Hello"""" ^ SyntaxError: EOL while scanning string literal >>> """He said, "Hello\"""" 'He said, "Hello"'





Formatting Strings


Storing strings in variables is nice, but being able to compose strings of other strings and manipulate them is also necessary. One way to achieve this is to use string formatting.

In Python 3, the preferred way to format strings is to use the .format method of strings. Below, you tell Python to replace {} (a placeholder) with the contents of name or the string Matt:

>>> name = 'Matt' >>> print('Hello {}'.format(name)) Hello Matt



Another useful property of formatting is that you can also format non-string objects, such as numbers:

>>> print('I:{} R:{} S:{}'.format(1, 2.5, 'foo')) I:1 R:2.5 S:foo





Format string syntax


Format strings have a special syntax for replacement fields. If an object is passed into the format string, attributes can be looked up using .attribute_name syntax. There is also support for pulling index-able items out by using [index] as well. The Python documentation refers to these as field names. The field names can be empty, a name of a keyword argument, a number of a positional argument, or index of a list or dictionary (in square brackets):

>>> 'Name: {}'.format('Paul') 'Name: Paul' >>> 'Name: {name}'.format(name='John') 'Name: John' >>> 'Name: {[name]}'.format({'name':'George'}) 'Name: George'



The curly braces ({ and }) can also contain an integer inside of them. The integer refers to the zero based position of the argument passed into .format. Below is an example of using the numbers of positional arguments in the placeholders. The first argument to .format, 'Paul', is at position 0, the second, 'George', is position 1, and 'John' is at 2:

>>> 'Last: {2} First: {0}'.format('Paul', 'George', ... 'John') 'Last: John First: Paul'



There is a whole language for formatting strings. If you insert a colon following the field name, you can provide further formatting information. The format is below. Anything in square brackets is optional:

:[[fill]align][sign][#][0][width][grouping_option][.precision][type]



The following tables lists the fields and their meaning.

Field Meaning

fill Character used to fill in align (default is space)

align Alight output < (left align), > (right align), ^ (center align), or = (put padding after sign)

sign For numbers + (show sign on both positive and negative numbers, - (default, only on negative), or space (leading space for positive, sign on negative)

# Prefix integers. 0b (binary), 0o (octal), or 0x (hex)

0 Enable zero padding

width Minimum field width

grouping_option Number separator , (use comma for thousands separator), _ (Use underscore for thousands separator)

.precision For floats (digits after period (floats), for non-numerics (max length)

type Number type or s (string format default) see Integer and Float charts

The tables below lists the various options you have for formatting integer and floating point numbers.

Integer Types Meaning

b binary

c character - convert to Unicode character

d decimal (default)

n decimal with locale-specific separators

o octal

x hex (lower-case)

X hex (upper-case)

Float Types Meaning

e/E Exponent. Lower/upper-case e

f Fixed point

g/G General. Fixed with exponent for large, and small numbers (g default)

n g with locale-specific separators

% Percentage (multiplies by 100)





Some format examples


Here are a few examples of using .format. To format a string in the center of 12 characters surrounded by *, use the code below. * is the fill character, ^ is the align field, and 12 is the width field:

>>> "Name: {:*^12}".format("Ringo") 'Name: ***Ringo****'



Next, you format a percentage using a width of 10, one decimal place, and the sign before the width padding. = is the align field, + ensures that there is always a sign (negative or positive), 10.1 are the width and precision fields, and % is the float type, which converts the number to a percentage:

>>> "Percent: {:=+10.1%}".format(-44/100) 'Percent: - 44.0%'



Below are a binary and a hex conversion. The integer type field is set to b and x respectively:

>>> "Binary: {:b}".format(12) 'Binary: 1100' >>> "Hex: {:x}".format(12) 'Hex: c'



Note

The .format method on a string provides an alternative for the % operator which is similar to C’s printf. The % operator is still available and some users prefer it as it requires less typing for simple statements and because it is similar to C. %s, %d, and %x are replaced by their string, integer, and hex values respectively. Here are some examples:

>>> "Num: %d Hex: %x" % (12, 13) 'Num: 12 Hex: d' >>> "%s %s" % ('hello', 'world') 'hello world'





Tip

A great resource for formatting is in the built-in help documentation, available in the REPL. Type:

>>> help()



Which puts you in the help mode, and gives you a help> prompt. Then type:

help> FORMATTING



You can scroll through here and find many examples. A bare return from the help> prompt will return you to the normal prompt.

Another resource is found at https://pyformat.info/. This website contains many formatting examples with both .format and the older % operator.

There is also an entry in help for strings, located under STRINGS.





F-Strings


Python 3.6 introduced a new type of string, called f-string. If you precede a string with an f, it will allow you to include code inside of the placeholders. Here is a basic example:

>>> name = 'matt' >>> f'My name is {name}' 'My name is matt'



Python will look in the placeholder and evaluate the code there. Note that the placeholder can contain function calls, method calls, or any other arbitrary code:

>>> f'My name is {name.capitalize()}' 'My name is Matt'



You can also provide format strings following a colon:

>>> f'Square root of two: {2**.5:5.3f}' 'Square root of two: 1.414'





Summary


In this chapter, strings were introduced. Strings can be defined with various delimiters. Unlike other languages, which may distinguish between a string defined with " and one defined with ', Python makes no distinction. Triple-quoted strings, however, may span multiple lines.

We also looked at the .format method and gave examples of formatting strings. Finally, the chapter introduced a new feature in Python 3.6, f-strings.





Exercises


Create a variable, name, pointing to your name. Create another variable, age, holding an integer value for your age. Print out a string formatted with both values. If your name was Fred and age was 23 it would print:

Fred is 23





Create a variable, paragraph, that has the following content:

"Python is a great language!", said Fred. "I don't ever remember having this much fun before."





Go to https://unicode.org and find the symbol omega in the Greek character code chart. Create a string that holds the omega character, using both the Unicode code point (\u form) and Unicode name (\N form). The code point is the hex number in the chart, the name is the bolded capital name following the code point. For example, the theta character has the code point of 03f4 and a name of GREEK CAPITAL THETA SYMBOL.



Make a variable, item, that points to a string, "car". Make a variable, cost, that points to 13499.99. Print out a line that has item in a left-justified area of 10 characters, and cost in a right-justified area of 10 characters with 2 decimal places and commas in the thousands place. It should look like this (without the quotes):

'car 13,499.99'





dir, help, and pdb


You have only touched the surface of strings, but you need to take a break to discuss two important functions and one library that come with Python. The first function is dir, which illustrates how powerful and useful the REPL is. The dir function returns the attributes of an object. If you had a Python interpreter open and wanted to know what the attributes of a string are, you can do the following:

>>> dir('Matt') ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']



dir lists all the attributes of the object passed into it. Since you passed in the string 'Matt' to dir, the function displays the attributes of a string. This handy feature of Python illustrates its “batteries included” philosophy. Python gives you an easy mechanism to discover the attributes of any object. Other languages might require special websites, documentation or IDEs to access similar functionality. But in Python, because you have the REPL, you can get at this information quickly and easily.

The attribute list is in alphabetical order, and you can normally ignore the first couple of attributes starting with __. Later on, you will see attributes such as capitalize (which is a method that capitalizes a string), format (which as was illustrated previously, allows for formatting of strings), or lower (which is a method used to ensure the string is lowercase). These attributes happen to be methods, which are functions that are attached to objects. To call, or invoke a function, you place a period after the object, then the method name, then parentheses.

The three methods are invoked below:

>>> print('matt'.capitalize()) Matt >>> print('Hi {}'.format('there')) Hi there >>> print('YIKES'.lower()) yikes





Dunder methods


You might be wondering what all the attributes starting with __ are. People call them special methods, magic methods, or dunder methods since they start (and end) with double underscores (Double UNDERscores). “Dunder add” is one way to say __add__, “the add magic method” is another. Special methods determine what happens under the covers when operations are performed on an object. For example, when you use the + or % operator on a string, the .__add__ or .__mod__ method is invoked respectively.

Beginner Pythonistas can usually ignore dunder methods. When you start implementing your own classes and want them to react to operations such as + or %, you can define them.

Tip

In the help() documentation is an entry, SPECIALMETHODS, that describes these methods.

Another place where these are described is on the Python website. Go to Documentation, Language Reference, Data Model. It is tucked away in there.





help


help is another built-in function that is useful in combination with the REPL. The book previously mentioned invoking help(), without any arguments, to bring up help documentation.

The help function also provides documentation for a method, module, class, or function if you pass them in as an argument. For example, if you are curious what the attribute upper on a string does, the following gives you the documentation:

>>> help('some string'.upper) Help on built-in function upper: upper(...) method of builtins.str instance S.upper() -> str Return a copy of S converted to uppercase.



The help function, combined with the REPL, allows you to read up on documentation without having to go to a browser, or even have internet access. If you were stranded on a desert island, you should be able to learn Python, provided you had a computer with Python installed and a power source.





pdb


Python also includes a debugger to step through code. It is found in a module named pdb. This library is modeled after the gdb library for C. To drop into the debugger at any point in a Python program, insert the code:

import pdb; pdb.set_trace()



These are two statements here, but I typically type them in a single line separated by a semicolon—that way I can easily remove them with a single keystroke from my editor when I am done debugging. This is also about the only place I use a semicolon in Python code (two statements in a single line).

When this line is executed, it will present a (pdb) prompt, which is similar to the REPL. Code can be evaluated at this prompt and you can inspect objects and variables as well. Also, breakpoints can be set for further inspection.

Below is a table listing useful pdb commands:

Command Purpose

h, help List the commands available

n, next Execute the next line

c, cont, continue Continue execution until a breakpoint is hit

w, where, bt Print a stack trace showing where execution is

u, up Pop up a level in the stack

d, down Push down a level in the stack

l, list List source code around current line

Note

In Programming Pearls, Jon Bentley states:

When I have to debug a little algorithm deep inside a big program, I sometimes use debugging tools... though, print statements are usually faster to implement and more effective than sophisticated debuggers.



I've heard Guido van Rossum, the creator of Python, voice the same opinion: he prefers print debugging. Print debugging is easy, simply insert print functions to provide clarity as to what is going on. This is often sufficient to figure out a problem. Make sure to remove these debug statements or change them to logging statements before releasing the code. If more exploration is required, you can always use the pdb module.





Summary


Python provides many tools to make your life easier. If you learn to use the REPL, you can take advantage of them. The dir function will help you see what the attributes of an object are. Then, you can use the help function to inspect those attributes for documentation.

This chapter also introduced the pdb module. This module allows you to step through code, which can be useful for debugging.





Exercises


Open a REPL, and create a variable, name, with your name in it. List the attributes of the string. Print out the help documentation for the .find and .title methods.



Open a REPL, and create a variable, age, with your age in it. List the attributes of the integer. Print out the help documentation for the .numerator method.





Strings and Methods


In the previous chapter you learned about the built-in dir function and saw some methods you can call on string objects. Because strings are immutable, these methods do not mutate the string, but rather return a new string or a new result. Strings allow you create a new version that is capitalized, return a formatted string, or create a lowercase string, as well as many other actions. You do this by calling methods.

Methods are functions that are called on an instance of a type. What does this mean? The string type allows you to call a method (another term for call is invoke) by placing a . (period) and the method name directly after the variable name holding the data (or the data itself), followed by parentheses with arguments inside of them.

Note

In this book, I place a period in front of methods. This is meant to remind you that you need to have an object before the method. I will mention the .capitalize method, rather than saying capitalize. The invocation looks like this on the text object:

text.capitalize()



This is in contrast to a function, like help, which you invoke by itself (there is no object or period before it):

help()





Illustration of calling a method on a string. The method does not change the string because it is immutable. Rather, the method returns a new string.



Here is an example of calling the .capitalize method on a variable pointing to a string and a string literal. Note that this does not change the object on which it is called. Because a string is immutable, the result of the method is a new object with the capitalized value:

>>> name = 'matt' # invoked on variable >>> correct = name.capitalize() >>> print(correct) Matt



Note that name does not change:

>>> print(name) matt



Note, the .capitalize method does not have to be called on a variable. You can invoke the method directly on a string literal:

>>> print('fred'.capitalize()) Fred



In Python, methods and functions are first-class objects. As was previously mentioned, everything is an object. If the parentheses are left off, Python will not throw an error, it will only show a reference to a method, which is an object:

>>> print('fred'.capitalize) <built-in method capitalize of str object at 0x7ff648617508>



Having first-class objects enables more advanced features like closures and decorators (these are discussed in my intermediate Python book).

Note

Do integers and floats have methods? Yes, again, everything in Python is and object and objects have methods. This is easy to verify by invoking dir on an integer (or a variable holding an integer):

>>> dir(4) ['__abs__', '__add__', '__and__', '__class__', ... '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'conjugate', 'denominator', 'imag', 'numerator', 'real']



Invoking a method on a number is somewhat tricky due to the use of the . to denote calling a method. Because . is common in floats, it would confuse Python if . were also used to call methods on numbers.

For example, the .conjugate method returns the complex conjugate of an integer. But if you try to invoke it on an integer, you will get an error:

>>> 5.conjugate() Traceback (most recent call last): ... 5.conjugate() ^ SyntaxError: invalid syntax



One solution to this is to wrap the number with parentheses:

>>> (5).conjugate() 5



Another option would be to assign a variable to 5 and invoke the method on the variable:

>>> five = 5 >>> five.conjugate() 5



However, in practice, it is fairly rare to call methods on numbers.





Common string methods


Here are a few string methods that are commonly used or found in the wild. Feel free to explore others using dir and help (or the online documentation).





endswith


If you have a variable holding a filename, you might want to check the extension. This is easy with .endswith:

>>> xl = 'Oct2000.xls' >>> xl.endswith('.xls') True >>> xl.endswith('.xlsx') False



Note

Notice that you had to pass in a parameter (or argument), 'xls', into the method. Methods have a signature, which is a funky way of saying that they need to be called with the correct number (and type) of parameters. For the .endswith method, it makes sense that if you want to know if a string ends with another string you have to tell Python which ending you want to check for. This is done by passing the end string to the method.



Tip

Again, it is usually easy to find out this sort of information via help. The documentation should tell you what parameters are required as well as any optional parameters. Here is the help for endswith:

>>> help(xl.endswith) Help on built-in function endswith: endswith(...) S.endswith(suffix[, start[, end]]) -> bool Return True if S ends with the specified suffix, False otherwise. With optional start, test S beginning at that position. With optional end, stop comparing S at that position. suffix can also be a tuple of strings to try.



Notice the line:

S.endswith(suffix[, start[, end]]) -> bool



The S represents the string (or instance) you are invoking the method on, in this case, the xl variable. .endswith is the method name. Between the parentheses, ( and ), are the parameters. suffix is a required parameter, the .endswith method will complain if you do not provide it:

>>> xl.endswith() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: endswith() takes at least 1 argument (0 given)



The parameters between the square brackets [ and ] are optional parameters. In this case, start and end allow you to only check a portion of the string. If you wanted to check if the characters starting at 0 and ending at 3 ends with Oct you could do the following:

>>> xl.endswith('Oct', 0, 3) True



Strings also have a .startswith method, so the correct way to check if a string starts with 'Oct' is:

>>> xl.startswith('Oct') True





find


The .find method allows you to find substrings inside other strings. It returns the index (offset starting at 0) of the matched substring. If no substring is found it returns -1:

>>> word = 'grateful' # 0 is g, 1 is r, 2 is a >>> word.find('ate') 2 >>> word.find('great') -1





format


format allows for easy creation of new strings by combining existing variables. The chapter on strings discussed this method:

>>> print('name: {}, age: {}'.\ ... format('Matt', 10)) name: Matt, age: 10



Note

In the above example, the print function is spread across two lines. By placing a \ following a . you indicate to Python that you want to continue on the next line. If you have opened a left parenthesis, (, you can also place the arguments on multiple lines without a \:

>>> print("word". ... find('ord')) 1 >>> print("word".find( ... 'ord')) 1



To help make the code more readable, indent the continued lines. Note that indenting with four spaces serves to indicate to anyone reading the code that the second line is a continuation of a previous statement:

>>> print("word".\ ... find('ord')) 1 >>> print("word".find( ... 'ord')) 1



Why spread code that could reside in a single line across multiple lines? Where this comes into play in most code is dealing with code standards that expect lines to be less than 80 characters in length. If a method takes multiple arguments, it may be hard to follow the 80 character limit. (Note that Python itself does not care about line length, but readers of your code might). It is not uncommon to see a separate line for each argument to a method:

>>> print('{} {} {} {} {}'.format( ... 'hello', ... 'to', ... 'you', ... 'and', ... 'you' ... )) hello to you and you





join


Oftentimes you have a list (lists are discussed later in the book) of items and need to insert something between them. The .join method creates a new string from a sequence by inserting a string between every member of the list:

>>> ', '.join(['1','2','3']) '1, 2, 3'



Tip

For most Python interpreters, using .join is faster than repeated concatenation using the + operator. The above idiom is common.





lower


The .lower method returns a copy of the string converted to lowercase. The is often useful for validating if the input matches a string. For example, some programs capitalize file extensions, while others do not. If you wanted to know if a file name had TXT or txt as an extension, you could do the following:

>>> fname = 'readme.txt' >>> fname.endswith('txt') or fname.endswith('TXT') True



A more Pythonic version would read:

>>> fname.lower().endswith('txt') True





startswith


The .startswith method is analogous to .endswith except that it checks that a string starts with another string:

>>> 'Book'.startswith('B') True >>> 'Book'.startswith('b') False





strip


The .strip method returns a new string that removes preceding and trailing whitespace (spaces, tabs, newlines). This may come in handy if you have to normalize data or parse input from a user (or the web):

>>> ' hello there '.strip() 'hello there'



Note that three spaces at the front of the string were removed as were the two at the end. But the two spaces between the words were left intact. If you are interested in removing only the leading whitespace or rightmost whitespace, the methods lstrip and rstrip respectively will perform those duties.





upper


The .upper method is analogous to .lower. It returns a copy of the string with all of the letters capitalized:

>>> 'yell'.upper() 'YELL'





Other methods


There are other string methods, but they are used less often. Feel free to explore them by reading the documentation and trying them out. The appendix provides a list of them.

Note

The STRINGMETHODS entry in the help section from the REPL contains documentation for all of the string methods as well as some examples.





Summary


This chapter talked about methods. Methods are always called by putting an object and a period before the method name. You also looked at some of the more common methods of strings. One thing to remember is that a string is immutable. If you want to change a string’s value, you need to create a new string.





Exercises


Create a string, school, with the name of your elementary school. Examine the methods that are available on that string. Use the help function to view their documentation.



Create a string, country, with the value 'usa'. Create a new string, correct_country, that has the value in uppercase, by using a string method.

Create a string, filename, that has the value 'hello.py'. Check and see if the filename ends with '.java'. Find the index location of 'py'. See if it starts with 'world'.

Open a REPL. Enter the help documentation and scan through the STRINGMETHODS entry.





Comments, Booleans, and None


This chapter will introduce comments, booleans, and None. Comments have the potential to make your code more readable. The boolean and None types are very common throughout Python code.





Comments


Comments are not a type per se because they are ignored by Python. Comments serve as reminders to the programmer. There are various takes on comments, their purpose, and their utility. There is a continuum from those who are against any and all comments, to those who comment almost every line of code, as well as those who are in between. If you are contributing to a project, try to be consistent with their commenting scheme. A basic rule of thumb is that a comment should explain the why rather than the how (code alone should be sufficient for the how).

To create a comment in Python, start a line with a #. Anything that follows the hash is ignored:

>>> # This line is ignored by Python



You can also comment at the end of a line:

>>> num = 3.14 # PI



Tip

A rogue use of comments is to temporarily disable code during editing. If your editor supports this, it is sometimes easier to comment out code rather than remove it completely. But the best practice is to remove commented-out code before sharing the code with others.



Other languages support multi-line comments, but Python does not. The only way to comment multiple lines is to start every line with #.

Tip

You may be tempted to comment out multiple lines of code by making those lines a triple-quoted string. This is ugly and confusing. Try not to do this.





Booleans


Booleans represent the values for true and false. You have already seen them in previous code examples, such as the result of .startswith:

>>> 'bar'.startswith('b') True



You can also assign those values to variables:

>>> a = True >>> b = False



Note

The actual name of the boolean class in Python is bool, not boolean:

>>> type(True) <class 'bool'>





It can be useful to convert other types to booleans. In Python, the bool class can do that. Converting from one type to another is called casting. However, this is usually unnecessary due to the implicit casting Python performs when conditionals are evaluated. The conditional statement will do this casting for you.

In Python parlance, it is common to hear of objects behaving as “truthy” or “falsey”—that means that non-boolean types can implicitly behave as though they were booleans. If you are unsure what the behavior might be, pass in the type to the bool class for an explicit conversion (or cast).

For strings, an empty string is “falsey”, while non-empty values coerce to True:

>>> bool('') False >>> bool('0') # The string containing 0 True



Since a non-empty string behaves as truthy, you can test whether the string has content. In the code below name has been set, but imagine that it came from user input:

>>> name = 'Paul' >>> if name: ... print("The name is {}".format(name)) ... else: ... print("Name is missing") The name is Paul



You don't have to test if the name has a length. So don't do this:

>>> if len(name) > 0: ... print("The name is {}".format(name))



Also, you don't need to do this:

>>> if bool(name): ... print("The name is {}".format(name))



because Python will evaluate the contents of the if statement, and coerce to a boolean for you. Because a string is True when it has content you only need:

>>> if name: ... print("The name is {}".format(name))



Note

The built-in types, int, float, str, and bool, are classes. Even though their capitalization (lowercase) makes it look as if they were functions, they are classes. Invoking help(str) will confirm this:

>>> help(str) Help on class str in module builtins: class str(object) | str(object='') -> str | str(bytes_or_buffer[, encoding[, errors]]) -> str |



This is one of those slight inconsistencies with Python. User-defined classes typically follow PEP8, which suggests camel cased naming of classes.



For numbers, zero coerces to False while other numbers have “truthy” behavior:

>>> bool(0) False >>> bool(4) True



While explicit casting via the bool function is available, it is usually overkill, because variables are implicitly coerced to booleans when used in conditional statements. For example, container types, such as lists and dictionaries, when empty, behave as “falsey”. On the flipside, when they are populated they act as “truthy”.

Tip

Be careful when parsing content that you want to turn into booleans. Strings that are non-empty evaluate to True. One example of a string that might bite you is the string 'False' which evaluates to True:

>>> bool('False') True





Here is a table of truthy and falsey values:

Truthy Falsey

True False

Most objects None

1 0

3.2 0.0

[1, 2] [] (empty list)

{'a': 1, 'b': 2} {} (empty dict)

'string' "" (empty string)

'False'

'0'

Tip

Do not test boolean values to check if they are equal to True. Do not explicitly cast expressions to boolean results. If you have a variable, done, containing a boolean, this is sufficient:

if done: # do something



While this is overkill:

if done == True: # do something



As is this:

if bool(done): # do something



Similarly, if you have a list and need to distinguish between an empty and non-empty list, this is sufficient:

members = [] if members: # do something if members # have values else: # member is empty



Likewise, this test is superfluous. It is not necessary to determine the truthiness of a list by its length:

if len(members) > 0: # do something if members # have values else: # member is empty





Note

If you wish to define the implicit truthiness for user-defined objects, the .__bool__ method specifies this behavior. It can return True, or False. If this magic method is not defined, the .__len__ method is checked for a non-zero value. If neither method is defined, an object defaults to True:

>>> class Nope: ... def __bool__(self): ... return False >>> n = Nope() >>> bool(n) False



If this is confusing, feel free to come back to this example after reading about classes.





None


None is an instance of NoneType. Other languages have similar constructs such as nil, NULL or undefined. Variables can be assigned to None to indicate that they are waiting to hold a real value. None coerces to False in a boolean context:

>>> bool(None) False



Note

A Python function defaults to returning None if no return statement is specified:

>>> def hello(): ... print("hi") >>> result = hello() hi >>> print(result) None





Note

None is a singleton (Python only has one copy of None in the interpreter). The id for this value will always be the same:

>>> a = None >>> id(a) 140575303591440 >>> b = None >>> id(b) 140575303591440



As any variable containing None is the same object as any other variable containing None. You typically use is to check for identity with these variables rather than using == to check for equality:

>>> a is b True >>> a is not b False



is is faster than == and connotes to the programmer that identity is being compared rather than the value.

You can put the is expression in an if statement:

>>> if a is None: ... print("A is not set!") A is not set!



Since None evaluates to False in a boolean context you could also do the following:

>>> if not a: ... print("A is not set!") A is not set!



But, you should be careful as other values also evaluate to False, such as 0, [], or '' (empty string). Checking against None is explicit.





Summary


In this chapter, you learned about comments in Python. Comments are started with a hash, and any content following the hash until the end of the line is ignored. There are no multi-line comments.

The chapter also discussed True, False, and boolean coercion. Most values are True in a boolean context (when used in an if statement). The False values are zero, None, and empty sequences.

Finally, the None object was mentioned. It is a singleton that is used to indicate that you have a variable that may be assigned a value in the future. It is also the result of a function that does not explicitly return a value.





Exercises


Create a variable, age, set to your age. Create another variable, old, that uses a condition to test whether you are older than 18. The value of old should be True or False.



Create a variable, name, set to your name. Create another variable, second_half, that tests whether the name would be classified in the second half of the alphabet? What do you need to compare it to?

Create a list, names, with the names of people in a class. Write code to print 'The class is empty!' or 'Class has enrollments.', based on whether there are values in names. (See the tip in this chapter for details).

Create a variable, car, set to None. Write code to print 'Taxi for you!', or 'You have a car!', based on whether or not car is set (None is not the name of a car).





Conditionals and Whitespace


In this chapter, you will learn more about making comparisons in Python. Most code needs to make decisions about which path to execute, so you will look at how this is done.

In addition to the boolean values, True and False, in Python, you can also use expressions to get boolean values. If you have two numbers, you might want to compare them to check if they are greater than or less than each other. The operators, > and <, do this respectively:

>>> 5 > 9 False



Here is a table of comparison operations to create boolean values:

Operator Meaning

> Greater than

< Less than

>= Greater than or equal to

<= Less than or equal to

== Equal to

!= Not equal to

is Identical object

is not Not identical object

These operations work on most types. If you create a custom class that defines the appropriate magic