Today: list memory, 3x range() forms, while/break logic
Whoops! Forgot to mention this example in Mon lecture, but here it is. For the homework, just need to understand Form-1 or Form-2 (solutions below). You can download the .zip to run it yourself, or just look at the solution pattern below.
affirm.zip Example of main() command line args
The affirm.py program takes 3 command line forms
python3 affirm.py -affirm Bart
argslist is a list of the strings typed after the py
argsis the list
python3 affirm.py -hello Bart
python3 affirm.py -n 100 Bart
def main(): """ This program takes 3 command line arg forms: 1. -affirm *name* 2. -hello *name* 3. -n *number* *name* """ # standard - load "args" list with cmd-line-args args = sys.argv[1:] # args is a list of the command line argument strings that follow # the program.py file. # So if the command is: python3 affirm.py aaa bbb ccc # The args list will be: # args == ['aaa', 'bbb', 'ccc'] # The args are all strings, whatever was typed in the terminal. # There are 3 command-line-argument patterns below. # The code is complete for pattern-1, with the others TBD. # 1. This example if-statement recognizes the arg pattern: # python3 affirm.py -affirm Bart # e.g. args is '-affirm' and args is 'Bart' # Print out: Looking good Bart # 'Looking good' is selected from the random AFFIRMATIONS list if len(args) == 2 and args == '-affirm': # Select random nice phrase affirmation = random.choice(AFIRMATIONS) print(affirmation, args) # 2 - Write an if-statement to recognize this arg pattern: # python3 affirm.py -hello Lisa # Print out: Hello Lisa # Here 'Hello' is fixed, nothing random. pass # 3 - Write an if-statement to recognize this arg pattern: # python3 affirm.py -n 100 Maggie # Print out 100 copies of 'Maggie' separated by spaces # Note: the command line arg is a string, convert to int pass
... # 2 - Write an if-statement to recognize this arg pattern: # python3 affirm.py -hello Lisa # Print out: Hello Lisa # Here 'Hello' is fixed, nothing random. if len(args) == 2 and args == '-hello': print('Hello', args) # 3 - Write an if-statement to recognize this arg pattern: # python3 affirm.py -n 100 Maggie # Print out 100 copies of 'Maggie' separated by spaces # Note: the command line arg is a string, convert to int if len(args) == 3 and args == '-n': # Note: command line values are always strings, so here # convert to int form for use in range() n = int(args) for i in range(n): # Print each copy of the name with space instead of \n after it. print(args, end=' ') # Print a single \n after the whole thing. print()
x = y- x points to same thing as y
See: Python Variables
>>> # Build up a list to have 3 string elements >>> lst =  >>> lst.append('yo') >>> lst.append('yo') >>> lst.append('ma') >>> lst ['yo', 'yo', 'ma']
Here is the memory picture for this state. Each element in the list can hold anything. Here they each hold a pointer to a string. In this way, each is like a variable, and = can work on each one.
What does the following line do?
>>> lst2 = lst
= does not duplicate or makes a copy of a data structure. Instead the
= works in a shallow way, just setting the pointer in the left variable to point to the same thing as the right variable.
Here is a picture after the assignment
>>> lst 'ma' >>> lst2 'ma'
lst, is like a little variable
>>> lst = 'Donut'
Here is the memory picture after that change:
Now if we look at the value of
lst2 .. they both show the changed list, since in fact there is just the one list and they are both pointing to it.
>>> lst ['yo', 'yo', 'donut'] >>> lst2 ['yo', 'yo', 'donut']
This code sets up 2 lists of numbers
>>> evens = [2, 4] >>> odds = [1, 3, 5]
A list can be stored inside of an "outer" list. This code sets up the list outer: its first element is the "evens" list, its second element is the "odds" list.
>>> evens = [2, 4] >>> odds = [1, 3, 5] >>> outer =  >>> outer.append(evens) >>> outer.append(odds) >>> >>> outer [[2, 4], [1, 3, 5]] >>> >>> outer [2, 4] >>> outer [1, 3, 5]
Here is a memory picture of how outer is built.
A classic way to "iterate" over numbers. All languages have some way to do this, and the Python range() functions are an easy and flexible way to do it.
range(stop_num)# yields 0, 1, 2, .. stop_num-1
range(10)# yields 0, 1, 2, ... 9
range(0)- no numbers at all
# standard for/i/range structure for i in range(20): print(i)
range(start, stop)# this form = 2 parameters
range(5, 10) → [5, 6, 7, 8, 9] range(5, 6) →  range(5, 5) →  # i.e. nothing range(5, 4) →  # i.e. nothing
range(start, stop, step)# this form = 3 parameters
range(0, 10, 2) → [0, 2, 4, 6, 8] range(200, 800, 100) → [200, 300, 400, 500, 600, 700]
range(5, 0, -1) -> [5, 4, 3, 2, 1] range(10, 5, -2) -> [10, 8, 6] range(10, 10, -2) -> 
In interpreter, try these with list(range(xxx)) form which makes a [ ... ] list of the numbers, making the exact range of numbers very clear:
>>> list(range(10, 5, -2)) [10, 8, 6]
Given a non-negative int n, return a list of n multiples of 6 starting with 6 itself, e.g. n=3 returns [6, 12, 18].
Given a non-negative int n. Create and return a list of lists like this: [, [1, 2], [1, 2, 3] .... [1, 2, 3, .. n]]. There will be n lists inside the outer list. Use nested range loops. One approach: write outer loop to set a "top" variable which varies the top number for each inner list.
Output for n=3. Use this to think about outer and inner loops:
[ , [1, 2], [1. 2. 3], ]
def triangle(n): outer =  # Outer loop, one iteration per inner list for top in range(1, n + 1): # Inner loop, create 1 inner list # 1..top inner =  for i in range(1, top + 1): inner.append(i) outer.append(inner) return outer
Extra problem for practice.
Consider the sequence 100, 200, 300, ... n*100. For each 'x00' multiple of 100 in that sequence, make a list of the 10 numbers leading up to that number, e.g. [91, 92, 93, 94, 95, 96, 97, 98, 99, 100]. Return a big list of all these lists as elements, first the list of 100, then 200, and so on. N = 2 yields [[91, 92, 93, 94, 95, 96, 97, 98, 99, 100], [191, 192, 193, 194, 195, 196, 197, 198, 199, 200]]. Use nested range loops.
Censor problem: censored(n, censor): Given a non-negative int n. Return a list of the ints [1, 2, 3, ... n]. Except as soon as a number in the given censor list is seen, end the list without that number, so censored(10, [5, 4]) returns [1, 2, 3]. Use "break"
def censored(n, censor): nums =  for i in range(1, n + 1): if i in censor: # Key: if-break break nums.append(i) return nums
def censored(n, censor): nums =  for i in range(1, n + 1): if i in censor: i = n + 1 # let'd be done with this loop else: result.append(i) return nums
i = 0 # 1. init while i < n: # 2. test # use i i += 1 # 3. increment, bottom of loop
double_char() written as a while (using a range() is eaier for this problem, so just demonstrating what while would look like)
def while_double(s): result = '' i = 0 while i < len(s): result += s[i] + s[i] i += 1 return result
Given string s. Return a list of all the '[' strings in s. Use s.find() within a while loop to find all the '['.
search as index variable, marking current position of search within s.
In loop - how to find each '['? How to end the loop when there is no '['? Important at bottom of loop, advance variable for next iteration ("search" in this case)
def all_lefts(s): search = 0 result =  while search < len(s): left = s.find('[', search) if left == -1: break result.append(s[left:left + 1]) # Key: set up var at end of loop search = left + 1 return result
This pulls it all together, solving a realistic problem.
Given string s. Return a list of all the 'abc' strings for each '[abc]' substring within s. For each left bracket, find the right bracket that follows it. End the search if no left or right bracket is found. Use s.find() within a while loop.
Start with the all_brackets() code. Add code to find the right-bracket following each left bracket. As before: how to terminate the loop? Remember to advance search variable at bottom of loop.
def all_brackets(s): search = 0 result =  while search < len(s): left = s.find('[', search) if left == -1: break # Your code here pass right = s.find(']', left + 1) if right == -1: break result.append(s[left + 1:right]) # Key: set up var at end of loop search = right + 1 return result