Session+2.2

=Tests, Loops, and Escapes=

Topics

 * **if** tests
 * **and**, **or,** and **not** logic
 * **for** loops
 * Using range in a loop
 * Nested for loops for complex data structures
 * Indexing loops with enumerate
 * Loops with zip
 * While loops
 * Loop control and escapes with **continue** and **break**

Introduction
In the last few action-packed sessions, we've learned quite a bit. However, we're still missing two of the most essential components of programming: logic and repetition. To add these to your Python programs, there are three key words that you will need: **if, for,** and **while.**

The objective, when you begin programming, is to make the computer do your work for you. Instead of normalizing that microarray data or computing that crystal structure fit with a pocket calculator and a bucket of coffee, you want to be able to say, 'Computer, do my work,' and then have it done. Of course, you'd have to say it a little more clearly than that -- for instance, to pick out over-expressed membrane proteins from microarray data, you could tell the computer that for each gene in the genome:

"If the protein is located in the membrane, tell me //if// that protein's expression level under a given set of experimental conditions [stored in column 2, for example] is 5-fold or more greater than the expression level under control conditions [stored in column 4, for example]."

Q: What's the magic word there? A: if

Indeed, the **if** statement is one of the most fundamental components of programming, and it is found in some form or another in every general-purpose programming language (and nearly all specialized ones, too). It simply tells the computer to execute a block of code if a given statement is true. If the statement is false, the code is skipped. Although the concept is simple, conditional statements like **if** allow your programs to make decisions on their own.

Now, how can we ask the above question about every protein in our dataset of 5, or 20, or 10,000 proteins? The really great thing about computers is their ability to do things over and over again really quickly, without getting bored. It's easy for us to do stuff on a handful of data points, but more than a couple dozen (or two, depending on how much patience we have) and we'd really start wishing the computer was doing it for us. Every programming language has a way to do this, looping over a section of code multiple times. Python has two kinds of loops: the **for** loop and the **while** loop.

In principle, anything you can do with one you should be able to do with the other somehow, but it's often a lot cleaner to pick the appropriate one for the situation. Hopefully once you've seen how each one works, it will be reasonably obvious which one is best for any given job at hand.

The Syntax of //if//
In Python, we construct our **if** statements with this general form:

> **execute this line of code** > **execute this line of code too**
 * if** :

The key pieces of syntax here are the **if**, the condition that we would like to evaluate (note: the condition is expressed within brackets **<>** for emphasis in this example, but brackets are not used in real code), the colon **:** that signifies the end of the logical test, and the tab-indentation for the things to do below the first line of the statement.

We will discuss what makes things **True** in a minute, but for now we should focus on the syntax. Beyond the **if** and the colon, Python will execute all of the following indented code. Indentation is the signal to the interpreter that this block of code is under the control of the **if** statement.

Speaking of decision making, we could use this syntax to write a program that spares us the trouble of deciding what to eat each week:

code format="python"
 * 1) !/usr/bin/env python

checkingAccountBalance = 4


 * 1) Let's imagine that I have to eat crappy ramen if I
 * 2) have less than $10 at the start of the week, but I
 * 3) can eat the fancier kind if I have more...

if checkingAccountBalance < 10: thisWeeksFood = 'ramen' if checkingAccountBalance >= 10: thisWeeksFood = 'goodRamen'

print "We are eating %s this week" % (thisWeeksFood)


 * 1) But maybe if I have exactly $15, I can get the
 * 2) very best ramen.

if checkingAccountBalance == 15: thisWeeksFood = 'that particular brand of good ramen'

if checkingAccountBalance != 15: thisWeeksFood = 'certainly _not_ that brand!' print 'absolutely not!'
 * 1) if statements can contain more than one command

code

Not bad for a start, but we'd like to clean that up a bit. Not only is "checkingAccountBalance >= 10" a pile of unnecessary keystrokes, it could also hurt us down the road. For instance, what if inflation pushed up the price of good ramen? We'd want to change out cutoff point to twelve bucks, for instance. However, if we changed the numbers in just the first **if** statement, but forgot to change the second, we'd have a bug in our code. By making our program simpler we can avoid such mistakes, and we can make things simpler by using python's **else** statement.

code format="python" if checkingAccountBalance < 10: thisWeeksFood = 'ramen' else: thisWeeksFood = 'goodRamen' code

But what if there's a third option? Or a fourth? This is taken care of by Python's **elif** statement (short for "else if"). **elif** tells Python that the indented code immediately following the **elif** statement should only be executed if the preceding **if** or **elif** statement(s) evaluated to false.

