Skip to content
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
1139 lines (886 sloc) 34.5 KB
layout title permalink categories hierarchy
Python 101
name path

Hey there!

We’re going to crash course through the programming language Python to introduce you to the very basics of coding. If you have no or minimal coding background, then this is the place for you! Otherwise, feel free to move on and explore the rest of StartHacking.

Table of Contents

  1. Basics
  2. Variables
  3. Types
  4. Sequences
  1. Dictionaries
  2. Conditionals
  1. Looping
  1. Functions
  2. Classes
  3. Conclusion


In programming there are 3 types of commands: Executive, Conditional, and Iterative.


Executive means "do something". The classic way of thinking about a basic computer program is to think about a recipe. If you have a list of executive commands as your program to make a PB&J sandwich, your program would look like:

01 Take the bread.
02 Spread the jam.
03 Spread the butter.

Since all of these are direct commands, we know that they are all executive commands. In the context of robotics, an executive command can be "drive forward at some speed".


Conditional statements are of the form IF (something) THEN (do something) ELSE (do something else). This allows the computer to make decisions, often referred to as branching, based on the current state of the program.


Iterative means DO WHILE or FOR (this long) DO SOMETHING. The difference between a conditional and an iterative is that a conditional statement "happens" or is evaluated once when (something) happens. But, an iterative can do some action repeatedly WHILE (something) is true or FOR a certain number of times.


Almost every computer program needs to use variables, a placeholder that can take on various values, in order to be useful. For example, if I want to write a Fahrenheit to Celsius converter, I need to be able to store the temperature in Fahrenheit in a variable that people can edit; otherwise, I would only be able to convert a single temperature. Every variable used is given a name, such as a, b, lengthOfRobot, etc. They represent numbers, letters or words, and even true or false (known as boolean values).

To create and assign values to variables in Python, we use the name = value syntax. For example:

a = 3
b = "hello world"
lengthOfRobot = 3.1415
winningTheMatch = True
theSkyIsGreen = False


Variables do not have units; they are just numbers. There are different kinds of variables (integers, floats, doubles, characters, strings, booleans), known as variable types. The definitions of these are as follows:

  • integer, or int is a whole number without a decimal (e.g. 1,2, 5, 11, 100745).
  • float or double. These are not the same thing, but basically they are detailed numbers, that can include decimals (3.14, 7.1342, 2234.31).
  • character or char is just one letter such as "a" or "b" or "y".
  • string is a set of characters, making up words, sentences, etc such as "hello world" or "this is fun" or "Try again".
  • boolean is either True or False; we use these to store the true value of certain statements.

Sometimes, we'll need to convert from one type to another, in a process called casting. For example, to get only the integer portion of 8.33, we would use cast our number, 8.33, into an integer, using the following code:

restaurant_bill = 8.33
dollars_to_give = int(restaurant_bill) # convert 8.33 into an integer



We’re going to get into more detail about strings. You can create strings in Python in different ways. For example:

