Today: xxxxxxx midterm prep, Doctests, exponentiation, modulus, num-histogram example

No new material shown today is on the midterm - the midterm is about topics on HW5, but we will do an additional HW5 dict example today.

Computer Science - Glimpsed in HWs

Big Picture - 3x Goals

Three priorities for a computer project.

Goal #1 - Correct

Goal #2 - Good

Goal #3 - Fast


Today - Better / Cleaner / Shorter

Today, I'll show you some techniques where we have code that is already correct, but we can write it in a better, cleaner way. It's intuitively satisfying to have a 10 line thing, and shrink it down to 6 lines that reads better.

Already talked about Decomp-By-Var, which is in the same family of techniques - replace working code with a version that reads better.

Technique: Build on Idiomatic Phrases

You can think of every program as having some phrases of stock, idiomatic code, and then some phrases that are custom, idiosyncratic bits particular to that algorithm. We'll just say, use the idiomatic bits where they come up — easy to type in, easy to understand. Build your needed changes around the idiomatic code. The first 3 solutions above work in this way. The last, reverse5, is the opposite - manually build it vs. building on the capability of range().

The reverse() Rosetta Stone

Would that be "attesor"?

How many ways can you think of to reverse a string in Python?

'Hello' -> 'olleH'

Here are challenges for 5 different ways, each using different parts of Python. Each problem problem says "use xxx" to direct which language feature to use.

Aside: there is a scene in the Movie Amadeus where Motzart plays a piece one way, then gets under the piano, reaches hands up and plays it again upside down. I believe today this would be called a "flex"? youtube

The first two versions are the best. The are the best because they leverage foreach or for/i/range to hit all the chars, solving the problem without any error prone, manual index computation.

> reverse() problems

Work out the code for the first 2 or 3.

Fine: use the stock for/i/range(), compute needed rev_i from that (reverse3)

Not as good: compute rev_i manually, not leveraging the idiomatic for/i/range (reverse4 and reverse5)


Technique: Better Code with Invariant Lines

> better - invariant problems

speeding() Example

speeding(speed, birthday): Compute speeding ticket fine as function of speed and birthday boolean. Rule: speed under 55, fine is 100, otherwise 200. If it's your birthday, the allowed speed is 5 mph more. Challenge: change this code to be shorter, not have so many distinct paths.

The code below works correctly. How to write it better?

def speeding(speed, birthday):
    if not birthday:
        if speed < 50:
            return 100
        else:
            return 200
    else:  # is birthday
        if speed < 55:
            return 100
        else:
            return 200

Invariant Var Solution

speeding() Better Solution

def speeding(speed, birthday):
    # Setup limit var
    limit = 50
    if birthday:
        limit = 55
    
    # Invariant: limit holds value to use
    if speed < limit:
        return 100
    return 200

ncopies() Exercise

Change this code to be better / shorter. Look at lines that are similar - make an invariant.

ncopies(word, n, suffix): Given name string, int n, suffix string, return n copies of string + suffix. If suffix is the empty string, use '!' as the suffix. Challenge: change this code to be shorter, not have so many distinct paths.

Before:

def copies(word, n, suffix):
    result = ''
    
    if suffix == '':
        for i in range(n):
            result += word + '!'
    else:
        for i in range(n):
            result += word + suffix
    return result

ncopies() Better Solution

Solution: use logic to set "suffix" to hold the suffix to use for all cases. Later code just uses suffix vs. separate if-stmt for each case.

def copies(word, n, suffix):
    result = ''
    # Set suffix to be value to use regardless
    if suffix == '':
        suffix = '!'
 
    # invariant: suffix is value to use
    for i in range(n):
        result += word + suffix
    return result

Bits and Bytes

At the smallest scale in the computer, information is stored as bits and bytes. In this section, we'll look at how that works.

Bit

Byte

How Many Patterns With N Bits? (demo)

How many different patterns can be made with 1, 2, or 3 bits?

Number of bits Different Patterns
1 0 1
2 00 01 10 11
3 000 001 010 011
100 101 110 111
Number of bits Different Patterns
1 0 1
2 00 01 10 11
3 000 001 010 011
100 101 110 111

One Byte - 256 Patterns

"HDR" Image