code format="python" if checkingAccountBalance < 10: thisWeeksFood = 'ramen' elif checkingAccountBalance < 100: thisWeeksFood = 'good ramen' elif checkingAccountBalance < 200: thisWeeksFood = 'better ramen' else: thisWeeksFood = 'ramen that is truly profound in its goodness' code

As a rule, it's good practice to account for all possibilities in your **if, elif, else** statements. In the case of our $10 budget, we initially cared only if we had $10 or more, and so this might be a safe place to use the **if, else** construct to account for all possibilities. But what if we actually had a zero balance in our checking accounts, and thus had no money to exchange for noodles? (Don't worry, you can always steal cookies at the departmental seminar.) We've accounted for all positive values with our above logic, but we've left an implicit assumption that having $0 or less on our checking account balance still results in our eating ramen this week. The point: we often make oversights that python will not overlook. These can result in interesting, though nonsensical outcomes -- like getting ramen for nothing. The lesson is to be careful and thorough as you compose your logical statements.



At least we know what's for dinner.

The Nature of truth
But what is truth, anyway? Here we have a simple statement, "less than," and it's meaning is intuitive. But truth has a formal meaning in Python, as it does in all programming languages. In short:


 * Any nonzero number, nonempty object, and the special object **True** are things Python believes to be **True.**
 * Zero numbers, empty objects, and the special objects **None** and **False** are things Python believes to be **False.**

To evaluate an object's identity, employ the **==** logical operator. **==** evaluates whether the value of the two operands on either side are equal or not, and if they are, the statement evaluates to **True**. To learn more about operators, go here.

code format="python" s = 0

if s:   print "s is True!" else: print "s is False!"

if s == 0: print "s is True!" else: print "s is False!" code

**and**, **or**, (and) **not**
Finally, what if we want to evaluate more than one **if** statement at once? The Boolean operators **and**, **or**, and **not** can help us out. The operator **and** will only return **True** if both accompanying statements are **True**, while **or** will return **True** if either accompanying statement is **True**. **not** returns the inverse of the logical value of the statement given.

code format="python" true_statement = 'truth itself' # non-empty strings are true false_statement = '' # empty strings are false

if true_statement and false_statement: print "This should not print." else: print "This should print."

if true_statement or false_statement: print "This should print."

if not false_statement: print "This should print."

if not (true_statement and false_statement): print "This should print." code

To learn about order of operations in Python: go here

**for** loops
The for loop allows you to perform the same actions multiple times, but with different data each time through (some languages have an equivalent construct and call it a for each loop). We've even used this concept before when talking about lists, we just didn't explain what was going on:

code format="python"
 * 1) !/usr/bin/python

li = ['Red Leicester', 'Gruyere', 'Camembert', 'Parmesan', 'Mozarella', 'Cheddar']

for x in li: print x code
 * 1) iterate over list


 * $./loops.py**

code format="python" Red Leicester Gruyere Camembert Parmesan Mozarella Cheddar code

The general syntax here is that for goes through each item in the list (or tuple or dictionary) after the in, stores that in the variable name before in, then executes the code after the colon. Once it's done all that code, it gets a new element from the list, and repeats.

code format="python" for VARIABLE_NAME in CONTAINER: DO_SOMETHING DO_SOMETHING_ELSE ....


 * 1) is the same as

VARIABLE_NAME = CONTAINER[0] DO_SOMETHING DO_SOMETHING_ELSE

VARIABLE_NAME = CONTAINER[1] DO_SOMETHING DO_SOMETHING_ELSE

VARIABLE_NAME = CONTAINER[2] DO_SOMETHING DO_SOMETHING_ELSE ... code
 * 1) and so on

Just like an if statement, if you want to do more than one thing inside the loop, you can start a new block of indented lines after the colon, and then when you're done with the code you want to run every time, go back to the original indentation:

code format="python"
 * 1) !/usr/bin/python

li = ['Red Leicester', 'Gruyere', 'Camembert', 'Parmesan', 'Mozarella', 'Cheddar']

for x in li: print "Cleese: Do you have any %s?" % x   if x == 'Camembert': print "Chapman: Oooh, the cat's eaten it!" else: print "Chapman: No." print "Cleese: Well I'm sorry, but I'm going to have to shoot you." code
 * 1) iterate over list

Looping a given number of times
code format="python" for x in range(4): print 'hello' y = range(4) print y code $**./loops.py** code format="python" hello hello hello hello [0, 1, 2, 3] code

