Introduction to Python#

In this lessons, we’ll learn about the basics of Python programmming.

Variables#

Variables are containers for holding data and they’re defined by a name and value.

c7c45362f7434136a810e78c99373d55

[1]:
# Integer variable
x = 5
print (x)
print (type(x))

5
<class 'int'>

We can change the value of a variable by simply assigning a new value to it.

[2]:
# String variable
x = "hello"
print (x)
print (type(x))
hello
<class 'str'>

There are many different types of variables: integers, floats, strings, boolean etc.

[3]:
# int variable
x = 5
print (x, type(x))
5 <class 'int'>
[4]:
# float variable
x = 5.0
print (x, type(x))
5.0 <class 'float'>
[5]:
# text variable
x = "5"
print (x, type(x))
5 <class 'str'>
[6]:
# boolean variable
x = True
print (x, type(x))
True <class 'bool'>

We can also do operations with variables.

[7]:
# Variables can be used with each other
a = 1
b = 2
c = a + b
print (c)
3

We should always know what types of variables we’re dealing with so we can do the right operations with them. Here’s a common mistake that can happen if we’re using the wrong variable type.

[8]:
# int variables
a = 5
b = 3
print (a + b)
8
[9]:
# string variables
a = "5"
b = "3"
print (a + b)
53

Lists#

Lists are an ordered, mutable (changeable) collection of values that are comma separated and enclosed by square brackets. A list can be comprised of many different types of variables (below is a list with an integer, string and a float).

[10]:
# Creating a list
x = [3, "hello", 1.2]
print (x)
[3, 'hello', 1.2]
[11]:
# Length of a list
len(x)
[11]:
3

You can add to a list by using the append function.

[12]:
# Adding to a list
x.append(7)
print (x)
print (len(x))
[3, 'hello', 1.2, 7]
4
[13]:
# Replacing items in a list
x[1] = "bye"
print (x)
[3, 'bye', 1.2, 7]
[14]:
# Operations
y = [2.4, "world"]
z = x + y
print (z)
[3, 'bye', 1.2, 7, 2.4, 'world']

Indexing and Slicing#

Indexing and slicing from lists allow us to retrieve specific values within lists. Note that indices can be positive (starting from 0) or negative (-1 and lower, where -1 is the last item in the list).

643a40aae74e48d8b8c00a6ff1d0be8b

[15]:
# Indexing
x = [3, "hello", 1.2]
print ("x[0]: ", x[0])
print ("x[1]: ", x[1])
print ("x[-1]: ", x[-1]) # the last item
print ("x[-2]: ", x[-2]) # the second to last item
x[0]:  3
x[1]:  hello
x[-1]:  1.2
x[-2]:  hello
[16]:
# Slicing
print ("x[:]: ", x[:]) # all indices
print ("x[1:]: ", x[1:]) # index 1 to the end of the list
print ("x[1:2]: ", x[1:2]) # index 1 to index 2 (not including index 2)
print ("x[:-1]: ", x[:-1]) # index 0 to last index (not including last index)
x[:]:  [3, 'hello', 1.2]
x[1:]:  ['hello', 1.2]
x[1:2]:  ['hello']
x[:-1]:  [3, 'hello']

Tuples#

Tuples are collections that are ordered and immutable (unchangeable). You will use these to store values that will never be changed.

[17]:
# Creating a tuple
x = (3.0, "hello") # tuples start and end with ()
print (x)
(3.0, 'hello')
[18]:
# Adding values to a tuple
x = x + (5.6, 4)
print (x)
(3.0, 'hello', 5.6, 4)
[19]:
# Try to change (it won't work and you'll get an error)
# x[0] = 1.2

Dictionaries#

Dictionaries are an unordered, mutable and indexed collection of key-value pairs. You can retrieve values based on the key and a dictionary cannot have two of the same keys.

0ad3e71589774897bcf9823c1c753480

[20]:
# Creating a dictionary
person = {'name': 'Goku',
          'eye_color': 'brown'}
print (person)
print (person['name'])
print (person['eye_color'])
{'name': 'Goku', 'eye_color': 'brown'}
Goku
brown
[21]:
# Changing the value for a key
person['eye_color'] = 'green'
print (person)
{'name': 'Goku', 'eye_color': 'green'}
[22]:
# Adding new key-value pairs
person['age'] = 24
print (person)
{'name': 'Goku', 'eye_color': 'green', 'age': 24}
[23]:
# Length of a dictionary
print (len(person))
3

If statements#

We can use if statements to conditionally do something. The conditions are defined by the words if, elif (which stands for else if) and else. We can have as many elif statements as we want. The indented code below each condition is the code that will execute if the condition is True.

[24]:
# If statement
x = 4
if x < 1:
    score = 'low'
elif x <= 4: # elif = else if
    score = 'medium'
else:
    score = 'high'
