Today: xxxx - bug and symptom. String - replace(), split(), join(), unicode. computer = CPU + RAM + Storage, CPU use, RAM use

Misc Loose Ends

1. Function Call - Parameters in Detail

(loose end from previous lecture)

How do function call parameters work? Most often, a function call works intuitively, so you don't have to think about it too much. BUT when pushed, you need to know how it works to avoid getting tripped up.

1. The variables and parameters in each function are independent, sealed off from those in other functions. An "x" in one function is totally independent of an "x" in some other function.

2. Function call: parameter values come in by position within the ( .. ) (not by name or anything else)

Function Call Example

Say we have a "foo" function with 2 parameters, and it is called by a "caller" function later. What does the run of caller() below print? This is very detail oriented, but mercifully there's just a few lines.

def foo(x, y):
    x = x - y
    return x + 1


def caller():
    x = 2
    y = 3
    z = foo(y, x)
    print(x, y, z)

Solution

printed line:
2 3 2

Values passed in to foo(x, y) are 3 and 2, value returned is 1
The "x" within foo() is independent of the "x" in caller()

foo() y = 13?

What if we said y = 13 up in foo()? Would that change the output? No. Each function has its own "y", that would just change the "y" variable that is inside foo().

2. Debug-Print .. demo

Debug technique #1 is look at "got", look at your code. Technique #2: add print(), shows up as additinal output alongside return value / got. Need to do demo on parlante.org .. let's use a reverse() problem.

reverse1: add in the loop: print('ch, ch, 'result', result)

This is a debugging technique only - need to take those print() statements out. Also remember that return is the real result of a function, such as for testing. The print() output is just this on the side text area.

> reverse() problems

String - More Functions

See guide for details: Python String

If a homework project needs one of these, the handout will mention it, so just showing these briefly so you see the idea.

String - replace()

>>> s ='this is it'
>>> s.replace('is', 'xxx')  # returns changed version
'thxxx xxx it'
>>> 
>>> s.replace('is', '')
'th  it'
>>> 
>>> s        # s not changed
'this is it'

Recall: s.foo() Does Not Change s

Recall how calling a string function does not change it. Need to use the return value...

# NO: Call without using result:
s.replace('is', 'xxx')
# s is the same as it was


# YES: this works
s = s.replace('is', 'xxx')

String - strip()

>>> s = '   this and that\n'
>>> s.strip()
'this and that'

String - split()

>>> s = '11,45,19.2,N'
>>> s.split(',')
['11', '45', '19.2', 'N']
>>> 'apple:banana:donut'.split(':')
['apple', 'banana', 'donut']
>>> 
>>> 'this    is     it  '.split()  # special space form
['this', 'is', 'it']

String - join()

>>> foods = ['apple', 'banana', 'donut']
>>> ':'.join(foods)
'apple:banana:donut'

String - format()

>>> 'Alice' + ' got score:' + str(12)  # old: use +
'Alice got score:12'
>>>
>>> '{} got score:{}'.format('Alice', 12) # new: format()
'Alice got score:12'
>>> 

String Unicode

(just quoting from Python String) In the early days of computers, the ASCII character encoding was very common, encoding the roman a-z alphabet. ASCII is simple, and requires just 1 byte to store 1 character, but it has no ability to represent characters of other languages.

Each character in a Python string is a unicode character, so characters for all languages are supported. Also, many emoji have been added to unicode as a sort of character.

Every unicode character is defined by a unicode "code point" which is basically a big int value that uniquely identifies that character. Unicode characters can be written using the "hex" version of their code point, e.g. "03A3" is the "Sigma" char Σ, and "2665" is the heart emoji char ♥.

Hexadecimal aside: hexadecimal is a way of writing an int in base-16 using the digits 0-9 plus the letters A-F, like this: 7F9A or 7f9a. Two hex digits together like 9A or FF represent the value stored in one byte, so hex is a traditional easy way to write out the value of a byte. When you look up an emoji on the web, typically you will see the code point written out in hex, like 1F644, the eye-roll emoji 🙄.

You can write a unicode char out in a Python string with a \u followed by the 4 hex digits of its code point. Notice how each unicode char is just one more character in the string:

>>> s = 'hi \u03A3'
>>> s
'hi Σ'
>>> len(s)
4
>>> s[0]
'h'
>>> s[3]
'Σ'
>>>
>>> s = '\u03A9'  # upper case omega
>>> s
'Ω'
>>> s.lower()     # compute lowercase
'ω'
>>> s.isalpha()   # isalpha() knows about unicode
True
>>>
>>> 'I \u2665'
'I ♥'

For a code point with more than 4-hex-digits, use \U (uppercase U) followed by 8 digits with leading 0's as needed, like the fire emoji 1F525, and the inevitable 1F4A9.

>>> 'the place is on \U0001F525'
'the place is on 🔥'
>>> s = 'oh \U0001F4A9'
>>> len(s)
4

Optional background material - skipping it today to catch up for Mon holiday

(optional) What is a Computer?

You have one on your person all day. You're debugging code for one. You see the output of them constantly. What is it and how does it work?

Step 1 - Why is it called Silicon Valley?

We'll look starting from the outside...

Computer - CPU, RAM, Storage

alt: computer is made of CPU, RAM, storage

Want to talk about running a computer program...

1. Running Program Gets its own RAM Area

alt:each running program gets its own area in RAM

2. Operating System (Terminal)

3. RAM = Code + Vars, CPU Runs the Code

alt:program RAM area stores both code and values

4. CPU - Cores


Python Shields us from Hardware Details - Great!

Python shields us from much detail about CPU and RAM, which is great. We're just peeking at the details here to get a little insight about what it means for a program to run, use CPU and RAM.

Hardware Demo Program

Nick's Hardware Squandering Program!

> hardware-demo.zip

Demo: computer is mostly idle to start. Idle CPU is cool. CPU starts running hard, generates heat .. fan spins! This program is an infinite loop - uses 100% of one core. Why is the fan running on my laptop? Use Activity Monitor (Mac), Task Manager (Windows) to see programs that are currently running, see CPU% and MEM%. Run program twice, once in each of 2 terminals - 200%

Core function of -cpu feature:

def use_cpu(n):
    """
    Infinite loop counting a variable 0, 1, 2...
    print a line every n (0 = no printing)
    """
    i = 0
    while True:
        if n != 0 and i % n == 0:
            print(i)
        i = i + 1

Try 1000 first ... woah! Try 1 million instead

$ python3 hardware-demo.py -cpu 1000000
0
1000000
2000000
3000000
4000000
5000000
6000000
7000000
^CTraceback (most recent call last):
  File "hardware-demo.py", line 66, in 
    main()
  File "hardware-demo.py", line 56, in main
    use_cpu(n)
  File "hardware-demo.py", line 24, in use_cpu
    i = i + 1
KeyboardInterrupt

(ctrl-c to exit)

Let's Talk About RAM

When code reads and writes values, those values are stored in RAM. RAM is a big array of bytes, read and written by the CPU.

Say we have this code

n = 10
s = 'Hello'
lst = [1, 2, 3]
lst2 = lst

Every value in use by the program takes up space in RAM.

alt:python values each taking space in RAM

RAM

Demo using -mem, Look in activity monitor, "mem" area, 100 = 100 MB per second. Watch our program use more and more memory of the machine. Program exits .. not in the list any more!

$ python3 hardware-demo.py -mem 100
Memory MB: 100
Memory MB: 200
Memory MB: 300
Memory MB: 400
Memory MB: 500
Memory MB: 600
Memory MB: 700
^CTraceback (most recent call last):
...
KeyboardInterrupt
(ctrl-c to exit)