Mutating lists with loops
When we were discussing lists, we said that they were mutable. We showed that in a couple of ways, such as by using the sort method. If we wanted to change elements in a list, here's one way we might think to do it:

code li2 = [1,22,48,36,101] print li2 for x in li2: x = x + 42 print li2 code

code format="python" [1, 22, 48, 36, 101] [1, 22, 48, 36, 101] code
 * $./loops.py**

The reason this doesn't work as you might expect is actually fairly subtle, and to explain it, we're going to have a brief informative interlude about names and references.

Brief informative interlude
When we say that something is mutable, we mean that we can change the value without destroying the original data structure. To understand what this means, let's first discuss things that are immutable, such as strings and integers. Let's say we have an integer variable (for example, x = 5) and want to change its value to 10. We can't make 5 = 10, but we can easily (and efficiently) reassign x so that x = 10. The same thing is true for a string.

code format="python" S = 'Spam' S[0] = 'z' code
 * 1) !/usr/bin/python
 * 2) mutables.py

$**./mutables.py** code format="python" Traceback (most recent call last): File "./loops.py", line 4, in    S[0] = 'z' TypeError: 'str' object does not support item assignment code

So what do you do if you need to mutate this immutable string? Just like with the integer, you have to reassign the variable name to the value that you now want it to have. So to transform Spam in zpam, we could do this:

code format="python"
 * 1) !/usr/bin/python
 * 2) mutables.py

S = 'Spam' print S

S = 'z' + S[1:] print S code

On the other hand, lists and dictionaries can get pretty big, and it would be really inefficient in most cases to recreate the whole thing if you only want to change part of it. As it turns out, Python does not delete the original list and recreate another list with the update value, it merely changes the updated value in place. This means that instead of having to make resource-consuming copies of our data, we can change the mutable variables directly. Lists and dictionaries are mutable; tuples and strings are not.

Let's look some short code examples to compare the mutability of strings and lists.

code format="python" a = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] a[0] = 'X' print a
 * 1) Let's make a list

b = a print b

b[1] = 'Y' print b, "is the value of b" print a, "is the value of a" code

$ **./mutables.py** code format="python" ['X', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] ['X', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] ['X', 'Y', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] is the value of b ['X', 'Y', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] is the value of a code

What just happened? At this point, we're going to dive a little bit into how Python works internally. Imagine that you have a giant warehouse full of stuff, and in the front office of that warehouse is a catalog telling the names of all the stuff, and where each thing is. When you make a new variable, Python does two things: it puts that new thing into the warehouse, and it updates the catalog with a new entry.

When you say "b = a", Python is a bit lazy, and since the thing that corresponds to a already exists, it just puts a new entry into the catalog with the name b and the location of the object. In a very important sense, the thing in the catalog named b is the thing in the catalog named a (and there exists, in fact, a keyword is that will confirm this, although we won't use it at all in this course). It's also possible to have two things in the catalog that look and act the same, but are different. To visualize this, let's go here.

When a and b are mutable things (like lists, or dictionaries), then changing "a" also changes "b" because they are the same thing. If you were working with an immutable object, like a string, then the only way to "change" a would be to make a new object and then update the catalog to point to that new object.

code format="python" a = 'abcdefg'
 * 1) Makes a string object in the warehouse and an entry called "a"
 * 2) in the catalog that tells you where to find that object

b = a  # Makes a duplicate catalog entry

a = 'gfedcba'
 * 1) Makes a new string object, and updates the entry labelled "a" in the catalog

print a print b code
 * 1) The entry "b" in the catalog still tells you where to find the original string

As a general rule, whenever you have what Python calls a "container" (like a list, or a dictionary), it doesn't actually contain the object itself, it just contains another mini-catalog that tells you where to find the relevant object. For further reading on this subject, you can look at the (quite dense and hard to parse) Python documentation on the Data model and the Execution model.

Back to scheduled programming
So, to change the elements in a list, you usually have to modify the list directly, rather than the loop variable:

code format="python" li2 = [1,22,48,36,101, 42] print li2 for x in range( len(li2) ): li2[x] = li2[x] + 23 print li2 code

Here we've used the **range** function to make a list of indexes as long as the list, //li2//. This is admittedly clunky, and Python has a built-in alternative, **enumerate**.


 * enumerate** returns a tuple with the index of the item as well as the item itself. Because of the way Python handles assignment of tuples, you can then assign that tuple to two variables, one for the index and one for the element itself. You can use the index to access the actual item in the list, not just the copy. However, you can access the copy, too, if you want.

