Today - black box examples, boolean logic, string intro, Doctests

Recall: "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.

function is black box with parameters in and result out

Strategic Story - Why Black Box?

For Divide and Conquer, want to be able to work on each function separately, one at a time. Need to keep the functions sealed off from each other for this to work - black box. We'll see how all this comes together later in the quarter.

"Cases" - Code Handles All Cases

Think of each input as a "case" the function must handle, return the correct output. To be correct, code needs to handle all the possible input cases. Hallmark of putting something on the computer: forces you to think through all the cases.

Boolean Values

For more detail, see guide Python Boolean

Ways to Get a Boolean

Try this in the interpreter..

>>> n = 5   # assign to n to start
>>> n == 6
False
>>> n == 5
True
>>> 
>>> n < 10
True
>>> n < 5  # < is strict
False
>>> 
>>> n <= 5  # less-or-equal
True
>>> 
>>> n > 0
True

Black Box Example Functions

(Trying some new tech here)

> "logic1" Black Box Functions

1. "Winnings1" Function

score winnings
0      0
1      10
2      20
3      30
4      40
5      60  # 12x kicks in here
6      72
7      84
8      96
9      108
10     120

Winnings1 code

Solution

def winnings1(score):
    if score >= 5:
        return score * 12
    
    # Run gets here: we know score < 5
    return score * 10

if-return Pick-Off Strategy

None Is The Default Function Result

2. Winnings2 Example

Extra practice example.

Say there are 3 cases, have a series of if-return to get them. Need to think about the order. Need to put the == 10 case early.

Winnings2: The int score number 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. Given int score, compute and return the winnings.

Solution

def winnings2(score):
    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

Boolean Operators: and or not

>>> n      # Start n as 5
5
>>> n < 10
True
>>> n > 7
False
>>> 
>>> n < 10 and n > 7  # Try and/or
False
>>> n < 10 or n > 7
True
>>> 
>>> n = 8   # Change n to 8, try again
>>> n < 10 or n > 7
True
>>> n < 10 and n > 7
True
>>> 
>>> n == 8
True
>>> n == 10
False
>>> n != 10  # not-equal
True

and Example

Suppose we have this code

if n > 0 and n < 10:
   # get here if test is True

Values of n where test is True: 1 5 9

Values of n where test is False: 10 12 -1

3. is_teen(n) Example

is_teen(n): Given an int n which is 0 or more. Return True if n is a "teenager", in the range 13..19 inclusive. Otherwise return False. Write a boolean test to pick off the teenager case.

Solution

def is_teen(n):
    # Use and to check
    if n >= 13 and n <= 19:
        return True
    return False
    # Future topic: possible to write this
    # as one-liner: return n >= 13 and n <= 19

4. Lottery Scratcher Example

An extra example for practice.

Lottery scratcher game: We have three icons called a, b, and c. Each is an int 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. Given a, b and c inputs, compute and return the winnings. Use and/or/== to make the tests.

Solution:

def scratcher(a, b, c):
    # 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


Strings

For more detail, see guide Python Strings

len() function

>>> len('Hello')
5
>>> len('x')
1
>>> len('')
0

Empty String ''

Zero Based Indexing - Super Common

alt: the string 'Python' with 6 index numbers 0..5

String Square Bracket Index

>>> s = 'Python'
>>> s[0]
'P'
>>> s[1]
'y'
>>> s[4]
'o'
>>> s[5]
'n'
>>> s[6]
IndexError: string index out of range

String Immutable

>>> s = 'Python'
>>> s[0]        # read ok
'P'
>>> s[0] = 'X'  # write not ok
TypeError: 'str' object does not support item assignment

String +

>>> a = 'Hello'
>>> b = 'there'
>>> a + b
'Hellothere'
>>> a
'Hello'

String + Add At End Pattern

>>> a = 'Hi'
>>> a = a + '!'
>>> a
'Hi!'
>>> a = a + '!'
>>> a
'Hi!!'
>>> a = a + '!'
>>> a
'Hi!!!'

for/i/range String Loop

# have string s
for i in range(len(s)):
    # access s[i] in here

String Example Functions

> "str2" String Functions

1. double_char

Solution code

def double_char(s):
    result = ''
    for i in range(len(s)):
        result = result + s[i] + s[i]
    return result

String Boolean Tests - True or False

String Testing == 'a' 'A'

We've used == already. 'a' and 'A' are different characters.

>>> s = 'red'
>>> s == 'red'   # two equal signs
True
>>> s == 'Red'   # must match exactly
False

String Testing - in

>>> 'c' in 'abcd'
True
>>> 'bc' in 'abcd'
True
>>> 'bx' in 'abcd'
False
>>> 'A' in 'abcd'
False

String Character Class Tests

s.isdigit() - True if all chars in s are digits '0' '1' .. '9'

s.isalpha() - True for alphabetic word char, i.e. a-z A-Z. Each unicode alphabet has its own definition of what's alphabetic, e.g. 'Ω' below is alphabetic.

s.isalnum() - alphanumeric, just combines isalpha() and isdigit()

s.isspace() - True for whitespace char, e.g. space, tab, newline

>>> 'a'.isalpha()
True
>>> 'abc'.isalpha()  # works for multiple chars too
True
>>> 'Z'.isalpha()
True
>>> '@'.isalpha()
False
>>> '9'.isdigit()
True
>>> ' '.isspace()
True

2. digits_only

Solution code

def digits_only(s):
    result = ''
    for i in range(len(s)):
        if s[i].isdigit():
            result += s[i]
    return result

if Variation: if / else

(probably not doing this today)
if test-expr:
  Lines-A
else:
  Lines-B

3. str_dx

Solution code

def str_dx(s):
    result = ''
    for i in range(len(s)):
        if s[i].isdigit():
            result += 'd'
        else:
            result += 'x'
    return result

Big Picture - Program, Functions, Testing

alt: program made of functions, each with tests

str1 project

Python Function - Pydoc

def digits_only(s):
    """
    Given a string s.
    Return a string made of all
    the chars in s which are digits,
    so 'Hi4!x3' returns '43'.
    Use a for/i/range loop.
    (this code is complete)
    >>> digits_only('Hi4!x3')
    '43'
    >>> digits_only('123')
    '123'
    >>> digits_only('')
    ''
    """
    result = ''
    for i in range(len(s)):
        if s[i].isdigit():
            result += s[i]
    return result

Python Function - Doctest

See lines like:

    >>> digits_only('Hi4!x3')
    '43'

You will learn and experiment with Doctests in section