McKinney Chapter 2 - Practice for Section 05

FINA 6333 for Spring 2024

Author

Richard Herron

1 Announcements

There are no due dates this week, but please take note of a few due dates next week:

  1. Before class on Tuesday, complete the week 2 pre-class quiz
  2. By Friday 1/19 at 11:59 PM:
    1. Acknowledge the academic integrity section of our syllabus
    2. Complete the first DataCamp course and upload your certificate

2 5-Minutes Recap

2.1 First, Python variables are references to objects.

a = [1, 2, 3]
a
[1, 2, 3]

Two (or more) variables can refer to the same object.

b = a
b
[1, 2, 3]

Remember, Python is zero-indexed!

b[0] = 2001
b
[2001, 2, 3]

So both variables reflect changes to the referenced object.

a
[2001, 2, 3]

We can also reassign a new object, which does not change the original object.

b = 'W.T. Door'
b
'W.T. Door'
a
[2001, 2, 3]

2.2 Second, we can define functions to re-use code

def square_root(x):
    return x ** 0.5
square_root(4)
2.0
square_root(9)
3.0

Note that white space is requried and not just cosmetic! Our square_root() function does not work without the white space!

# def square_root(x):
# return x ** 0.5
#   Cell In[26], line 2
#     return x ** 0.5
#     ^
# IndentationError: expected an indented block after function definition on line 1

2.3 Third, if-elif-else blocks let us conditionally run code blocks

Again, note the white space is required and not just cosmetic.

x = 5
if x < 0:
    print(f'{x} is negative')
elif x == 0:
    print(f'{x} is zero')
else:
    print(f'{x} is positive')
5 is positive

3 Practice

3.1 Extract the year, month, and day from an integer 8-digit date (i.e., YYYYMMDD format) using // (integer division) and % (modulo division).

Try 20080915.

1234 / 100
12.34
1234 // 100
12
1234 % 100
34
lb_collapse = 20080915
lb_collapse // 10_000
2008
lb_collapse % 10_000 // 100
9
lb_collapse % 100
15

3.2 Use your answer above to write a function date that accepts an integer 8-digit date argument and returns a tuple of the year, month, and date (e.g., return (year, month, date)).

def date(ymd):
    year = ymd // 10_000
    month = ymd % 10_000 // 100
    day = ymd % 100
    return (year, month, day)
date(lb_collapse)
(2008, 9, 15)
date(20240112)
(2024, 1, 12)

3.3 Rewrite date to accept an 8-digit date as an integer or string.

def date_2(ymd):
    if type(ymd) is str:
        ymd = int(ymd)
    year = ymd // 10_000
    month = ymd % 10_000 // 100
    day = ymd % 100
    return (year, month, day)
date_2('20090915')
(2009, 9, 15)

3.4 Finally, rewrite date to accept a list of 8-digit dates as integers or strings.

Return a list of tuples of year, month, and date.

ymds = [20080915, '20080916']
def date_3(ymds):
    dates = []
    for ymd in ymds:
        if type(ymd) is str:
            ymd = int(ymd)
        year = ymd // 10_000
        month = ymd % 10_000 // 100
        day = ymd % 100
        dates.append((year, month, day))
    return dates
date_3(ymds)
[(2008, 9, 15), (2008, 9, 16)]

3.5 Write a for loop that prints the squares of integers from 1 to 10.

for i in range(1, 11):
    print(i**2, end=' ')
1 4 9 16 25 36 49 64 81 100 

Above, I change the end argument to a space to shorten the output.

3.6 Write a for loop that prints the squares of even integers from 1 to 10.

for i in range(1, 11):
    if i % 2 == 0:
        print(i**2, end=' ')
4 16 36 64 100 

3.7 Write a for loop that sums the squares of integers from 1 to 10.

total = 0
for i in range(1, 11):
    total += i**2

total
385

3.8 Write a for loop that sums the squares of integers from 1 to 10 but stops before the sum exceeds 50.

total = 0
for i in range(1, 11):
    if (total + i**2) > 50:
        break
    total += i**2

total
30

3.9 FizzBuzz

Write a for loop that prints the numbers from 1 to 100. For multiples of three print “Fizz” instead of the number. For multiples of five print “Buzz”. For numbers that are multiples of both three and five print “FizzBuzz”. More here.

for i in range(1, 101):
    if (i%3 == 0) & (i%5 == 0):
        print('FizzBuzz', end=' ')
    elif i%3 == 0:
        print('Fizz', end=' ')
    elif i%5 == 0:
        print('Buzz', end=' ')
    else:
        print(i, end=' ')
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz 

3.10 Use ternary expressions to make your FizzBuzz code more compact.

for i in range(1, 101):
    print('Fizz'*(i%3==0) + 'Buzz'*(i%5==0) if (i%3==0) or (i%5==0) else i, end=' ')
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz 

The solution above is shorter and uses from neat tricks, but I consider the previous solution easier to read and troubleshoot. The solution above uses the trick that we can multiply a string by True or False to return the string itself or an empty string.

'Hey!'*True
'Hey!'
'Hey!'*False
''

3.11 Triangle

Write a function triangle that accepts a positive integer \(N\) and prints a numerical triangle of height \(N-1\). For example, triangle(N=6) should print:

1
22
333
4444
55555
def triangle(N):
    for i in range(1, N):
        print(str(i) * i)
triangle(6)
1
22
333
4444
55555

The solution above works because a multiplying a string by i concatenates i copies of the string.

'Test' + 'Test' + 'Test'
'TestTestTest'
'Test' * 3
'TestTestTest'

3.12 Two Sum

Write a function two_sum that does the following.

Given an array of integers nums and an integer target, return the indices of the two numbers that add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

Here are some examples:

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

Example 2:

Input: nums = [3,2,4], target = 6
Output: [1,2]

Example 3:

Input: nums = [3,3], target = 6
Output: [0,1]

I saw this question on LeetCode.

def two_sum(nums, target):
    for i in range(1, len(nums)):
        for j in range(i):
            if nums[i] + nums[j] == target:
                return [j, i]
two_sum(nums = [2,7,11,15], target = 9)
[0, 1]
two_sum(nums = [3,2,4], target = 6)
[1, 2]
two_sum(nums = [3,3], target = 6)
[0, 1]

We can write more efficient code once we learn other data structures in chapter 3 of McKinney!

3.13 Best Time

Write a function best_time that solves the following.

You are given an array prices where prices[i] is the price of a given stock on the \(i^{th}\) day.

You want to maximize your profit by choosing a single day to buy one stock and choosing a different day in the future to sell that stock.

Return the maximum profit you can achieve from this transaction. If you cannot achieve any profit, return 0.

Here are some examples:

Example 1:

Input: prices = [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. Note that buying on day 2 and selling on day 1 is not allowed because you must buy before you sell.

Example 2:

Input: prices = [7,6,4,3,1]
Output: 0
Explanation: In this case, no transactions are done and the max profit = 0.

I saw this question on LeetCode.

def max_profit(prices):
        min_price = prices[0]
        max_profit = 0
        for price in prices:
            min_price = price if price < min_price else min_price
            profit = price - min_price
            max_profit = profit if profit > max_profit else max_profit
        return max_profit
max_profit(prices=[7,1,5,3,6,4])
5
max_profit(prices=[7,6,4,3,1])
0