my_string  = 'Hello!'
my_other_string = "The quick brown fox jumped over the lazy dog."
very_long_string = '''Sometimes, you are going to have a giant
block of text that has multiple lines. In this case,
make sure to use three consecutive single or double
pi = 3.14
pi_string = str(pi)



The quick brown fox jumped over the lazy dog.
Sometimes, you are going to have a giant
block of text that has multiple lines. In this case,
make sure to use three consecutive single or double

You might be wondering what pi and pi_string are. Pi is a float, but in order to treat it like a string and print it out, we have to transform it into a string. You can cast numbers into strings quite easily but you can’t turn a string into a number.

Strings are also immutable, which means that you can’t change the variable’s content after you assign it. If you want to change your string, you’ll have to create a new string variable or directly reassign the string variable.

You can add two strings together using the +’operator, much like math. This is known as concatenation, which means the action of linking things together. For example:

a = "Hello "
b = "world!"
c = a + b


Hello world!

You can also slice strings to obtain sections or even individual letters from the string. It can be done in this way:

my_string = "dank memes"



Python reads this as [start:finish] where the start is the first character we want and finish is the first character we don't want. Python, similar to other programming languages, is zero-indexed, which means that the position of the first element is position 0. A little confusing? Here’s adiagram to help:

index 0 1 2 3 4 5 6 7 8 9
string d a n k m e m e s

You can also use negative values when slicing in order to access the end of the string.

my_string = "dank memes"



Here are some other ways to use slicing.

my_string = "dank memes"


dank memes


Next, we’re going to be checking out another data type: lists (also known as arrays in other programming languages). Lists are actually quite similar to strings, so what you’ve learned above will also apply here. Instead of being a collection of characters, lists are a collection of pretty much any other kind of object that exists in Python, such as integers and booleans. However, lists are mutable, which means that you will be able change the data without recreating the list.

You can create empty lists in Python as follows:

my_list = []
my_list = list()

You can create filled lists as follows:

my_list = [3, 2, 1]
colors = ["red", "blue", "green"]
random = ["pie", 3.14, "tau", 5.28]

You can even create a list of lists!

list_of_lists = [my_list, colors]


[[3, 2, 1], ['red', 'blue', 'green']]

You can combine lists as well, using concatenation.

combined_lists = my_list + colors


[3, 2, 1, 'red', 'blue', 'green']

And, you can also slice lists, just like strings.

my_list = [1, 2, 3, 4, 5]


[2, 3]

If you would like to reassign certain objects in the list, you can do so by calling its index and reassigning. It’s pretty simple!

my_list = [1, 2, 3, 4, 5]
my_list[0] = 0


[0, 2, 3, 4, 5]


Lists are incredibly useful, but sometimes you'll find that you want to retrieve an item in a list (known as the value, as will be explained below) not by its index in the list, but rather by a name (known more formally as a key). Dictionaries are able to do just that. For example, perhaps you want to count the number of times every letter of alphabet appears in a string. To do this, we will create a dictionary that maps every letter that appears in the string to its number of appearances.

First, some basic syntax for dictionaries. Instead of using square braces/brackets to define a list, we use curly braces.

my_dictionary = {}    # create an empty dictionary.

To have things in the dictionary when we create it, we use the "key":"value" (often referred together as a key/value pair) syntax:

my_second_dict = {"a": 7,     # note the use of the common to separate key
                  "b": 20}

To add a key/value pair to the dictionary, do the following.

Note that key and value can be of any hashable type (look up "hashable" here).

my_second_dict[key] = value # adds a new key/value pair to the dictionary.

To change or update the value associated with key key to updated_value, use the same syntax as above:

my_second_dict[key] = updated_value # updates the value associated with key

Finally, to remove a key/value pair from the dictionary, use the del keyword.

del my_second_dict[key]  # remove key/updated_value from the dictionary

Okay, now we can get back to our character appearance counter. We will loop over every character in our string, updating our dictionary as we go along.

string = "hello there, today we will be counting the number of times each character appears in this annoyingly long string of text"

character_counts = {}
for char in string:
  if char in character_counts.keys(): # if we've seen the character at least once before, we can just increment
    character_counts[char] += 1
  else: # if we haven't seen the character before, we need to initialize a value for it in the dictionary first
    character_counts[char] = 1

for key, value in character_counts.items():   # the way to loop over the items in a dictionary
  print(key, ":", value)


h : 6
e : 12
l : 6
o : 7
  : 20
t : 10
r : 6
, : 1
d : 1
a : 7
y : 3
w : 2
i : 7
b : 2
c : 4
u : 2
n : 9
g : 4
m : 2
f : 2
s : 4
p : 2
x : 1

Other sequences

There are other sequences in Python, such as tuples and sets. Feel free to explore them on your own! You’ll find them both similar and different to what we have discussed here -- which is what makes coding versatile. Their unique qualities allows each type of sequence to be utilized in various ways. Here are some links to get you started:


If statements: if / elif / else

While programming, you will want to check if something is true or not. Let’s say that you’re in the kitchen. You might have a train of thought like this:

Am I hungry?
If yes: make a sandwich.
Otherwise: leave the kitchen.

The code for conditionals is also pretty straightforward. Let’s look at some examples to get you used to if statements!

if 100 > 10:


if 100 < 10:


a = 100
b = 10
if a < b:
elif a > b:



If the if/elif statement is satisfied (i.e. it is true), then it will run whatever is indented below it. Indentation is essential in Python. Any indented code will only run if the code that it is under is true. You can think of code as a giant file cabinet, where each line of code is a folder, and indented lines are files inside the folder. You can only access the "indented" files if the folder it is in allows you to.

You’ve seen if statements and you’ve seen elif statements. What exactly are elif statements? You can think of elif as short for "else if". The program only checks these statements if whatever above them is false. They must be used after an if statement, but you can also have a long line of elif statements if that is what you need. Else statements are optional, but it is good practice to use them as defaults. Whatever is indented under an else statement will only run only if every other if and elif statement above it renders as false.

Boolean Operators

You are going to want to do a lot more than just using < and > in if statements. This is where Boolean operations come in.

Operator Meaning
or at least one statement has to be true in order for the total to be True
and both statements must be true in order for the total to be True
not flips the statement so that whatever is False is True, and vice versa

Let’s take a look at Boolean operations in action!

a = 1
b = 7

if a > 5 or b > 5:



This prints true because while a is not greater than 5, b is greater than 5. Only one of the statements has to be true when or is used.

if a > 5 and b > 5:



This prints false because a > 5 is false. Both have to be true for the statement to be true!

x = True
y = False

if x and not y:



Why does it print true? Let’s take a look at it. The x evaluates as True, and y evaluates as not False, which is True! Both are True, therefore the if statement evaluates as True.

You can mix and match all the Boolean conditionals to fit your needs while programming!


for loops

For loops are useful when you have blocks of code that you’d like to repeat a certain number of times. Let’s say you’re back in the kitchen, making sandwiches - but this time you’re packing several for a lunch with 5 friends. You’re going over the same motions (known as iterating) for a fixed number of repeats (each repeat is called an iteration). What would this look like in Python?

for x in range(1,6):
  print("Packing sandwich #" + str(x))


Packing sandwich #1
Packing sandwich #2
Packing sandwich #3
Packing sandwich #4
Packing sandwich #5

There’s a couple things to unpack here. On the first line, we begin our for loop. We’re looping over every x in the range from 1 to 5. Why 5, you might ask, since it looks like we’re going from 1 to 6? This is because of the parameters that the range function takes: range([start], stop[, step]). Whenever you use range, you need to give it a stop value, and range will generate numbers up to, but not including, that value. You can optionally pass it any start value, and that is inclusive. Otherwise, range will start with 0. step specifies the difference between each number in the sequence, so you could use a step of 2 to have range generate just even numbers, for example.

On the second line, we have the actual body of our for loop. This is the code that the loop will repeat for each value of x. In this simple example, it’s just a print statement. But note the indent: this is what tells Python to repeat this particular block. This is also a nice reminder of casting (converting from one type to another) and string concatenation!

We don’t just have to use range in for loops - we can iterate over strings and lists, for example. Here’s an example where we print each letter in the word "sandwich" on a different line:

word = "sandwich"
for letter in word:



Our for loop considers each character in "sandwich" (contained in the variable word), and prints it. Here’s another example, but this time with a list:

friends = ["Alice", "Bob", "Charlie", "Dave", "Eve"]
for friend in friends:
  print("Hi, " + friend + "! Have a sandwich.")


Hi, Alice! Have a sandwich.
Hi, Bob! Have a sandwich.
Hi, Charlie! Have a sandwich.
Hi, Dave! Have a sandwich.
Hi, Eve! Have a sandwich.

This loop considers each element of the list of friends, and offers them a sandwich.

These examples so far have been pretty basic, but we can make our for loops much more complicated. Let’s add conditionals! Say you have a list of possible sandwich fillings, but you want to print out just the ones that have bacon. How would you go about doing that?

fillings = [["ham","cheese"], ["chicken","avocado","bacon"], ["egg","mayo"],["bacon","lettuce", "tomato"], ["cheese","turkey"]]
for x in fillings:
  if "bacon" in x:


['chicken', 'avocado', 'bacon']
['bacon', 'lettuce', 'tomato']

Note that here, we’re iterating over a list of lists. This just means that each time the for loop runs its code block, it’s considering another list. The block just checks if "bacon" is in the list of ingredients for that particular filling, and prints the ingredients if it is.

Now let’s look at a different kind of loop, called a while loop.

while loops

While loops are also used for repeating blocks of code, but not for a fixed number of repetitions. The block will be run until some condition is met. Let’s consider a basic while loop:

i = 1
while i < 5:
  i += 1



Let’s break this down line by line. On the first line, we’ve created a counter variable i and set it to 1. The second line is the beginning of our loop: we’re going to keep running it until the condition i < 5 is met. The next two indented lines are the block that will repeat. The first indented line is just a print statement, but the second one is more interesting: we’re incrementing the counter i by 1. i += 1 is just a more compact way of writing i = i+1, and it makes sure that we don’t endlessly get stuck in the loop: if we never increased i, the condition i < 5 would always be true and we’d have an infinite loop which would never end. This is not something you usually want in your code. What about the condition? What if we changed it to i <= 5? We’d print the numbers from 1 to 5 this time, instead of 1 to 4.

There are a bunch of numerical examples we could go over, but while loops get more interesting when we include user input. Let’s go over the code for a simple number guessing game:

# code to get a random number -- search online for the "random" module to learn more
import random
to_be_guessed = random.randint(1, 100) # gets a random number from 1 to 100, inclusive

# start guessing game
guess = 0  # initialize guess variable
while guess != to_be_guessed: # run as long as the guess is incorrect
  guess = int(input("New number: ")) # get a guess from the user
  if guess > 0: # guess is valid only if it is positive
    if guess > to_be_guessed: # let the user know if their guess is above/below
      print("Number too large")
    elif guess < to_be_guessed:
      print("Number too small")
    print("Sorry that you're giving up!")

if guess == to_be_guessed:  # we need this b/c its possible that they gave up
  print("Congratulations. You made it!")

Let’s assume that to_be_guessed has been set to 84. The first line initializes a guess variable, and from there on it’s the while loop. The loop runs as long as the guess is incorrect. Inside the loop, the first thing we do is get a guess from the user - the input function takes a string using the prompt in quotes (New number:). The first if/else block checks to see if the guess is valid. We’ll talk later about other, more comprehensive ways this can be done. Inside the first if block we have another if/else block to tell the user how they did if they guessed over or under — note there’s no else block to handle if they guessed correctly. What happens if they do guess correctly? We end up passing through all the ifs without printing anything but once we return to the condition check for the while loop, we find that the condition is now False. We break out of the loop and print the congratulations statement.

This is a more complicated example of while loops, bringing conditionals into the mix too, but if you’re comfortable with this you’re good to go!


Say you’re trying to do some form of input verification. You want your user to input a specific string, and you want them to keep trying until they do. This is one way you might do it:

n = input("Please enter 'hello':")
while n != 'hello':
  n = input("Please enter 'hello':")

This is pretty wordy, though. We have the same input request typed out twice, and it’s generally good form to try to minimize repetition. One way we can fix this is with a break statement:

while True:
  n = input("Please enter 'hello':")
  if n == 'hello':

A break statement does just what it sounds like it does - it breaks out of the loop. In the second example, we’ve contained everything in the while loop. Notice that we start out with a condition that will never evaluate to false: this seems problematic, but we won’t end up with an infinite loop because we have the option of breaking out of it in the body of the loop. We collect user input, compare it against our reference string, and break out of the loop if they’ve typed what we want, and move on. This is a really good way to handle while loops.


You’ll notice that we’ve been using the word "function" to describe some of the things we’re using - like input, range, and more. So what is a function? A function is a block of organized and reusable code that performs a single task. It’s good form to minimize repetitive code, so if you find that you’re having to do the same thing a lot, that’s probably a sign that you need to write a function for it. Python has some functions built in — like input and range — but you can write your own!

Here’s a really simple function so you understand the syntax:

def print_string(string):




On the first line, we use def to tell Python that we’re defining a function. print_string is our function’s name, and in the parentheses are the parameters that it’ll use to generate some output. This is a really basic function, so it just prints out whatever parameter we pass it. But we could have any number of parameters of any type, and do all sorts of interesting things with them in the body of our function, which — surprise, surprise — is indented under the function definition. Under the function definition is a function call, where we use our function with the parameter set to sandwich.

Here’s another example where instead of just printing, we do something more interesting: we return a value.

def add_numbers(a,b):
  return a + b

print(add_numbers(3, 5))



Notice first that we’re using multiple parameters in this new function. The next big difference is the use of return. return outputs a value that we can use in more expressions. For example, let’s try:

print("Hello, " + print_string("Bob"))

This wouldn’t work, because technically print_string doesn’t return anything. It just prints a value and returns nothing, or more technically, None — an object Python uses to represent nothingness. You don’t always need to return something, but if you want to use your function output, then you do need return. For example, we could do this:

print(add_numbers(1,3) + 5)

Since add_numbers returns its output, we can incorporate it into other expressions without ending up with errors.

Another important distinction to be aware of when writing your own functions is the difference between global and local variables:

start = 1
def add_list(numlist):
  total = 0
  for i in numlist:
    total += i
  return total



Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'total' is not defined

The second print statement gives an error because total is a local variable, not a global variable. total only exists inside the function definition and is not accessible outside it. On the other hand, start exists outside the function and is a global variable, accessible anywhere.

The functions you write can take all sorts of arguments and do all sorts of things, so no matter what kind of project you’re working on, you’ll probably need to write at least a couple of functions. It might take a little bit of getting used to, but once you start, you’ll never know how you managed without them!


You might have heard of something called Object-Oriented Programming. It’s just a fancy name for a very simple concept. Take a look at everything around you. The keyboard you’re using. The book sitting next to your desk. The table you’re working on. They’re all objects — things that have properties, e.g. the keyboard’s format, the book’s title, the table’s height, and actions associated with them.

Object Properties Actions
Book Title
Cover image
Flip page
Open book
Close book
Table Height
Change height (if it's an Updesk)
Keyboard Keyboard format
Caps Lock enabled?
Number pad attached?
Toggle Caps Lock

That’s all an object really is in programming — something with properties and actions. Why might this be useful? Well, let’s consider that we’re programming a gradebook application for a school system. What are some objects that a gradebook consists of? It would probably include the students, aggregated together into courses, of which a teacher may teach several.

What might some of the properties and actions of each of these objects be?

Object Properties Actions
Student First name
Middle initial
Last name
Enrolled courses
Enroll in course
Drop course
Print transcript
Course List of enrolled students
List of assignments
Enroll student
Drop student
Add grade
Remove grade
Edit grade
Print grade report
Teacher First name
Middle initial
Last name
Position (e.g. Department Head)
List of courses teaching
Change department
Change position
Add course taught
Remove course taught

Having written down the properties and actions we associate with each object, we can begin writings classes for each object. What’s a class? It’s simply a blueprint for what properties and actions an object should have. In other words, I have a class that defines a generic object, like Student. When I want specific students, such as George or Michael, I create an instance of Student, with each student’s name property set appropriately. The code might help clarify things a bit.

Let's begin with the implementation of the Student class:

class Student:
  def __init__(self, first, mi, last):
    self.first_name = first # initialize class variables
    self.middle_initial = mi
    self.last_name = last
    self.enrolled_courses = []

  def enroll(self, course): # course should be an instance of Course (aka should be a Course object)
    self.enrolled_courses.append(course) # add the Course to the student's list of enrolled courses
    course.enrolled_students.append(self) # add the student to the Course's list of students; see below

  def drop(self, course): # course should be an instance of Course
    self.enrolled_courses.remove(course) # remove the Course from the student's list of enrolled courses
    course.enrolled_students.remove(self) # remove the student from the Course's list of students

  def get_transcript(self):
    print(self.first_name + " " + self.middle_initial + ". " + self.last_name + ":") # Print out their full name
    for course in self.enrolled_courses: # For every course they're enrolled in
      print("\t" + course.course_name + ": " + str(course.get_overall_grade_for(self))) # Print their overall grade

A bit of syntax for classes: we begin a class definition with class ClassName:. Since our class is for a student, we'll name it Student, so the class definition would begin: class Student:. We then need to provide a constructor for our class. A constructor is a function that is called when we want to create, or construct, an instance of our class. This particular constructor function takes in a first name, middle initial, and last name as parameters (we'll explain the self parameter in the following detour). So, to construct a Student object, we would do the following: matt = Student("Matthew", "R", "Feng"). Inside the constructor function, we can declare instance variables (the ones that start with self.) that belong to the object. In this example, every Student object will have its own first_name, middle_initial, last_name, and enrolled_courses variable. In addition to the constructor, we can also define other functions we want each of our objects to have. Here, we defined methods (another name for functions) for a student to enroll and drop courses, as well as get their transcript - an overview of their grades.

A Short Detour

You might be wondering what the self variable means. It's known as an implicit parameter, which means that when calling the function, you specify the object name before the function name. Here's a concrete example to clear things up.

class Table:
  def __init__(self):
    self.height = 10

  def change_height(self, amount):
    self.height += amount

t = Table() # create an instance of the Table class, aka create a Table object
t.change_height(10) # call change_height
Table.change_height(t, 10) # does the same thing as the previous line

Say that we have an object named t, of class type Table. Suppose that Table has a function change_height. We can thus call change_height two different ways - by implicitly passing the parameter, or explicitly passing the parameter. If we call change_height like t.change_height(10), then t, our object, is named before the function name, change_height. Thus, change_height was called with an implicit parameter. Alternatively, we could have written Table.change_height(t, 10), where we pass in the object explicitly.

Back to the Gradebook Application

Now that we have the Student class written, it's time to start writing the Course class, which will represent the courses that students are taking. Each Course should have a course name, a list of enrolled students, and a list of assignments, so we'll create those as instance variables. Additionally, we need ways to add and remove assignments, as well as set and get grades for the students, so we'll create those as functions.

class Course:
  def __init__(self, name):
    self.course_name = name
    self.enrolled_students = []
    # assignments is a dictionary with key=assignment name, value=dictionary of students
    #   with key=Student object, value=assignment grade
    self.assignments = {}

  def add_assignment(self, assignment):
    self.assignments[assignment] = {}

  def remove_assignment(self, assignment):
    del self.assignments[assignment]

  def set_grade(self, assignment, student, grade):
    self.assignments[assignment][student] = grade # assign a grade to a Student

  def get_overall_grade_for(self, student):
    sum_scores = 0  # need an accumulator (see Glossary) to compute average
    num_graded = 0  # need to keep track of total number of grades for average
    for assignment, grades in self.assignments.items(): # iterate over all items in self.assignments
      if student in grades.keys():  # look to see if the student has a grade
        sum_scores += grades[student]  # add that grade to the accumulator
        num_graded += 1 # increment number of graded assignments (the denominator)

    if num_graded == 0: # can't have an average with 0 elements
      return "N/A"

    return sum_scores / float(num_graded) # return the average

So how do we use our classes now? Well, we create some instances of the classes and call the functions! We do that in the main section of our program.

john = Student("John", "A", "Smith") # create a Student named John
katie = Student("Katie", "M", "Zhu") # create a Student named Katie

biology = Course("Biology") # create a course called Biology
calculus = Course("Calculus") # create a course called Calculus
physics = Course("Physics") # create a course called Physics

john.enroll(biology) # enroll John in Bio and Calculus

katie.enroll(biology) # enroll Katie in Bio, Calc, and Physics

biology.add_assignment("Bio exam #1") # Add the assignments for each of the three classes
biology.add_assignment("Bio exam #2")
physics.add_assignment("Physics homework #1")
calculus.add_assignment("Calc homework #1")
calculus.add_assignment("Calc quiz #1")

biology.set_grade("Bio exam #1", john, 90) # give John and Katie grades for Bio
biology.set_grade("Bio exam #1", katie, 95)

physics.set_grade("Physics homework #1", katie, 86) # give Katie a grade for Physics

calculus.set_grade("Calc homework #1", john, 100) # give John and Katie grades for Calculus
calculus.set_grade("Calc homework #1", katie, 98)
calculus.set_grade("Calc quiz #1", john, 78)
calculus.set_grade("Calc quiz #1", katie, 84)

john.get_transcript() # print out their overall grades


John A. Smith:
  Biology: 90.0
  Calculus: 89.0
Katie M. Zhu:
  Biology: 95.0
  Calculus: 91.0
  Physics: 86.0


This is by no means a very extensive tutorial but we hope that you feel more confident about pursuing coding projects now! (Re)

Below are some other handy resources for you to learn more about Python:

If you have suggestions for content to add or revise, or have questions, or just want to talk, feel free to shoot us an email at starthacking (at) and we'll try our best to get back to you as soon as possible!

You can’t perform that action at this time.