# Lab 3 Lesson¶

## Introduction to Python, Part 2¶

Topics

• functions
• importing packages
• random numbers
• while loops
• for loops
• looping infinitely
• break and continue statements
• manipulating strings

This lecture is centered around your reading for this week, chapters 4, 5, and 6 of Python for Everyone.

## Functions¶

A function, most basically, is a group of code that executes together when you call its name.

In [ ]:
def my_cool_function():
print("I'm so cool.")
print("Just look at what everyone calls me.")

my_cool_function()


Functions can have arguments, which are variables that the function can do stuff with. You pass a variable to a function by putting it in the parentheses after the function name.

In [ ]:
def hello(name):
print("Hello,", name)

hello("Bob")
hello("everyone")


All the code in a function is in a block, which, for Python, means that it's at the same indentation level. When you're done defining a function, just hit the backspace key until you're back at the normal indentation level. It's not required, but it's good practics to include a blank line after a function definition.

You can reference functions from other functions. When you call a function, all of its code runs like normal.

In [ ]:
def lyrics():
print("This is the song that never ends.")
print("It goes on and on, my friends.")

def song():
lyrics()
lyrics()

song()


We'll revisit the song that never ends when we talk about infinite loops. :)

One last thing: functions can return values, but they don't have to. Returning a value means that wherever you call the function, you can "catch" that value in a variable and use it in your program. This one's a little hard to see, but we'll look at a few examples.

In [ ]:
def add_three(num1, num2, num3):
sum = num1 + num2 + num3;
return sum

print(my_sum)

In [ ]:
def whats_my_name():
return "Sean Bailey"

whats_my_name()

my_name = whats_my_name()

In [ ]:
my_number = int("200") # is there a value being returned here?

In [ ]:
stuff = print("Lorem ipsum dolor sit amet")
print(stuff)


## Documentation¶

Python, like most other languages, has extensive official documentation available online. In your lab exercises this week, there are a few points where you'll have to read and interpret documentation.

Take a short look at the standard function documentation. Skimming documentation is a useful skill. Don't spend too much time reading the minutiae, but you should familiarize yourself, in broad strokes, with what you can do in Python with the library functions.

## Packages¶

Functions provided to you, the programmer, can be grouped into packages for distribution purposes. Don't worry about the specifics of that right now. Python provides a bunch of packages standard, but the Python community is legendary for writing packages concerning basically anything you could possibly want to do with Python.

The only thing that's relevant right now, package-wise, is importing. Importing a package is simple: at the top of a Python file, just put the words import and the package name you want to import. Simple, huh?

## Random Numbers¶

The standard Python package random provides the ability to generate pseudorandom numbers. (Don't use these for cryptography or security.) The easiest way to dip your toes into random numbers is to just generate some, so let's run some sample code.

In [ ]:
import random # see how easy that is?

x = random.random()
print(x)


Run that a few times. What can you tell about the numbers that the random() function is generating?

(Side note: you run functions from a package using a dot! So, pizza.list_toppings() is the list_toppings() function from the package named pizza.)

Generating just decimals is useful for a lot of things, and you'll find that the default random number generator in a lot of programming languages will do the same thing that Python does. But there's one that you'll use a lot more, at least right now: randint(). Let's take a look:

In [ ]:
random.randint(5, 10)


Let's break down this function a bit.

• arguments: 5 and 10
• range: from the first argument to the second argument
• return value: a number, between 5 and 10, of type Int

Random numbers in Python can be useful if you want a bunch of sample data to test out a function. It's easier to write a loop to generate 10,000 random integers between 0 and 1 million than it is to type them in manually. (Duh.)

With that in mind, let's talk about...

## Loops¶

Loops, most basically, allow you to tell a program to run an arbitrary section of code an arbitrary number of times.

In [ ]:
n = 0
while n < 10:
print("Current number:", n)
n = n + 1


That's a while loop, the simplest loop. It works like this:

while something:
do this stuff

At the beginning of each loop iteration, it'll test the something. If it's true, it'll run the code! If it's not, it'll move on to the next thing.

n above is the counter for the loop. You can make a loop run a specified number of times by incrementing the counter in the body of the loop, so, each time the loop runs, the counter gets 1 added to it.

You can use a while loop to loop infinitely, like so:

def lyrics(): print("This is the song that never ends.") print("It goes on and on, my friends.") while True: lyrics()

NOTE: This code absolutely can make your computer hang, browser crash, Jupyter stop working. If you really want to run it, change the cell to a code cell. But you have been warned.

It's probably a good idea to avoid infinite loops, in general. But, they can be tamed. You just have to break them.

In [ ]:
def lyrics():
print("This is the song that never ends.")
print("It goes on and on, my friends.")

while True:
lyrics()
break


So what happened there?

Since we used a break statement, the infinite loop stopped after running only once.

For loops are a little more fun: they let you play with sequences, like lists!

In [ ]:
my_friends = ["Bob", "Susan", "Noah", "Amanda"]

for friend in my_friends:
print("Hello,", friend)


Let's break that down a little.

• no counter: If you want to see where you are in the loop, you need to handle that separately.
• arbitrary names: friend doesn't mean anything outside of the loop.
• iterating over a sequence: lists let you iterate sequentially through them, and have a specified order.

## String Manipulation¶

There are two ways to approach dealing with strings:

1. Learn a bunch of methods that do stuff, use them individually, and forget about them twenty minutes after you finish the exercise.

2. Do some string manipulation. Remember that you can just Google for how to do Python string manipulation.

So... who wants to memorize a list of methods?

Group challenge: string manipulation

This is not part of your exercises for the week. It's a challenge for you to do in groups during the lab session. When you reach this point, find one or two people to work with.

Below is a code cell. The data variable contains a sample email header string. Your job is to write some code that takes that string and gets rid of everything but the domain. You're given

From [email protected] Sat Jan 5 09:14:16 2008

and you want to get

pitt.edu

You can imagine this being used in spam filtering on email servers. It's important for this to work with any potential email address. I should be able to replace [email protected] with [email protected] or with [email protected] and your code should still get me the domain of the email address.

The Python 3 string documentation is here: https://docs.python.org/3/library/string.html. It's going to be your best friend.

We'll look at some solutions before we leave today, but there are several good ways to approach this problem. If you need a hint, here you go:

• Is there anything that is going to always come before the thing you want? Anything that's the same across every email address?

Stuck? Just raise your hand. I'll come get you started.

In [ ]:
data = "From [email protected] Sat Jan  5 09:14:16 2008"

# what we want: just the url (pitt.edu)