code format="python" print li2 for xInd, x in enumerate(li2): print x   li2[xInd] = li2[xInd] + 23 print x   print print li2 code

code format="python" [1, 22, 48, 36, 101, 42] 1 1
 * $./loops.py**

22 22

48 48

36 36

101 101

42 42

[24, 45, 71, 59, 124, 65] code

**while** loop
The rough format of a while loop is similar to a for loop: there's a colon at the end of the first line, and an indented block of code that gets run every time through. Despite this general similarity, while acts a little differently than a for loop. Instead of giving a list of items to iterate over, a while loop continues until the statement between while and the colon no longer has thruthiness (e.g. False,, [], '', etc).

code format="python"
 * 1) !/usr/bin/python

x = 'Ni!' while x:   print x    x = x[1:] print

x = 5 while x > 0: print x   x = x - 1 print code


 * $./loops.py**

code format="python" Ni! i! !

5 4 3 2 1 code

Escaping loops
Occasionally, you might want to get out of a loop before the truth statement is met (with a while loop) or you've gone through every element (with a for loop). In fact, some loops are designed such that the control condition at the top of the loop is never met! You can modify the default flow of the loop using break and continue. The keyword break ends the loop right where you are, while the keyword continue goes back to the top of the loop (bringing in the next item in the list if it's a for loop).

code format="python" while True: dividend = int(raw_input("Dividend: ")) divisor = int(raw_input("Divisor: ")) if divisor == 0: break print dividend/divisor code

code format="python"
 * 1) !/usr/bin/python

x = 10 while x:   x = x-1 #use mod to check if number #is even? go to next number if x % 2 == 0: continue #use comma to print multiple #things on same line print x, print code


 * $./loops.py**

code format="python" 9 7 5 3 1 code

In this example, each number is checked by the if statement to see if it is even. In the event the number is even, the loop goes back to the while logical expression (i.e. that x != 0) and continues.

You can use else to check whether a for or while loop finished normally, without hitting a break. Just like an if statement, the else should be at the same level of indentation as the for or while, have a colon, and then a block of code to run.

code format="python"
 * 1) !/usr/bin/python

y = 10 x = y-1 while x > 1: if y % x == 0: print x, 'is a factor of', y       break x = x-1 else: print y, 'is prime' code


 * $ ./loops.py**

code format="python" 5 is a factor of 10 code

Here, y is checked for each number to see if it is evenly divisible (also called a factor). If y is evenly divisible, the number is printed and the code stops. If no factor is found, the loop defers to the else statement. What happens when you change the y to 100? 43? 3?

List Comprehensions
Sometimes we'll want to change every item in a list in a systematic way. For example, we may want to add one to each of a list of integers:

code format="python"
 * 1) !/usr/bin/python

a = range(10) b = [] for i in a:   b.append(i + 1) a = b print a code

This is a totally acceptable way to solve this problem. However, because it is very common to commit the same operation on every member of a list, Python provides for us a shortcut that is both syntactically more concise, and computationally optimized to be much, much faster. It's called list comprehension, and it works like this:

code format="python"
 * 1) !/usr/bin/python

a = range(10) print [ i + 1 for i in a ]
 * 1) let's recreate our list
 * 1) note that the entire statement below is contained in **[ ]**
 * 2) This is the defining syntax of a **list comprehension**.

a = [ i + 1 for i in a ] print a code
 * 1) note also that we have to save the resulting new list back
 * 2) to **a** if we want to replace the old list

1. Truth or Consequences
Use the following format to evaluate the truth of some expressions in python:

code format="python" query =

if query: print 'Query is true' else: print 'Query is false' code

Try the following things in the blank. Are they True? If you don't see exactly why they are True or False, please ask a TA.

A) "" (the empty string)

B) []

C) {}

D) (a list containing an empty list)

E) 0

F) [0]

G) [0][0] (also-- what is this? Print out the value of [0][0] and [1][0] before doing the truth test)

H) [0]

2. My Pet Gene Finder
Write your first gene-finding program: have the user enter a string of six nucleotides. If the length of the string is not six, tell the user to input another string. If it is, and the six nucleotide sequence contains 'ATG,' print the position where it is found. If 'ATG' appears multiple times, print only the location of the first instance. If the string does not contain 'ATG', print -1.

Hint: one way to do this is to create the four three-base substrings of this string and then determine whether any of the resulting substrings are 'ATG.'