print (score)
medium
[25]:
# If statement with a boolean
x = True
if x:
    print ("it worked")
it worked

Loops#

For Loops#

A for loop can iterate over a collection of values (lists, tuples, dictionaries, etc.) The indented code is executed for each item in the collection of values.

[26]:
# For loop
veggies = ["carrots", "broccoli", "beans"]
for veggie in veggies:
    print (veggie)
carrots
broccoli
beans

When the loop encounters the break command, the loop will terminate immediately. If there were more items in the list, they will not be processed.

[27]:
# `break` from a for loop
veggies = ["carrots", "broccoli", "beans"]
for veggie in veggies:
    if veggie == "broccoli":
        break
    print (veggie)
carrots

When the loop encounters the continue command, the loop will skip all other operations for that item in the list only. If there were more items in the list, the loop will continue normally.

[28]:
# `continue` to the next iteration
veggies = ["carrots", "broccoli", "beans"]
for veggie in veggies:
    if veggie == "broccoli":
        continue
    print (veggie)
carrots
beans

While Loops#

A while loop can perform repeatedly as long as a condition is True. We can use continue and break commands in while loops as well.

[29]:
# While loop
x = 3
while x > 0:
    x -= 1 # same as x = x - 1
    print (x)
2
1
0

Functions#

Functions are a way to modularize reusable pieces of code. They’re defined by the keyword def which stands for definition and they can have the following components.

37e767f3a33440219451ddd157b97566

[30]:
# Define the function
def add_two(x):
    """Increase x by 2.""" # explains what this function will do
    x += 2
    return x

Here are the components that may be required when we want to use the function. we need to ensure that the function name and the input parameters match with how we defined the function above.

b1bde610e5724ca0a70a6cd6726b5284

[31]:
# Use the function
score = 0
new_score = add_two(x=score)
print (new_score)
2

A function can have as many input parameters and outputs as we want.

[32]:
# Function with multiple inputs
def join_name(first_name, last_name):
    """Combine first name and last name."""
    joined_name = first_name + " " + last_name
    return joined_name
[33]:
# Use the function
first_name = "Goku"
last_name = "Mohandas"
joined_name = join_name(first_name=first_name,
                        last_name=last_name)
print (joined_name)
Goku Mohandas

It’s good practice to always use keyword argument when using a function so that it’s very clear what input variable belongs to what function input parameter. On a related note, you will often see the terms *args and **kwargs which stand for arguments and keyword arguments. You can extract them when they are passed into a function. The significance of the * is that any number of arguments and keyword arguments can be passed into the function.

[34]:
def f(*args, **kwargs):
    x = args[0]
    y = kwargs.get('y')
    print (f"x: {x}, y: {y}")
[35]:
f(5, y=2)
x: 5, y: 2

Classes#

Classes are object constructors and are a fundamental component of object oriented programming in Python. They are composed of a set of functions that define the class and it’s operations.

__init__ function#

The __init__ function is used when an instance of the class is initialized.

[36]:
# Creating the class
class Pet(object):
    """Class object for a pet."""

    def __init__(self, species, name):
        """Initialize a Pet."""
        self.species = species
        self.name = name
[37]:
# Creating an instance of a class
my_dog = Pet(species="dog",
             name="Scooby")
print (my_dog)
print (my_dog.name)
<__main__.Pet object at 0x7f4f74247f10>
Scooby

__str__ function#

The print (my_dog) command printed something not so relevant to us. Let’s fix that with the __str__ function.

[38]:
# Creating the class
class Pet(object):
    """Class object for a pet."""

    def __init__(self, species, name):
        """Initialize a Pet."""
        self.species = species
        self.name = name

    def __str__(self):
        """Output when printing an instance of a Pet."""
        return f"{self.species} named {self.name}"
[39]:
# Creating an instance of a class
my_dog = Pet(species="dog",
             name="Scooby")
print (my_dog)
print (my_dog.name)
dog named Scooby
Scooby

Classes can be customized with magic functions like __init__ and __str__, to enable powerful operations. We’ll be exploring additional built-in functions in subsequent notebooks (like __len__, __iter__ and __getitem__, etc.) but if you’re curious, here is a tutorial on more magic methods.

Object methods#

[40]:
# Creating the class
class Pet(object):
    """Class object for a pet."""

    def __init__(self, species, name):
        """Initialize a Pet."""
        self.species = species
        self.name = name

    def __str__(self):
        """Output when printing an instance of a Pet."""
        return f"{self.species} named {self.name}"

    def change_name(self, new_name):
        """Change the name of your Pet."""
        self.name = new_name
[41]:
# Creating an instance of a class
my_dog = Pet(species="dog", name="Scooby")
print (my_dog)
print (my_dog.name)
dog named Scooby
Scooby
[42]:
# Using a class's function
my_dog.change_name(new_name="Scrappy")
print (my_dog)
print (my_dog.name)
dog named Scrappy
Scrappy