Processing math: 100%

CPSC150A
Scientific Computing

Activity 26

Lists

Add Ends

Write the function add_ends(a_list: [float]) -> float that computes the sum of the first and last elements of a list. The parameter a_list is a list of numbers with at least two elements. The function should return the sum of the first element and the last element from the list.

Test Cases

import test

def add_ends(a_list: [float]) -> float:
    # Put your code here

def main() -> None:
    test.equal(add_ends([1.0, 2.0, 3.0, 4.0]), 5.0)
    # Put more test cases here
    return None

main()

Create List

Write the function create_list(item1: int, item2: int, item3: int, item4: int, item5: int) -> [int] that returns a new list containing the five parameters where item1 is the first element, item2 is the second element, etc.

Test Cases

import test

def create_list(item1: int, item2: int, item3: int, item4: int, item5: int) -> [int]:
    # Put your code here

def main() -> None:
    test.equal(create_list(1, 2, 3, 4, 5), [1, 2, 3, 4, 5])
    # Put more test cases here
    return None

main()

Batting Average

The book, and later movie, Moneyball described how the use of statistics changed baseball. Using statistics like batting average can help mangagers make decisions. Batting average is the ratio of hits to at bats. Computing a player's batting average requires counting the different types of hits a player makes.

Details

Write the Python function batting_average(appearances: [int]) -> float that computes a player's batting average. The paramete appearances, is a list of integers that encodes the results of a baseball player's appearances at bat. Each appearance can be interpreted as follows:

4Home Run
3Triple
2Double
1Single
0Walk
-1Out

The function should return the batting average for the appearances in the list. The batting average can be computed using the following equations:

num_at_bats=num_appearancesnum_walksnum_hits=num_singles+num_doubles+num_triples+num_home_runsbatting_average=num_hits/num_at_bats

Test Cases

import test

def batting_average(appearances: [int]) -> float:
    # Put your code here

def main() -> None:
    test.equal(batting_average([1, 1, -1]), 0.6666666666)
    test.equal(batting_average([-1, 1, -1, -1, 1, -1, -1, 2, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 0, -1, 0, -1, -1, -1, 2, 1, -1, -1, -1, -1, 1, 0, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 0, -1, 1, 1, -1, -1, 2, 0, -1, -1, -1, -1, -1, -1, -1, 1, -1, 2, -1, -1, -1, -1, -1, -1, -1, 1]), 0.25396825396825395)
    return None

main()

To compute the batting average, the function needs to count the number of walks, singles, double, triples, and home runs. To do this, count the number of 0's, 1's, 2's, 3's, and 4's.

Challenge

Sabermetrics is the application of statistics to the management of baseball teams that was popularized with the book Moneyball. Sabermetric tries to improve upon the batting average metric by not just computing a batter's hits but by also incorporating a batter's contribution to the number of runs scored. Write the function runs_created(appearances: [int]) -> float that returns the Sabermetrics runs created statistic for the specified appearances list. The runs created stat can be computed with the following formulas:

total_bases=(num_singles)+(2num_doubles)+(3num_triples)+(4num_home_runs)runs_created=((num_hits+num_walks)(total_bases))/num_appearances

Birthday Paradox

Suppose someone comes into the class, and bets you $100 that some two people share a birthday within the individuals of the class. Do you share your birthday with anyone in the class? Is there a shared birthday between any two people in the class? It seems that the odds would be pretty slim. However, if you are putting up $100 on this bet, you might want to figure out your odds of winning this bet.

Details

Write the function shared_probability(group_size: int) -> float that computes the probability that two people in a group share a birthday. The parameter group_size is a positive integer that specifies the number of people in a group. The function should return a floating point value in the range [0, 1], the probability that there is a shared birthday in a group of size group_size. A probability of 0.0 means that there is a 0% chance and a probability of 1.0 means that there is a 100% chance. The function should not compute the exact probability, instead it should approximate the probability with repeated simulation.

To similate a group of people, create a list of group_size integers where each number represents a birthday. Ignoring leap years, there are 365 different birthdays, so the list should be filled with random numbers in the range [0, 364]. If there are any duplicate numbers in the list, then two people share a birthday.

To compute the probability, run the simulation *many* times. The more times it runs the more accurate it will be. The probability is the average number of times that there are two people that share a birthday.

Once you have written and tested the function, use it to answer the following questions:

  • What is the minimum group size that the probability exceeds 50%?
  • What is the minimum group size that there is a virtual guarantee (0.9999) there is a shared birthday?

Example

import test

def shared_probability(group_size: int) -> float:
    # Put your code here

def main() -> None:
    test.equal(shared_probability(1), 0.0)
    # Find the smallest group size with probablility over 0.5
    return None

main()

Functions are your friends. They make writing complex functions more simple by beaking it into more simple, easier to write functions. Here are some functions that would make writing the shared_probability function easier:

  • create_group(group_size: int) -> [int] - return a new list of group_size random integers in the range [0, 364]
  • are_duplicates(group: [int]) -> bool - return whether there are any elements of the list group that are identical.

With these two functions written -- don't forget to test them first -- the shared_probability function will repeatedly create a group, counting the number of times there are duplicate birthdays. The probability is the number of groups with a duplicate divided by the number of groups created.

Challenge

The above program assumes that birthdays are uniformly distributed: For a given person, their odds of being born on a particular date is the same for all dates. However, it is probably pretty obvious to you that this is not true in real life cases. In fact, you are much more likely to be born in the months July - October than any other month in the year.

How could you use the random number generator, which outputs numbers in a uniform distribution, to generate some skewed non-uniform random distribution? Try to redo your shared_probability function using this new, non-uniform distribution of birthdays. How do the results for the above questions change? Do they get higher, or lower? You may assume, for simplicity sakes, that all months have 30 days for this challenge portion.