Fill This Form To Receive Instant Help
Homework answers / question archive / Python HW help MIDTERM - W200 Introduction to Data Science Programming, UC Berkeley MIDS Instructions Short Questions (15 pts) 1
MIDTERM - W200 Introduction to Data Science
Programming, UC Berkeley MIDS
Instructions
1.1. Python's dynamic typing allows one variable to refer to multiple types of objects within the same program execution. This can speed program development. Name one disadvantage of dynamic typing.
1.2. Compiled languages typically offer faster performance than interpreted languages. List two reasons why would you choose an interpreted language like Python for the purpose of analyzing a data set instead of a compiled language.
1.3. We have gone over FOR and WHILE loops. Discuss one reason to use a for loop over a while loop and one reason to use a while loop over a for loop. Please elaborate beyond a single word.
Your answer here
We have taught you a number of ways to program in Python. These have included using scripts versus functions and using Jupyter notebooks versus calling .py files from the command line. Describe a scenario in which you would use .py files from the command line over a Jupyter notebook and the opposite. Describe a scenario in which you would use a script versus a function and the opposite. There are four cases and each answer should be about 1-2 sentences, explain why!
2.1. I would use a Jupyter notebook:
Your answer here
2.2. I would use .py files over a Jupyter notebook:
Your answer here
2.3. I would use a script over a function:
Your answer here
2.4. I would use a function over a script:
Your answer here
Suppose we have the following problem. We have a dictionary of names and ages and we would like to find the oldest person.
ages_dict = {'Bill':34, 'Fred':45, 'Alice':14, 'Betty':17}
Here is a loop that shows how to iterate through the dictionary:
In |
[3]: |
Fred is the oldest. |
|
ages_dict |
|
= |
{ |
'Bill' |
: |
34 |
, |
'Fred' |
: |
45 |
, |
'Alice' |
: |
14 |
, |
'Betty' |
: |
17 |
} |
|
max_age |
|
= |
|
0 |
max_name |
|
= |
|
'' |
for |
|
name |
, |
age |
|
in |
|
ages_dict |
. |
items |
(): |
|
if |
|
age |
|
> |
|
max_age |
: |
|
max_age |
|
= |
|
age |
|
max_name |
|
= |
|
name |
|
|
( |
max_name |
, |
"is the oldest." |
) |
|
Your friend comes to you and thinks that this dictionary is difficult to deal with and instead offers a different plan using two lists.
names = ['Bill', 'Fred', 'Alice', 'Betty'] ages = [34, 45, 14, 17]
Instead of using a loop, your friend writes this code to find the oldest person.
In |
[4]: |
Fred is the oldest. |
|
names |
|
= |
[ |
'Bill' |
, |
'Fred' |
, |
'Alice' |
, |
'Betty' |
] |
ages |
|
= |
[ |
34 |
, |
45 |
, |
14 |
, |
17 |
] |
|
max_age |
|
= |
|
max |
( |
ages |
) |
index_max |
|
= |
|
ages |
. |
index |
( |
max_age |
) |
max_name |
|
= |
|
names |
[ |
index_max |
] |
|
|
( |
max_name |
, |
'is the oldest.' |
) |
Discuss the advantages and disadvantages of each of the approaches.
3.1. Is one more efficient (i.e. faster in Big O notation) than the other?
Your answer here
3.2. Why would you prefer the dictionary?
Your answer here
3.3. Why would you prefer the two lists?
Your answer here
4.1. In the asynchronous sessions, we discussed mutability. Please describe, in your own words, why mutability is a useful feature in Python lists and dictionaries.
Mutability can also lead to unexpected behavior - specifically when multiple variables point to the same object or when mutable objects are nested inside each other.
4.2. Please write some code demonstrating a situation where mutability could lead to unexpected behavior. Specifically, show how updating just one object (list_a) can change the value when you print a second variable (list_b).
In |
[1]: |
# Your code here |
4.3. Show how "copy" or "deepcopy" could be used to prevent the unexpected problem you described, above.
In |
[2]: |
# Your code here |
4.4. Now, show the same problem using two dictionaries. Again show how "copy" or "deepcopy" can fix the issue.
In |
[3]: |
# Your code here |
4.5. Can this unexpected behavior problem occur with tuples? Why, or why not?
Your answer here
A tweet is a string that is between 1 and 280 characters long (inclusive). A username is a string of letters and/or digits that is between 1 and 14 characters long (inclusive). A username is mentioned in a tweet by including @username in the tweet (notice the username does not include the @ symbol). A retweet is way to share another user's tweet, and can be identified by the string RT, followed by the original username who tweeted it.
Your job is to fill in the function count_retweets_by_username so that it returns a frequency dictionary that indicates how many times each retweeted username was retweeted.
In [1]: tweets = ["This is great! RT @fakeuser: Can you believe this?",
"It's the refs! RT @dubsfan: Boo the refs and stuff wargarbal",
"That's right RT @ladodgers: The dodgers are destined to win the w
"RT @sportball: That sporting event was not cool",
"This is just a tweet about things @person, how could you",
"RT @ladodgers: The season is looking great!",
"RT @dubsfan: I can't believe it!",
"I can't believe it either! RT @dubsfan: I can't believe it"]
In [2]: def count_retweets_by_username(tweet_list):
""" (list of tweets) -> dict of {username: int}
Returns a dictionary in which each key is a username that was retweeted in tweet_list and each value is the total number of times thi username was retweeted.
"""
# write code here and update return statement with your dictionary return {}
In [ ]: # allow this code to work by implementing count_retweets_by_username functi
print(count_retweets_by_username(tweets))
A mining company conducts a survey of an n-by-n square grid of land. Each row of land is numbered from 0 to n-1 where 0 is the top and n-1 is the bottom, and each column is also numbered from 0 to n-1 where 0 is the left and n-1 is the right. The company wishes to record which squares of this grid contain mineral deposits.
The company decides to use a list of tuples to store the location of each deposit. The first item in each tuple is the row of the deposit. The second item is the column. The third item is a nonnegative number representing the size of the deposit, in tons. For example, the following code defines a sample representation of a set of deposits in an 8-by-8 grid.
In [1]: deposits = [(0, 4, .3), (6, 2, 3), (3, 7, 2.2), (5, 5, .5), (3, 5, .8), (7,
6.1. Given a list of deposits like the one above, write a function to create a string representation for a rectangular sub-region of the land. Your function should take a list of deposits, then a set of parameters denoting the top, bottom, left, and right edges of the sub-grid. It should return (do not print in the function) a multi-line string in which grid squares without deposits are represented by "" and grid squares with a deposit are represented by "X".
In [5]: def display(deposits, top, bottom, left, right):
"""display a subgrid of the land, with rows starting at top and up to but not including bottom, and columns starting at left and up to but not including right."""
ans = "" # delete this line and enter your own code return ans
For example, your function should replicate the following behavior for the example grid:
print(display(deposits, 0, 8, 0, 8))
----X---
--------
--------
-----X-X
--------
-----X--
--X-----
-------X
print(display(deposits, 5, 8, 5, 8))
X--
---
--X
6.2. Next, complete the following function to compute the total number of tons in a rectangular sub-region of the grid.
In [ ]: def tons_inside(deposits, top, bottom, left, right):
"""Returns the total number of tons of deposits for which the row is at but strictly less than bottom, and the column is at least left, but str less than right."""
# Do not alter the function header.
# Just fill in the code so it returns the correct number of tons.
Suppose you record a list of birthdays for your classmates, recorded as month day tuples. An example is given below.
In [19]: # The 2nd to last tuple needs the int(2) in it so that it is uniquely store # Under the hood Python 3.7 changed how these are stored so (2,8) and (2,8)
# and then the algorithm below doesn't work
dates = [(3,14),(2,8),(10,25),(5,17),(3,2),(7,25),(4,30),(8,7),(int(2),8),(
You read about the famous birthday problem and you become interested in the number of pairs of classmates that share the same birthday. Below is an algorithm you write to do this. (Note: the is operator tests that two operands point to the same object)
In |
[20]: |
Total birthday pairs: 1 |
|
count |
|
= |
|
0 |
|
for |
|
person_a |
|
in |
|
dates |
: |
|
for |
|
person_b |
|
in |
|
dates |
: |
|
# Make sure we have different people |
|
|
if |
|
person_a |
|
is |
|
person_b |
: |
|
continue |
|
|
# Check both month and day |
|
if |
|
person_a |
[ |
0 |
] |
|
== |
|
person_b |
[ |
0 |
] |
|
and |
|
person_a |
[ |
1 |
] |
|
== |
|
person_b |
[ |
1 |
]: |
|
count |
|
+= |
|
1 |
|
# We counted each pair twice (e.g. jane-bob and bob-jane) so divide by 2: |
|
( |
"Total birthday pairs:" |
, |
count |
// |
2 |
) |
7.1. What is the (tightest) Big-O running time bound for the above algorithm? You may assume that simple operations like equality check, addition, and print take constant time.
7.2. You notice that your algorithm is inefficient in that it counts each pair twice. For example, it will
increment count once when person_a is Jane and person_b is Bob, and again when person_a is Bob and person_b is Jane. Below, revise the algorithm so that it only looks at each pair once.
In |
[ ]: |
# Your code here |
7.3. What is the (tightest) Big-O running time bound for your new algorithm? What does this tell you about whether your revision was worth making?
7.4. Finally, create a third revision of your algorithm which has a faster Big-O running time bound that both the previous algorithms.
In |
[5]: |
# Your code here |
7.5. What is the (tightest) Big-O running time bound for your last algorithm? Explain what trade-off you made to have a faster running time.