Python
Python
by TELUGU GYAAN
Dictionaries store connections between pieces of
List comprehensions information. Each item in a dictionary is a key-value pair.
squares = [x**2 for x in range(1, 11)]
A simple dictionary
Slicing a list alien = {'color': 'green', 'points': 5}
finishers = ['sam', 'bob', 'ada', 'bea']
Accessing a value
first_two = finishers[:2]
print("The alien's color is " + alien['color'])
Variables are used to store values. A string is a series of Copying a list
characters, surrounded by single or double quotes. Adding a new key-value pair
copy_of_bikes = bikes[:]
Hello world alien['x_position'] = 0
print("Hello world!") Looping through all key-value pairs
Hello world with a variable Tuples are similar to lists, but the items in a tuple can't be fav_numbers = {'eric': 17, 'ever': 4}
modified. for name, number in fav_numbers.items():
msg = "Hello world!"
print(name + ' loves ' + str(number))
print(msg) Making a tuple
Concatenation (combining strings) dimensions = (1920, 1080) Looping through all keys
fav_numbers = {'eric': 17, 'ever': 4}
first_name = 'albert'
for name in fav_numbers.keys():
last_name = 'einstein'
print(name + ' loves a number')
full_name = first_name + ' ' + last_name If statements are used to test for particular conditions and
print(full_name) respond appropriately. Looping through all the values
Conditional tests fav_numbers = {'eric': 17, 'ever': 4}
for number in fav_numbers.values():
equals x == 42 not equal
A list stores a series of items in a particular order. You print(str(number) + ' is a favorite')
access items using an index, or within a loop. x != 42 greater than x >
42
Make a list or equal to x >= 42
less than x < 42 Your programs can prompt the user for input. All input is
bikes = ['trek', 'redline', 'giant'] or equal to x <= 42 stored as a string.
Get the first item in a list Conditional test with lists Prompting for a value
first_bike = bikes[0] 'trek' in bikes name = input("What's your name? ")
Get the last item in a list 'surly' not in bikes print("Hello, " + name + "!")
last_bike = bikes[-1] Assigning boolean values Prompting for numerical input
Looping through a list game_active = True age = input("How old are you? ")
can_edit = False
for bike in bikes: age = int(age)
print(bike) A simple if test
pi = input("What's the value of pi? ")
Adding items to a list if age >= 18:
pi = float(pi)
print("You can vote!")
bikes = []
bikes.append('trek') If-elif-else statements
bikes.append('redline') if age < 4:
bikes.append('giant') ticket_price = 0
Making numerical lists elif age < 18:
ticket_price = 10
squares = [] else:
for x in range(1, 11): ticket_price = 15
squares.append(x**2)
A while loop repeats a block of code as long as a certain A class defines the behavior of an object and the kind of Your programs can read from files and write to files. Files
condition is true. information an object can store. The information in a class are opened in read mode ('r') by default, but can also be
is stored in attributes, and functions that belong to a class opened in write mode ('w') and append mode ('a').
A simple while loop are called methods. A child class inherits the attributes and
methods from its parent class. Reading a file and storing its lines
current_value = 1
while current_value <= 5: filename = 'siddhartha.txt'
Creating a dog class
print(current_value) with open(filename) as file_object:
current_value += 1 class Dog(): lines = file_object.readlines()
"""Represent a dog."""
Letting the user choose when to quit for line in lines:
def __init__(self, name):
msg = '' print(line)
while msg != 'quit': """Initialize dog object."""
self.name = name Writing to a file
msg = input("What's your message? ")
print(msg) filename = 'journal.txt'
def sit(self):
with open(filename, 'w') as file_object:
"""Simulate sitting.""" file_object.write("I love programming.")
print(self.name + " is sitting.")
Functions are named blocks of code, designed to do one Appending to a file
specific job. Information passed to a function is called an my_dog = Dog('Peso')
argument, and information received by a function is called a filename = 'journal.txt'
parameter. print(my_dog.name + " is a great dog!") with open(filename, 'a') as file_object:
file_object.write("\nI love making games.")
my_dog.sit()
A simple function
def greet_user(): Inheritance
"""Display a simple greeting.""" class SARDog(Dog): Exceptions help you respond appropriately to errors that
print("Hello!") """Represent a search dog.""" are likely to occur. You place code that might cause an
greet_user() error in the try block. Code that should run in response to
def __init__(self, name): an error goes in the except block. Code that should run only if
the try block was successful goes in the else block.
Passing an argument """Initialize the sardog."""
super().__init__(name)
def greet_user(username): Catching an exception
"""Display a personalized greeting.""" def search(self): prompt = "How many tickets do you need? "
print("Hello, " + username + "!") """Simulate searching.""" num_tickets = input(prompt)
print(self.name + " is searching.")
greet_user('jesse') try:
my_dog = SARDog('Willie') num_tickets = int(num_tickets)
Default values for parameters
except ValueError:
def make_pizza(topping='bacon'): print(my_dog.name + " is a search dog.") print("Please try again.")
"""Make a single-topping pizza.""" my_dog.sit() else:
print("Have a " + topping + " pizza!") my_dog.search() print("Your tickets are printing.")
make_pizza()
make_pizza('pepperoni')
If you had infinite programming skills, what would you Simple is better than complex
Returning a value build?
If you have a choice between a simple and a complex
def add_numbers(x, y): As you're learning to program, it's helpful to think solution, and both work, use the simple solution. Your
"""Add two numbers and return the sum.""" about the real-world projects you'd like to create. It's code will be easier to maintain, and it will be easier
return x + y a good habit to keep an "ideas" notebook that you for you and others to build on that code later on.
sum = add_numbers(3, 5) can refer to whenever you want to start a new project.
print(sum) If you haven't done so already, take a few minutes
and describe three projects you'd like to create.
You can add elements to the end of a list, or you can insert The sort() method changes the order of a list permanently.
them wherever you like in a list. The sorted() function returns a copy of the list, leaving the
original list unchanged. You can sort the items in a list in
Adding an element to the end of the list alphabetical order, or reverse alphabetical order. You can
also reverse the original order of the list. Keep in mind that
users.append('amy')
lowercase and uppercase letters may affect the sort order.
Starting with an empty list
Sorting a list permanently
users = []
A list stores a series of items in a particular order. users.append('val') users.sort()
Lists allow you to store sets of information in one users.append('bob')
Sorting a list permanently in reverse
place, whether you have just a few items or millions users.append('mia')
alphabetical order
of items. Lists are one of Python's most powerful
Inserting elements at a particular position
features readily accessible to new programmers, and users.sort(reverse=True)
they tie together many important concepts in users.insert(0, 'joe')
Sorting a list temporarily
program m ing. users.insert(3, 'bea')
print(sorted(users))
print(sorted(users, reverse=True))
Use square brackets to define a list, and use commas to You can remove elements by their position in a list, or by Reversing the order of a list
separate individual items in the list. Use plural names for the value of the item. If you remove an item by its value,
users.reverse()
lists, to make your code easier to read. Python removes only the first item that has that value.
Use curly braces to define a dictionary. Use colons to Looping through all the keys
connect keys and values, and use commas to separate You can modify the value associated with any key in a # Show everyone who's taken the survey.
individual key-value pairs. dictionary. To do so give the name of the dictionary and for name in fav_languages.keys():
enclose the key in square brackets, then provide the new print(name)
Making a dictionary value for that key.
alien_0 = {'color': 'green', 'points': 5} Looping through all the values
Modifying values in a dictionary
# Show all the languages that have been chosen.
alien_0 = {'color': 'green', 'points': 5} for language in fav_languages.values():
print(alien_0) print(language)
To access the value associated with an individual key give
the name of the dictionary and then place the key in a set of # Change the alien's color and point value. Looping through all the keys in order
square brackets. If the key you're asking for is not in the
alien_0['color'] = 'yellow'
dictionary, an error will occur. # Show each person's favorite language,
You can also use the get() method, which returns None alien_0['points'] = 10 # in order by the person's name.
instead of an error if the key doesn't exist. You can also print(alien_0) for name in sorted(fav_languages.keys()):
specify a default value to use if the key is not in the print(name + ": " + language)
dictionary.
Getting the value associated with a key You can remove any key-value pair you want from a
dictionary. To do so use the del keyword and the dictionary
You can find the number of key-value pairs in a dictionary.
alien_0 = {'color': 'green', 'points': 5} name, followed by the key in square brackets. This will
delete the key and its associated value. Finding a dictionary's length
print(alien_0['color'])
Deleting a key-value pair num_responses = len(fav_languages)
print(alien_0['points'])
alien_0 = {'color': 'green', 'points': 5}
Getting the value with get() print(alien_0)
alien_0 = {'color': 'green'}
del alien_0['points']
alien_color = alien_0.get('color') print(alien_0)
alien_points = alien_0.get('points', 0)
print(alien_color)
print(alien_points) Try running some of these examples on pythontutor.com.
It's sometimes useful to store a set of dictionaries in a list; Storing a list inside a dictionary alows you to associate Standard Python dictionaries don't keep track of the order
this is called nesting. more than one value with each key. in which keys and values are added; they only preserve the
association between each key and its value. If you want to
Storing dictionaries in a list Storing lists in a dictionary preserve the order in which keys and values are added, use
an OrderedDict.
# Start with an empty list. # Store multiple languages for each person.
users = [] fav_languages = { Preserving the order of keys and values
'jen': ['python', 'ruby'],
# Make a new user, and add them to the list. from collections import OrderedDict
'sarah': ['c'],
new_user = { 'edward': ['ruby', 'go'],
'last': 'fermi', 'phil': ['python', 'haskell'], # Store each person's languages, keeping
'first': 'enrico', } # track of who respoded first.
'username': 'efermi', fav_languages = OrderedDict()
} # Show all responses for each person.
users.append(new_user) for name, langs in fav_languages.items(): fav_languages['jen'] = ['python', 'ruby']
print(name + ": ") fav_languages['sarah'] = ['c']
# Make another new user, and add them as well. for lang in langs: fav_languages['edward'] = ['ruby', 'go']
new_user = { print("- " + lang) fav_languages['phil'] = ['python', 'haskell']
'last': 'curie',
'first': 'marie', # Display the results, in the same order they
'username': 'mcurie', # were entered.
} You can store a dictionary inside another dictionary. In this for name, langs in fav_languages.items():
users.append(new_user) case each value associated with a key is itself a dictionary. print(name + ":")
for lang in langs:
# Show all information about each user. Storing dictionaries in a dictionary print("- " + lang)
for user_dict in users: users = {
for k, v in user_dict.items(): 'aeinstein': {
print(k + ": " + v) 'first': 'albert',
print("\n") 'last': 'einstein', You can use a loop to generate a large number of
'location': 'princeton', dictionaries efficiently, if all the dictionaries start out with
You can also define a list of dictionaries }, similar data.
directly, without using append(): 'mcurie': { A million aliens
'first': 'marie',
# Define a list of users, where each user aliens = []
'last': 'curie',
# is represented by a dictionary.
'location': 'paris',
users = [ # Make a million green aliens, worth 5 points
},
{ # each. Have them all start in one row.
}
'last': 'fermi', for alien_num in range(1000000):
'first': 'enrico', new_alien = {}
for username, user_dict in users.items():
'username': 'efermi', new_alien['color'] = 'green'
print("\nUsername: " + username)
}, new_alien['points'] = 5
full_name = user_dict['first'] + " "
{ new_alien['x'] = 20 * alien_num
full_name += user_dict['last']
'last': 'curie', new_alien['y'] = 0
location = user_dict['location']
'first': 'marie', aliens.append(new_alien)
'username': 'mcurie',
print("\tFull name: " + full_name.title())
}, # Prove the list contains a million aliens.
print("\tLocation: " + location.title())
] num_aliens = len(aliens)
# Show all information about each user.
print("Number of aliens created:")
for user_dict in users:
for k, v in user_dict.items(): Nesting is extremely useful in certain situations. However, print(num_aliens)
print(k + ": " + v) be aware of making your code overly complex. If you're
nesting items much deeper than what you see here there
print("\n")
are probably simpler ways of managing your data, such as
using classes.
Testing numerical values is similar to testing string values. Several kinds of if statements exist. Your choice of which to
use depends on the number of conditions you need to test.
Testing equality and inequality You can have as many elif blocks as you need, and the
>>> age = 18 else block is always optional.
>>> age == 18
Simple if statement
True
>>> age != 18 age = 19
False
if age >= 18:
Comparison operators print("You're old enough to vote!")
>>> age = 19
If-else statements
>>> age < 21
True age = 17
>>> age <= 21
True if age >= 18:
If statements allow you to examine the current state >>> age > 21 print("You're old enough to vote!")
of a program and respond appropriately to that state. False else:
>>> age >= 21 print("You can't vote yet.")
You can write a simple if statement that checks one
False
condition, or you can create a complex series of if The if-elif-else chain
statements that idenitfy the exact conditions you're
age = 12
looking for.
You can check multiple conditions at the same time. The
While loops run as long as certain conditions remain if age < 4:
and operator returns True if all the conditions listed are
true. You can use while loops to let your programs True. The or operator returns True if any condition is True. price = 0
elif age < 18:
run as long as your users want them to.
Using and to check multiple conditions price = 5
else:
>>> age_0 = 22 price = 10
>>> age_1 = 18
A conditional test is an expression that can be evaluated as >>> age_0 >= 21 and age_1 >= 21 print("Your cost is $" + str(price) + ".")
True or False. Python uses the values True and False to False
decide whether the code in an if statement should be >>> age_1 = 23
executed. >>> age_0 >= 21 and age_1 >= 21
True You can easily test whether a certain value is in a list. You
Checking for equality can also test whether a list is empty before trying to loop
A single equal sign assigns a value to a variable. A double equal Using or to check multiple conditions
sign (==) checks whether two values are equal. through the list.
>>> age_0 = 22
>>> car = 'bmw' Testing if a value is in a list
>>> age_1 = 18
>>> car == 'bmw' >>> players = ['al', 'bea', 'cyn', 'dale']
>>> age_0 >= 21 or age_1 >= 21
True >>> 'al' in players
True
>>> car = 'audi' True
>>> age_0 = 18
>>> car == 'bmw' >>> 'eric' in players
>>> age_0 >= 21 or age_1 >= 21
False False
False
Ignoring case when making a comparison
>>> car = 'Audi'
>>> car.lower() == 'audi' A boolean value is either True or False. Variables with
True boolean values are often used to keep track of certain
conditions within a program.
Checking for inequality
>>> topping = 'mushrooms' Simple boolean values
>>> topping != 'anchovies' game_active = True
True can_edit = False
Testing if a value is not in a list Letting the user choose when to quit Using continue in a loop
banned_users = ['ann', 'chad', 'dee'] prompt = "\nTell me something, and I'll " banned_users = ['eve', 'fred', 'gary', 'helen']
user = 'erin' prompt += "repeat it back to you."
prompt += "\nEnter 'quit' to end the program. " prompt = "\nAdd a player to your team."
if user not in banned_users: prompt += "\nEnter 'quit' when you're done. "
print("You can play!") message = "" players = []
while message != 'quit':
Checking if a list is empty message = input(prompt) while True:
player = input(prompt)
players = [] if player == 'quit':
if message != 'quit':
break
if players: print(message)
elif player in banned_users:
for player in players: print(player + " is banned!")
print("Player: " + player.title())
Using a flag
continue
else: prompt = "\nTell me something, and I'll " else:
print("We have no players yet!") prompt += "repeat it back to you." players.append(player)
prompt += "\nEnter 'quit' to end the program. "
print("\nYour team:")
active = True for player in players:
You can allow your users to enter input using the input() while active: print(player)
statement. In Python 3, all input is stored as a string. message = input(prompt)
Simple input if message == 'quit':
name = input("What's your name? ") active = False
print("Hello, " + name + ".") Every while loop needs a way to stop running so it won't
else: continue to run forever. If there's no way for the condition to
print(message) become False, the loop will never stop running.
Accepting numerical input
age = input("How old are you? ")
Using break to exit a loop An infinite loop
age = int(age) prompt = "\nWhat cities have you visited?" while True:
prompt += "\nEnter 'quit' when you're done. " name = input("\nWho are you? ")
if age >= 18:
while True: print("Nice to meet you, " + name + "!")
print("\nYou can vote!")
else: city = input(prompt)
print("\nYou can't vote yet.") if city == 'quit':
The remove() method removes a specific value from a list,
Accepting input in Python 2.7 break
but it only removes the first instance of the value you
Use raw_input() in Python 2.7. This function interprets all input as a else:
string, just as input() does in Python 3. print("I've been to " + city + "!") provide. You can use a while loop to remove all instances
of a particular value.
name = raw_input("What's your name? ")
print("Hello, " + name + ".") Removing all cats from a list of pets
pets = ['dog', 'cat', 'dog', 'fish', 'cat',
Sublime Text doesn't run programs that prompt the user for
input. You can use Sublime Text to write programs that 'rabbit', 'cat']
prompt for input, but you'll need to run these programs from print(pets)
A while loop repeats a block of code as long as a condition
is True. a terminal. while 'cat' in pets:
Counting to 5 pets.remove('cat')
print(pets)
current_number = 1
You can use the break statement and the continue
while current_number <= 5: statement with any of Python's loops. For example you can
use break to quit a for loop that's working through a list or a
print(current_number) dictionary. You can use continue to skip over certain items
current_number += 1 when looping through a list or dictionary as well.
The two main kinds of arguments are positional and A function can return a value or a set of values. When a
keyword arguments. When you use positional arguments function returns a value, the calling line must provide a
Python matches the first argument in the function call with variable in which to store the return value. A function stops
the first parameter in the function definition, and so forth. running when it reaches a return statement.
With keyword arguments, you specify which parameter
each argument should be assigned to in the function call. Returning a single value
When you use keyword arguments, the order of the
arguments doesn't matter. def get_full_name(first, last):
"""Return a neatly formatted full name."""
full_name = first + ' ' + last
Using positional arguments
return full_name.title()
def describe_pet(animal, name):
"""Display information about a pet.""" musician = get_full_name('jimi', 'hendrix')
Functions are named blocks of code designed to do
print("\nI have a " + animal + ".") print(musician)
one specific job. Functions allow you to write code
print("Its name is " + name + ".")
once that can then be run whenever you need to Returning a dictionary
accomplish the same task. Functions can take in the describe_pet('hamster', 'harry') def build_person(first, last):
information they need, and return the information they
describe_pet('dog', 'willie') """Return a dictionary of information
generate. Using functions effectively makes your
about a person.
programs easier to write, read, test, and fix. Using keyword arguments
"""
def describe_pet(animal, name): person = {'first': first, 'last': last}
"""Display information about a pet.""" return person
The first line of a function is its definition, marked by the print("\nI have a " + animal + ".")
keyword def. The name of the function is followed by a set print("Its name is " + name + ".") musician = build_person('jimi', 'hendrix')
of parentheses and a colon. A docstring, in triple quotes, print(musician)
describes what the function does. The body of a function is describe_pet(animal='hamster', name='harry')
indented one level. describe_pet(name='willie', animal='dog') Returning a dictionary with optional values
To call a function, give the name of the function followed def build_person(first, last, age=None):
by a set of parentheses. """Return a dictionary of information
about a person.
Making a function You can provide a default value for a parameter. When
"""
function calls omit this argument the default value will be
def greet_user(): used. Parameters with default values must be listed after person = {'first': first, 'last': last}
"""Display a simple greeting.""" parameters without default values in the function's definition if age:
print("Hello!") so positional arguments can still work correctly. person['age'] = age
return person
greet_user() Using a default value
musician = build_person('jimi', 'hendrix', 27)
def describe_pet(name, animal='dog'): print(musician)
"""Display information about a pet."""
print("\nI have a " + animal + ".") musician = build_person('janis', 'joplin')
Information that's passed to a function is called an
print("Its name is " + name + ".") print(musician)
argument; information that's received by a function is called
a parameter. Arguments are included in parentheses after
the function's name, and parameters are listed in describe_pet('harry', 'hamster')
parentheses in the function's definition. describe_pet('willie')
Try running some of these examples on pythontutor.com.
Passing a single argument Using None to make an argument optional
def greet_user(username): def describe_pet(animal, name=None):
"""Display a simple greeting.""" """Display information about a pet."""
print("Hello, " + username + "!") print("\nI have a " + animal + ".")
if name:
greet_user('jesse') print("Its name is " + name + ".")
greet_user('diana')
greet_user('brandon') describe_pet('hamster', 'harry')
describe_pet('snake')
You can pass a list as an argument to a function, and the Sometimes you won't know how many arguments a You can store your functions in a separate file called a
function can work with the values in the list. Any changes function will need to accept. Python allows you to collect an module, and then import the functions you need into the file
the function makes to the list will affect the original list. You arbitrary number of arguments into one parameter using containing your main program. This allows for cleaner
can prevent a function from modifying a list by passing a the * operator. A parameter that accepts an arbitrary program files. (Make sure your module is stored in the
copy of the list as an argument. number of arguments must come last in the function same directory as your main program.)
definition.
Passing a list as an argument The ** operator allows a parameter to collect an arbitrary Storing a function in a module
number of keyword arguments. File: pizza.py
def greet_users(names):
Collecting an arbitrary number of arguments def make_pizza(size, *toppings):
"""Print a simple greeting to everyone."""
for name in names: def make_pizza(size, *toppings): """Make a pizza."""
msg = "Hello, " + name + "!" """Make a pizza.""" print("\nMaking a " + size + " pizza.")
print(msg) print("\nMaking a " + size + " pizza.") print("Toppings:")
print("Toppings:") for topping in toppings:
usernames = ['hannah', 'ty', 'margot'] for topping in toppings: print("- " + topping)
greet_users(usernames) print("- " + topping)
Importing an entire module
Allowing a function to modify a list File: making_pizzas.py
# Make three pizzas with different toppings. Every function in the module is available in the program file.
The following example sends a list of models to a function for
printing. The original list is emptied, and the second list is filled. make_pizza('small', 'pepperoni')
make_pizza('large', 'bacon bits', 'pineapple') import pizza
def print_models(unprinted, printed): make_pizza('medium', 'mushrooms', 'peppers',
"""3d print a set of models.""" 'onions', 'extra cheese') pizza.make_pizza('medium', 'pepperoni')
while unprinted: pizza.make_pizza('small', 'bacon', 'pineapple')
current_model = unprinted.pop() Collecting an arbitrary number of keyword arguments
print("Printing " + current_model) Importing a specific function
def build_profile(first, last, **user_info): Only the imported functions are available in the program file.
printed.append(current_model) """Build a user's profile dictionary."""
# Build a dict with the required keys. from pizza import make_pizza
# Store some unprinted designs, profile = {'first': first, 'last': last}
# and print each of them. make_pizza('medium', 'pepperoni')
unprinted = ['phone case', 'pendant', 'ring'] # Add any other keys and values. make_pizza('small', 'bacon', 'pineapple')
printed = []
print_models(unprinted, printed)
for key, value in user_info.items(): Giving a module an alias
profile[key] = value
import pizza as p
print("\nUnprinted:", unprinted) return profile
print("Printed:", printed) p.make_pizza('medium', 'pepperoni')
# Create two users with different kinds p.make_pizza('small', 'bacon', 'pineapple')
Preventing a function from modifying a list
The following example is the same as the previous one, except the # of information.
Giving a function an alias
original list is unchanged after calling print_models(). user_0 = build_profile('albert', 'einstein',
location='princeton') from pizza import make_pizza as mp
def print_models(unprinted, printed): user_1 = build_profile('marie', 'curie',
"""3d print a set of models.""" location='paris', field='chemistry') mp('medium', 'pepperoni')
while unprinted:
print(user_0) mp('small', 'bacon', 'pineapple')
current_model = unprinted.pop()
print("Printing " + current_model) print(user_1) Importing all functions from a module
printed.append(current_model) Don't do this, but recognize it when you see it in others' code. It
can result in naming conflicts, which can cause errors.
# Store some unprinted designs,
from pizza import *
# and print each of them. As you can see there are many ways to write and call a
original = ['phone case', 'pendant', 'ring'] function. When you're starting out, aim for something that make_pizza('medium', 'pepperoni')
printed = [] simply works. As you gain experience you'll develop an
make_pizza('small', 'bacon', 'pineapple')
print_models(original[:], printed) understanding of the more subtle advantages of different
structures such as positional and keyword arguments, and
print("\nOriginal:", original) the various approaches to importing functions. For now if
print("Printed:", printed) your functions do what you need them to, you're doing well.
If the class you're writing is a specialized version of another
Creating an object from a class class, you can use inheritance. When one class inherits
my_car = Car('audi', 'a4', 2016) from another, it automatically takes on all the attributes and
methods of the parent class. The child class is free to
Accessing attribute values introduce new attributes and methods, and override
attributes and methods of the parent class.
print(my_car.make) To inherit from another class include the name of the
print(my_car.model) parent class in parentheses when defining the new class.
print(my_car.year)
Classes are the foundation of object-oriented The __init__() method for a child class
Calling methods
programming. Classes represent real-world things class ElectricCar(Car):
you want to model in your programs: for example my_car.fill_tank()
"""A simple model of an electric car."""
dogs, cars, and robots. You use a class to make my_car.drive()
objects, which are specific instances of dogs, cars,
Creating multiple objects def __init__(self, make, model, year):
and robots. A class defines the general behavior that """Initialize an electric car."""
a whole category of objects can have, and the my_car = Car('audi', 'a4', 2016)
super().__init__(make, model, year)
information that can be associated with those objects. my_old_car = Car('subaru', 'outback', 2013)
Classes can inherit from each other – you can my_truck = Car('toyota', 'tacoma', 2010)
# Attributes specific to electric cars.
write a class that extends the functionality of an # Battery capacity in kWh.
existing class. This allows you to code efficiently for a self.battery_size = 70
wide variety of situations. You can modify an attribute's value directly, or you can # Charge level in %.
write methods that manage updating values more carefully. self.charge_level = 0
def __init__(self, make, model, year): Importing an entire module # Make 500 gas cars and 250 electric cars.
for _ in range(500):
"""Initialize an electric car.""" import car
car = Car('ford', 'focus', 2016)
super().__init__(make, model, year) gas_fleet.append(car)
my_beetle = car.Car(
for _ in range(250):
# Attribute specific to electric cars. 'volkswagen', 'beetle', 2016)
ecar = ElectricCar('nissan', 'leaf', 2016)
self.battery = Battery() my_beetle.fill_tank()
electric_fleet.append(ecar)
my_beetle.drive()
def charge(self):
# Fill the gas cars, and charge electric cars.
"""Fully charge the vehicle.""" my_tesla = car.ElectricCar(
self.battery.charge_level = 100 'tesla', 'model s', 2016) for car in gas_fleet:
print("The vehicle is fully charged.") my_tesla.charge() car.fill_tank()
my_tesla.drive() for ecar in electric_fleet:
ecar.charge()
Using the instance
Importing all classes from a module
my_ecar = ElectricCar('tesla', 'model x', 2016) (Don’t do this, but recognize it when you see it.) print("Gas cars:", len(gas_fleet))
from car import * print("Electric cars:", len(electric_fleet))
my_ecar.charge()
print(my_ecar.battery.get_range())
my_beetle = Car('volkswagen', 'beetle', 2016)
my_ecar.drive()
Storing the lines in a list Opening a file using an absolute path
filename = 'siddhartha.txt' f_path = "/home/ehmatthes/books/alice.txt"
import unittest E
from full_names import get_full_name ================================================
ERROR: test_first_last (__main__.NamesTestCase)
class NamesTestCase(unittest.TestCase): Test names like Janis Joplin.
"""Tests for names.py.""" ------------------------------------------------
Traceback (most recent call last):
def test_first_last(self): File "test_full_names.py", line 10,
When you write a function or a class, you can also """Test names like Janis Joplin.""" in test_first_last
write tests for that code. Testing proves that your full_name = get_full_name('janis', 'joplin')
code works as it's supposed to in the situations it's 'joplin') TypeError: get_full_name() missing 1 required
designed to handle, and also when people use your self.assertEqual(full_name, positional argument: 'last'
programs in unexpected ways. Writing tests gives 'Janis Joplin')
you confidence that your code will work correctly as ------------------------------------------------
more people begin to use your programs. You can unittest.main() Ran 1 test in 0.001s
also add new features to your programs and know
that you haven't broken existing behavior. Running the test FAILED (errors=1)
Python reports on each unit test in the test case. The dot reports a
single passing test. Python informs us that it ran 1 test in less than Fixing the code
A unit test verifies that one specific aspect of your 0.001 seconds, and the OK lets us know that all unit tests in the When a test fails, the code needs to be modified until the test
code works as it's supposed to. A test case is a test case passed. passes again. (Don’t make the mistake of rewriting your tests to fit
collection of unit tests which verify your code's your new code.) Here we can make the middle name optional.
.
behavior in a wide variety of situations. --------------------------------------- def get_full_name(first, last, middle=''):
Ran 1 test in 0.000s """Return a full name."""
if middle:
OK
full_name = "{0} {1} {2}".format(first,
Python's unittest module provides tools for testing your middle, last)
code. To try it out, we’ll create a function that returns a full else:
name. We’ll use the function in a regular program, and then full_name = "{0} {1}".format(first,
build a test case for the function. Failing tests are important; they tell you that a change in the
last)
code has affected existing behavior. When a test fails, you
return full_name.title()
A function to test need to modify the code so the existing behavior still works.
Save this as full_names.py
Modifying the function Running the test
def get_full_name(first, last): Now the test should pass again, which means our original
We’ll modify get_full_name() so it handles middle names, but
functionality is still intact.
"""Return a full name.""" we’ll do it in a way that breaks existing behavior.
full_name = "{0} {1}".format(first, last) .
return full_name.title() def get_full_name(first, middle, last):
---------------------------------------
"""Return a full name."""
Ran 1 test in 0.000s
Using the function full_name = "{0} {1} {2}".format(first,
Save this as names.py middle, last)
OK
return full_name.title()
from full_names import get_full_name
Using the function
janis = get_full_name('janis', 'joplin')
from full_names import get_full_name
print(janis)
bob = get_full_name('bob', 'dylan') john = get_full_name('john', 'lee', 'hooker')
print(bob) print(john)
david = get_full_name('david', 'lee', 'roth')
print(david)
You can add as many unit tests to a test case as you need. Testing a class is similar to testing a function, since you’ll When testing a class, you usually have to make an instance
To write a new test, add a new method to your test case mostly be testing your methods. of the class. The setUp() method is run before every test.
class. Any instances you make in setUp() are available in every
A class to test test you write.
Testing middle names Save as accountant.py
We’ve shown that get_full_name() works for first and last Using setUp() to support multiple tests
names. Let’s test that it works for middle names as well. class Accountant():
The instance self.acccan be used in each new test.
"""Manage a bank account."""
import unittest import unittest
from full_names import get_full_name def __init__(self, balance=0): from accountant import Accountant
self.balance = balance
class NamesTestCase(unittest.TestCase): def deposit(self, amount): class TestAccountant(unittest.TestCase):
"""Tests for names.py.""" """Tests for the class Accountant."""
self.balance += amount
def test_first_last(self): def withdraw(self, amount): def setUp(self):
"""Test names like Janis Joplin.""" self.balance -= amount self.acc = Accountant()
full_name = get_full_name('janis', def test_initial_balance(self):
'joplin')
Building a testcase # Default balance should be 0.
self.assertEqual(full_name,
For the first test, we’ll make sure we can start out with different self.assertEqual(self.acc.balance, 0)
'Janis Joplin')
initial balances. Save this as test_accountant.py.
# Test non-default balance.
def test_middle(self): import unittest
"""Test names like David Lee Roth.""" acc = Accountant(100)
from accountant import Accountant
full_name = get_full_name('david', self.assertEqual(acc.balance, 100)
'roth', 'lee') class TestAccountant(unittest.TestCase): def test_deposit(self):
self.assertEqual(full_name, """Tests for the class Accountant."""
'David Lee Roth') # Test single deposit.
def test_initial_balance(self): self.acc.deposit(100)
unittest.main() # Default balance should be 0. self.assertEqual(self.acc.balance, 100)
acc = Accountant() # Test multiple deposits.
Running the tests self.assertEqual(acc.balance, 0)
The two dots represent two passing tests. self.acc.deposit(100)
self.acc.deposit(100)
.. # Test non-default balance. self.assertEqual(self.acc.balance, 300)
--------------------------------------- acc = Accountant(100)
def test_withdrawal(self):
Ran 2 tests in 0.000s self.assertEqual(acc.balance, 100)
# Test single withdrawal.
OK unittest.main() self.acc.deposit(1000)
self.acc.withdraw(100)
Running the test self.assertEqual(self.acc.balance, 900)
.
Python provides a number of assert methods you can use unittest.main()
to test your code. ---------------------------------------
Ran 1 test in 0.000s
Verify that a==b, or a != b
OK Running the tests
assertEqual(a, b)
assertNotEqual(a, b) ...
---------------------------------------
Verify that x is True, or x is False In general you shouldn’t modify a test once it’s written. Ran 3 tests in 0.001s
assertTrue(x) When a test fails it usually means new code you’ve written OK
assertFalse(x) has broken existing functionality, and you need to modify
the new code until all existing tests pass.
Verify an item is in a list, or not in a list If your original requirements have changed, it may be
appropriate to modify some tests. This usually happens in
assertIn(item, list) the early stages of a project when desired behavior is still
assertNotIn(item, list) being sorted out.
The following code sets up an empty game window, and
starts an event loop and a loop that continually refreshes Useful rect attributes
the screen. Once you have a rect object, there are a number of attributes that
are useful when positioning objects and detecting relative positions
of objects. (You can find more attributes in the Pygame
An empty game window documentation.)
import sys
# Individual x and y values:
import pygame as pg
screen_rect.left, screen_rect.right
def run_game(): screen_rect.top, screen_rect.bottom
Pygame is a framework for making games using screen_rect.centerx, screen_rect.centery
Python. Making games is fun, and it’s a great way to # Initialize and set up screen.
screen_rect.width, screen_rect.height
expand your programming skills and knowledge. pg.init()
screen = pg.display.set_mode((1200, 800))
Pygame takes care of many of the lower-level tasks # Tuples
pg.display.set_caption("Alien Invasion")
in building games, which lets you focus on the screen_rect.center
aspects of your game that make it interesting. # Start main loop. screen_rect.size
while True: Creating a rect object
# Start event loop. You can create a rect object from scratch. For example a small rect
for event in pg.event.get(): object that’s filled in can represent a bullet in a game. The Rect()
Pygame runs on all systems, but setup is slightly different
if event.type == pg.QUIT: class takes the coordinates of the upper left corner, and the width
on each OS. The instructions here assume you’re using and height of the rect. The draw.rect() function takes a screen
Python 3, and provide a minimal installation of Pygame. If sys.exit()
object, a color, and a rect. This function fills the given rect with the
these instructions don’t work for your system, see the more # Refresh screen. given color.
detailed notes at http://ehmatthes.github.io/pcc/. pg.display.flip()
bullet_rect = pg.Rect(100, 100, 3, 15)
Pygame on Linux run_game() color = (100, 100, 100)
pg.draw.rect(screen, color, bullet_rect)
$ sudo apt-get install python3-dev mercurial
libsdl-image1.2-dev libsdl2-dev Setting a custom window size
libsdl-ttf2.0-dev The display.set_mode() function accepts a tuple that defines the
$ pip install --user screen size. Many objects in a game are images that are moved around
hg+http://bitbucket.org/pygame/pygame
screen_dim = (1200, 800) the screen. It’s easiest to use bitmap (.bmp) image files, but
you can also configure your system to work with jpg, png,
Pygame on OS X screen = pg.display.set_mode(screen_dim)
and gif files as well.
This assumes you’ve used Homebrew to install Python 3.
Setting a custom background color
$ brew install hg sdl sdl_image sdl_ttf Colors are defined as a tuple of red, green, and blue values. Each Loading an image
$ pip install --user value ranges from 0-255. ship = pg.image.load('images/ship.bmp')
hg+http://bitbucket.org/pygame/pygame bg_color = (230, 230, 230)
Getting the rect object from an image
Pygame on Windows screen.fill(bg_color)
Find an installer at ship_rect = ship.get_rect()
https://bitbucket.org/pygame/pygame/downloads/ or
http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame that matches Positioning an image
your version of Python. Run the installer file if it’s a .exe or .msi file. Many objects in a game can be treated as simple With rects, it’s easy to position an image wherever you want on the
If it’s a .whl file, use pip to install Pygame: rectangles, rather than their actual shape. This simplifies screen, or in relation to another object. The following code
positions a ship object at the bottom center of the screen.
code without noticeably affecting game play. Pygame has a
> python –m pip install --user
rect object that makes it easy to work with game objects. ship_rect.midbottom = screen_rect.midbottom
pygame-1.9.2a0-cp35-none-win32.whl
x_values = [0, 1, 2, 3, 4, 5]
squares = [0, 1, 4, 9, 16, 25]
plt.plot(x_values, squares)
plt.show()
You can make as many plots as you want on one figure. You can include as many individual graphs in one figure as
When you make multiple plots, you can emphasize Datetime formatting arguments you want. This is useful, for example, when comparing
relationships in the data. For example you can fill the space The strftime() function generates a formatted string from a related datasets.
datetime object, and the strptime() function genereates a
between two sets of data.
datetime object from a string. The following codes let you work with
dates exactly as you need to.
Sharing an x-axis
Plotting two sets of data The following code plots a set of squares and a set of cubes on
Here we use plt.scatter() twice to plot square numbers and two separate graphs that share a common x-axis.
%A Weekday name, such as Monday
cubes on the same figure. The plt.subplots() function returns a figure object and a tuple
%B Month name, such as January of axes. Each set of axes corresponds to a separate plot in the
import matplotlib.pyplot as plt %m Month, as a number (01 to 12) figure. The first two arguments control the number of rows and
%d Day of the month, as a number (01 to 31) columns generated in the figure.
x_values = list(range(11)) %Y Four-digit year, such as 2016
%y Two-digit year, such as 16 import matplotlib.pyplot as plt
squares = [x**2 for x in x_values]
cubes = [x**3 for x in x_values] %H Hour, in 24-hour format (00 to 23)
x_vals = list(range(11))
%I Hour, in 12-hour format (01 to 12)
%p AM or PM squares = [x**2 for x in x_vals]
plt.scatter(x_values, squares, c='blue',
%M Minutes (00 to 59) cubes = [x**3 for x in x_vals]
edgecolor='none', s=20)
%S Seconds (00 to 61)
plt.scatter(x_values, cubes, c='red', fig, axarr = plt.subplots(2, 1, sharex=True)
edgecolor='none', s=20) Converting a string to a datetime object
plt.axis([0, 11, 0, 1100]) axarr[0].scatter(x_vals, squares)
new_years = dt.strptime('1/1/2017', '%m/%d/%Y')
plt.show() axarr[0].set_title('Squares')
Converting a datetime object to a string axarr[1].scatter(x_vals, cubes, c='red')
Filling the space between data sets ny_string = dt.strftime(new_years, '%B %d, %Y') axarr[1].set_title('Cubes')
The fill_between() method fills the space between two data
sets. It takes a series of x-values and two series of y-values. It also print(ny_string) plt.show()
takes a facecolor to use for the fill, and an optional alpha
argument that controls the color’s transparency. Plotting high temperatures
The following code creates a list of dates and a corresponding list
plt.fill_between(x_values, cubes, squares, of high temperatures. It then plots the high temperatures, with
Sharing a y-axis
To share a y-axis, we use the sharey=True argument.
facecolor='blue', alpha=0.25) the date labels displayed in a specific format.
from datetime import datetime as dt import matplotlib.pyplot as plt
outcomes = [1, 2, 3, 4, 5, 6]
To make a plot with Pygal, you specify the kind of plot and frequencies = [18, 16, 18, 17, 18, 13]
then add the data.
chart = pygal.Bar()
Making a line graph chart.force_uri_protocol = 'http'
To view the output, open the file squares.svg in a browser. chart.x_labels = outcomes
import pygal chart.add('D6', frequencies)
chart.render_to_file('rolling_dice.svg')
x_values = [0, 1, 2, 3, 4, 5]
squares = [0, 1, 4, 9, 16, 25] Making a bar graph from a dictionary
Since each bar needs a label and a value, a dictionary is a great The documentation for Pygal is available at
way to store the data for a bar graph. The keys are used as the http://www.pygal.org/.
chart = pygal.Line() labels along the x-axis, and the values are used to determine the
chart.force_uri_protocol = 'http' height of each bar.
chart.add('x^2', squares)
chart.render_to_file('squares.svg') import pygal If you’re viewing svg output in a browser, Pygal needs to
render the output file in a specific way. The
Adding labels and a title results = { force_uri_protocol attribute for chart objects needs to
--snip--
1:18, 2:16, 3:18, be set to 'http'.
chart = pygal.Line() 4:17, 5:18, 6:13,
chart.force_uri_protocol = 'http' }
chart.title = "Squares"
chart.x_labels = x_values chart = pygal.Bar()
chart.x_title = "Value" chart.force_uri_protocol = 'http'
chart.y_title = "Square of Value" chart.x_labels = results.keys()
chart.add('x^2', squares) chart.add('D6', results.values())
chart.render_to_file('squares.svg') chart.render_to_file('rolling_dice.svg')
Pygal lets you customize many elements of a plot. There Pygal can generate world maps, and you can add any data
are some excellent default themes, and many options for Configuration settings you want to these maps. Data is indicated by coloring, by
styling individual plot elements. Some settings are controlled by a Config object. labels, and by tooltips that show data when users hover
my_config = pygal.Config() over each country on the map.
Using built-in styles my_config.show_y_guides = False
To use built-in styles, import the style and make an instance of the
my_config.width = 1000
Installing the world map module
style class. Then pass the style object with the style argument The world map module is not included by default in Pygal 2.0. It
when you make the chart object. my_config.dots_size = 5 can be installed with pip:
import pygal chart = pygal.Line(config=my_config) $ pip install --user pygal_maps_world
from pygal.style import LightGreenStyle --snip--
Making a world map
x_values = list(range(11)) The following code makes a simple world map showing the
Styling series countries of North America.
squares = [x**2 for x in x_values] You can give each series on a chart different style settings.
cubes = [x**3 for x in x_values] from pygal.maps.world import World
chart.add('Squares', squares, dots_size=2)
chart_style = LightGreenStyle() chart.add('Cubes', cubes, dots_size=3)
wm = World()
chart = pygal.Line(style=chart_style) Styling individual data points wm.force_uri_protocol = 'http'
chart.force_uri_protocol = 'http' You can style individual data points as well. To do so, write a wm.title = 'North America'
chart.title = "Squares and Cubes" dictionary for each data point you want to customize. A 'value' wm.add('North America', ['ca', 'mx', 'us'])
chart.x_labels = x_values key is required, and other properies are optional.
wm.render_to_file('north_america.svg')
import pygal
chart.add('Squares', squares)
chart.add('Cubes', cubes) repos = [ Showing all the country codes
In order to make maps, you need to know Pygal’s country codes.
chart.render_to_file('squares_cubes.svg') { The following example will print an alphabetical list of each country
'value': 20506, and its code.
Parametric built-in styles
Some built-in styles accept a custom color, then generate a theme 'color': '#3333CC',
from pygal.maps.world import COUNTRIES
based on that color. 'xlink': 'http://djangoproject.com/',
}, for code in sorted(COUNTRIES.keys()):
from pygal.style import LightenStyle 20054,
12607, print(code, COUNTRIES[code])
--snip--
chart_style = LightenStyle('#336688')
11827, Plotting numerical data on a world map
] To plot numerical data on a map, pass a dictionaryadd()
chart = pygal.Line(style=chart_style) to instead of a list.
chart = pygal.Bar()
--snip--
chart.force_uri_protocol = 'http' from pygal.maps.world import World
Customizing individual style properties chart.x_labels = [
Style objects have a number of properties you can set individually. 'django', 'requests', 'scikit-learn', populations = {
chart_style = LightenStyle('#336688') 'tornado', 'ca': 34126000,
chart_style.plot_background = '#CCCCCC' ] 'us': 309349000,
chart_style.major_label_font_size = 20 chart.y_title = 'Stars' 'mx': 113423000,
chart_style.label_font_size = 16 chart.add('Python Repos', repos) }
--snip-- chart.render_to_file('python_repos.svg')
wm = World()
Custom style class wm.force_uri_protocol = 'http'
You can start with a bare style class, and then set only the
wm.title = 'Population of North America'
properties you care about.
wm.add('North America', populations)
chart_style = Style() wm.render_to_file('na_populations.svg')
chart_style.colors = [
'#CCCCCC', '#AAAAAA', '#888888']
chart_style.plot_background = '#EEEEEE'
chart = pygal.Line(style=chart_style)
--snip--
The data in a Django project is structured as a set of Users interact with a project through web pages, and a
models. project’s home page can start out as a simple page with no
data. A page usually needs a URL, a view, and a template.
Defining a model
To define the models for your app, modify the file models.py that Mapping a project’s URLs
was created in your app’s folder. The __str__() method tells The project’s main urls.py file tells Django where to find the urls.py
Django how to represent data objects based on this model. files associated with each app in the project.
from django.db import models from django.conf.urls import include, url
from django.contrib import admin
Django is a web framework which helps you build class Topic(models.Model):
interactive websites using Python. With Django you """A topic the user is learning about.""" urlpatterns = [
define the kind of data your site needs to work with, text = models.CharField(max_length=200) url(r'^admin/', include(admin.site.urls)),
and you define the ways your users can work with date_added = models.DateTimeField( url(r'', include('learning_logs.urls',
that data. auto_now_add=True) namespace='learning_logs')),
]
def __str__(self):
return self.text Mapping an app’s URLs
It’s usualy best to install Django to a virtual environment, An app’s urls.py file tells Django which view to use for each URL in
where your project can be isolated from your other Python Activating a model the app. You’ll need to make this file yourself, and save it in the
projects. Most commands assume you’re working in an To use a model the app must be added to the tuple app’s folder.
active virtual environment. INSTALLED_APPS, which is stored in the project’s settings.py file.
from django.conf.urls import url
Create a virtual environment INSTALLED_APPS = (
--snip-- from . import views
$ python –m venv ll_env 'django.contrib.staticfiles',
urlpatterns = [
Activate the environment (Linux and OS X)
# My apps url(r'^$', views.index, name='index'),
$ source ll_env/bin/activate 'learning_logs', ]
)
Activate the environment (Windows) Writing a simple view
Migrating the database A view takes information from a request and sends data to the
> ll_env\Scripts\activate browser, often through a template. View functions are stored in an
The database needs to be modified to store the kind of data that
the model represents. app’s views.py file. This simple view function doesn’t pull in any
Install Django to the active environment data, but it uses the template index.html to render the home page.
(ll_env)$ pip install Django $ python manage.py makemigrations learning_logs
$ python manage.py migrate from django.shortcuts import render