3. Baby's First FASTA Parser
Write your first FASTA parser: from a series of user inputs, you wish to create a dictionary keyed by gene IDs with values corresponding to their sequence. A FASTA file has the following format: >gene1 ATAGCAGTTAGC TTAGCAGCAGTT ATAGCGCA >gene2 ATGACGACGATT TTGACGACTAGG ACAGCC >gene3 AGATGCCCCCTT ...

While you will learn about handling files soon, for now, assume that this file is being typed in by the user -- their first input will be '>gene1', their second will be 'ATAGCAGTTAGC', and so on. Ask the user for input 6 times (3 genes and 3 corresponding sequences). For each line input, you will have to determine whether it is a gene name or a sequence and act accordingly. Assume that the gene names and sequences will be entered in pairs (i.e. if the first input was a sequence, then the next will be the corresponding gene name, etc). Your dictionary should have keys 'gene1', 'gene2', and 'gene3' (note the absence of the '>' symbol) and the sequences of those genes as values.

Hint: Construct two lists with matching indices and combine them into a dictionary. You can use a for loop and **zip** (shown below) to create a dictionary keyed by items from list a with values from list b.

code format="python" a = range(10)
 * 1) list of 0 to 10

b = range(20)[10:]
 * 1) list of 10 to 20

d = dict(zip(a,b))

print d

code

4. Operator, Give Me the Number for 911
Replace "X" in this code with a statement that ensures that if the user entered "1", a "0" is printed, and if they entered a "0", a "1" is printed. Don't worry about other numbers.

code format="python" s = raw_input("Enter a number: ") s = int(s) t = X print t code

5. FizzBuzz
FizzBuzz is a counting game where you need to be a bit on your toes. You start counting upwards, but: When you have a number that's a multiple of three, you say "Fizz" When you have a number that's a multiple of five, you say "Buzz" When you have a number that's a multiple of both three and five, you say "FizzBuzz" Otherwise, you just say the number

Write a program that plays FizzBuzz for the numbers from 1 to 100. The output should look like this: 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz ...

You may find the % (modulo) operator helpful. This gives you the remainder when you divide one number by another, so: 1 % 3 gives 1 2 % 3 gives 2 3 % 3 gives 0 4 % 3 gives 1 5 % 3 gives 2 6 % 3 gives 0 7 % 3 gives 1 again, and so on.

6. Getting comfortable with Loops (adapted from __Learning Python__)
a) Computers only really understand numbers, not letters. Therefore, letters and symbols are stored in the computer according to numbers. The American Standard Code for Information Interchange (ASCII) is a formalized code that links characters and numbers. You determine the ASCII number code of a letter using the built-in function ord(character). For example, code format="python" >>> print ord('T') 84 code Write a for loop that prints the ASCII code of each character in the string 'Rock and Roll'. HINTS: You can loop over a string the same way you loop over a list. b) Next, change your loop to compute the sum of the ASCII codes of all characters in the string. c) Modify your code to print a new list that contains the ASCII codes of the characters in the string.

7. All Roads Lead to Rome (adapted from __Learning Python__)
A coworker (who obviously is not a native Python speaker) hands you the following code:

code format="python"
 * 1) !/usr/bin/python

L = [1,2,4,8,16,32,64] x = 5

found = i = 0 while not found and i < len(L): #check if 2 to the power #of x is in the list if 2 ** x == L[i]: found = 1 else: i = i+1 if found: print 'at index', i else: print x, 'not found' code

$ **./powers.py** code format="python" at index 5 code

As is, the script does not follow normal Python coding techniques. Follow the steps below to improve it. a) Rewrite this code with a while/else loop to eliminate the found flag and the final if statement. b) Rewrite the example to use a for/else loop to eliminate the explicit list indexing logic. c) Remove the loop completely by rewriting the examples using an expression with in (HINT: try the line 'print 2 in [1,2,3]') d) Use a for loop and the list append method to generate the list L instead of typing it by hand. e) Use a list comprehension and the exponentiation operator to generate the list L in one line (10**3 is 1000).

1. Truth or Consequences
code format="python"
 * 1) "" is False


 * 1) [] is False


 * 1) {} is False


 * 1) [ [] ] is True, because the list isn't empty, it has a list in it!


 * 1) 0 is False


 * 1) [0] is True, because the list isn't empty


 * 1) [0][0] is False, because [0] is a list, and [0][0] is the first position of the list, a.k.a., 0

