Today - function call, return, start String data type
Foreshadow: Big Picture
- Program made of functions
- Data flows between functions
- How do functions exchange data?
- Function: black box model
data in: parameters
data out: return
- Today 1 function at a time, later build whole picture
Theme: "Black Box" Function Model
Black-box model of a function: function runs with parameters as input, returns a value.
All the complexity of its code is sealed inside. Calling it is relatively simple - provide parameters, get back an answer.
4 Functions Today
(had a tech problem in lecture, now fixed)
>
Black Box Functions
1. Parameters = Input
- Parameters are the inputs of a function
- Each parameter is like a variable with a value already in it
- Where does the value come from...
- (a) (non-answer) Not our concern how, but there's a value in there
- (b) (real answer) The caller code places a value between the parens when calling the function, and this is the value of each parameter
2. return yields the result of a function
Inside the body of a function, like this:
def foo(n):
...
return n * 10
...
- Return exits the run of foo() immediately
- The run continues at the caller code
- The value, e.g.
n * 10 is the return value of the foo() call
Suppose the caller code looks like
# in caller function
a = foo(6)
b = foo(7)
- The return line within foo() causes 60 to be returned by
foo(6)
essentially a = 60
- This is called the "return value" of the function
- The return value of
foo(7) is 70, assigned to b
Example 1. "Winnings1" Function
- Say we work for the CA lottery
- Writing a function for a game
- Rules: input is an int score 0..10 inclusive
- Output:
score 5 or more, winnings = score * 12
score 4 or less, winnings = score * 10
- We could make a table showing output for each input
- Writing code, we need to be organized thinking about the cases and their outputs
- Code needs to work for all cases, i.e. to be general
- Later: we'll see how to put in formal tests that the code is getting the right output for each input
in out
0 0
1 10
2 20
3 30
4 40
5 60
6 72
7 84
8 96
9 108
10 120
Winnings1 code
- This code works
score parameter comes in
- if/logic to check for score >= 5
- return is used twice
- "pick off" of cases
- So past the first if.. what is true of score?
- We know score < 5
def winnings1(score):
"""Compute winnings1 described above."""
if score >= 5:
return score * 12
# Run gets here: we know score < 5
return score * 10
Winnings if-return Case Strategy
- The function needs to handle all input cases
- If-logic detects one case .. returns the answer
- The return exits the function immediately with a return value
- Lines below have if-return logic for other cases
- Code is "picking off" the cases one by one
- As we get past if-checks .. input must be a remaining case
- Analogy: coin sorting machine
coin rolls past holes, each a bit larger
dime, penny, nickel, quarter
a dime never makes it to the quarter-hole
The dime is picked-off earlier
- Bug demo: change <= to <
Return None Default
- Demo: cut out the code, just have a "pass"
- If a function does not run a return,
None is default function result
- If you see
None in your output - maybe you forgot the return
- Or your if-logic for some case doesn't return
Example 2. Winnings2 Example
Now there's 3 cases
Move the cutoffs around a little.
Winnings2: Input score is in the range 0..10 inclusive.
Bonus! if score is 10 exactly, winnings is score * 15.
If score is between 4 and 9 inclusive, winnings is score * 12.
if score is 3 or less, winnings is score * 10.
Winnings2 Example
Now there's 3 cases; the cutoff numbers are different. Write a series of if-return to pick off the cases.
Winnings2: Input score is in the range 0..10 inclusive.
Bonus! if score is 10 exactly, winnings is score * 15.
If score is between 4 and 9 inclusive, winnings is score * 12.
if score is 3 or less, winnings is score * 10.
Solution:
def winnings2(score):
"""Compute winnings2 described above."""
if score == 10:
return score * 15
if score >= 4: # score <= 9 is implicit
return score * 12
# All score >= 4 cases have been picked off.
# so score < 4 here.
return score * 10
Example 3. Lottery Scratcher Example
An extra example for practice.
Lottery scratcher game: Have three icons called a, b, and c.
Each is in the range 0..10 inclusive.
If all three are the same, winnings is 100.
Otherwise if 2 are the same, winnings is 50.
Otherwise winnings is 0.
Use and/or/== to make the tests.
def scratcher(a, b, c):
"""Return scratcher winnings described above."""
pass
Solution:
def scratcher(a, b, c):
"""Return scratcher winnings described above."""
# 1. All 3 the same
if a == b and b == c:
return 100
# 2. Pair the same (3 same picked off above)
if a == b or b == c or a == c:
return 50
# 3. Run gets to here, nothing matched
return 0
Interpreter
- Python interpreter - runs the python code
- You can type at it directly - super handy
- Try out little ideas, see what they do
- Interpreter has
>>> prompt
- You type an expression
- It evaluates, prints result
- How to get the interpreter:
- 1. Use "console" tab in PyCharm lower left
- 2. Use "Interpreter" button at bottom of parlante.org pages
>>> 1 + 1 # you type this
2 # Python prints this
Strings
- Super common data type
- Sequence of 'characters' or 'chars'
- data e.g. urls, paragraphs
- In Python code a string "literal" is written on one line within single quote marks ' (prefer)
- Double quote also works "
'hello'
"hello"
len() function
- Returns number of chars in string
- Works on other collections too
- Not noun.verb style
>>> len('Hello')
5
>>> len('x')
1
>>> len('')
0
Empty String ''
- The "empty" string is just the string with 0 chars
- Written like: '' or ""
- This is a valid string, len 0
- A common case to think about with string algorithms
- Does the code need to work on the empty string?
- Probably yes.
Zero Based Indexing - Super Common
- Everything in computers uses this zero-based indexing scheme
- Characters in strings are "indexed" from 0
- e.g. 'Python'
Python
012345
- Index number addresses each char in the string
- Foreshadow: we'll use index numbers, [ ], and len()...
For many many linear type data arrangements
But for today strings
String Square Bracket Index
- Use square bracket to access a char by index number
- Valid index numbers: 0..len-1
- Get out of bounds error
>>> s = 'Python'
>>> s[0]
'P'
>>> s[1]
'y'
>>> s[4]
'o'
>>> s[5]
'n'
>>> s[6]
IndexError: string index out of range
String Immutable
- A string in memory is not editable
- "Immutable" is official the official term
- e.g. square bracket cannot change
>>> s = 'Python'
>>> s[0] # read ok
'P'
>>> s[0] = 'X' # write not ok
TypeError: 'str' object does not support item assignment
String +
- Plus operator
+ combines 2 strings to make a bigger string
aka "concatenate"
- Uses new memory
- Does not change original string
>>> a = 'Hello'
>>> b = 'there'
>>> a + b
'Hellothere'
>>> a
'Hello'
String + Add At End Pattern
- Use + to add at the end of a string, yielding a new bigger string
- Use like this to grow the string s:
s = s + 'xxx'
- The += operator works here too
- The individual strings are still immutable -
We are constructing a new, bigger string with each step
>>> a = 'Hi'
>>> a = a + '!'
>>> a
'Hi!'
>>> a = a + '!'
>>> a
'Hi!!'
>>> a = a + '!'
>>> a
'Hi!!!'
Loop Over All Chars in a String
- How to loop over all chars in string s
- Use index numbers: 0 .. len-1
- Use range function to make the numbers, 0, 1, 2, ... len(s)-1
- Typical to use "i" as variable in loop
for i in range(len(s)):
# access s[i] in here
Example 4, double_char
- Start result as empty string
- Loop over each char in string
- For each char: use + to add it at the end of the result
Solution code:
def doublechar(s):
"""Return doublechar as described above."""
result = ''
for i in range(len(s)):
result = result + s[i] + s[i]
return result