code
 * 1) [ [] ][0] is False, because the 0th element of the list is an empty list.

2. My Pet Gene Finder
code format="python" hexamer = raw_input("Please enter a six-nucleotide sequence in all capital letters: ") if len(hexamer) != 6: print "Oh, hrmmmm... I'm fairly certain that sequence isn't of length 6." hexamer = raw_input("Please enter a six-nucleotide sequence in all capital letters: ")

start = 0 stop = 3

if hexamer[start:stop] == 'ATG': print start, "is the position of the first Met codon." else: start += 1 stop += 1

if hexamer[start:stop] == 'ATG': print start, "is the position of the first Met codon." else: start += 1 stop += 1

if hexamer[start:stop] == 'ATG': print start, "is the position of the first Met codon." else: start += 1 stop += 1 if hexamer[start:stop] == 'ATG': print start, "is the position of the first Met codon." else: print "-1" code

3. Baby''s First FASTA Parser
code format="python"
 * 1) a dict for genes

genes = [] sequences = []

input1 = raw_input("Enter the gene name (format: '>genename') or sequence (all caps!): ")

input2 = raw_input("If you entered the gene name above, enter the sequence here (and vice versa): ")

if input1[0] == ">": genes.append(input1[1:]) if input2[0] == ">": print "You did not enter a sequence." else: sequences.append(input2) elif input2[0] == ">": genes.append(input2[1:]) sequences.append(input1) else: print "You did not enter a gene name."

input1 = raw_input("Enter the gene name (format: '>genename') or sequence (all caps!): ")

input2 = raw_input("If you entered the gene name above, enter the sequence here (and vice versa): ")

if input1[0] == ">": genes.append(input1[1:]) if input2[0] == ">": print "You did not enter a sequence." else: sequences.append(input2) elif input2[0] == ">": genes.append(input2[1:]) sequences.append(input1) else: print "You did not enter a gene name."

input1 = raw_input("Enter the gene name (format: '>genename') or sequence (all caps!): ")

input2 = raw_input("If you entered the gene name above, enter the sequence here (and vice versa): ")

if input1[0] == ">": genes.append(input1[1:]) if input2[0] == ">": print "You did not enter a sequence." else: sequences.append(input2) elif input2[0] == ">": genes.append(input2[1:]) sequences.append(input1) else: print "You did not enter a gene name."

answer = dict(zip(genes, sequences)) print answer code

4. Operator, Give Me the Number for 911
code format="python" s = raw_input("Enter a number: ") s = int(s) t = int(not s) print t code

5. FizzBuzz
code format="python" nums = [i+1 for i in range(100)] # make a list that contains the numbers 1 - 100

for x in nums: if (x % 3 == 0) and (x % 5 == 0): print "FizzBuzz" elif x % 3 == 0: print "Fizz" elif x % 5 == 0: print "Buzz" else: print x code

6. Getting comfortable with Loops (adapted from __Learning Python__)
code format="python"
 * 1) !/usr/bin/env python

rockString = 'Rock and Roll' print rockString print

print 'a)' for x in rockString: print 'The ASCII value of %s is %s' % (x, ord(x)) print
 * a)

print 'b)' sum = 0 for x in rockString: sum = ord(x) + sum print sum, is the sum of the ASCII values corresponding to each of the letters of the string 'Rock and Roll'. print
 * b)

print 'c)' rockASCIIlist = [ ] for xInd, x in enumerate(rockString):   rockASCIIlist.append(ord(x))    #print rockASCIIlist # uncomment this to see the list grow with each iteration print rockASCIIlist print code
 * c)

7. All Roads Lead to Rome (adapted from __Learning Python__)
code format="python"
 * 1) !/usr/bin/env python

print 'a)' L = [1,2,4,8,16,32,64] x = 5
 * a)

i = 0 while i < len(L): if 2 ** x == L[i]: print 'at index', i       break else: i = i+1 else: print x, 'not found' print
 * 1) Less convoluted, but still indexing

print 'b)' L = [1,2,4,8,16,32,64] x = 5 for yInd, y in enumerate(L):   if 2 ** x == y:        print 'at index %s' % (yInd)        break print
 * b)

print 'c)' print 2 in [1,2,3] L = [1,2,4,8,16,32,64] x = 5 print 2**x in L print
 * c)
 * 1) Quickest way to see if something is in a list

print 'd)' L = [] for x in range(7):   L.append(2 ** x) print L print
 * d)

print 'e)' print [2**x for x in range(7)] code
 * e)