diff --git a/_internal/targets.json b/_internal/targets.json index 383081c9ea..bed75c86b2 100644 --- a/_internal/targets.json +++ b/_internal/targets.json @@ -1 +1 @@ -[{"due": "9/18/24", "link": "hw/hw02/", "name": "HW 02: Control", "piazza_name": "HW 02", "release": "9/11/24"}] +[{"due": "9/18/24", "link": "hw/hw02/", "name": "HW 02: Control", "piazza_name": "HW 02", "release": "9/11/24"}, {"due": "9/20/24", "link": "lab/lab03/", "name": "Lab 03: Higher-Order Functions", "piazza_name": "Lab 03", "release": "9/16/24"}] diff --git a/disc/disc03/index.html b/disc/disc03/index.html index f02e5e6f72..b138a0cb74 100644 --- a/disc/disc03/index.html +++ b/disc/disc03/index.html @@ -163,7 +163,7 @@

Now switch to Pensieve:

Once you're on Pensieve, you don't need to return to this page; Pensieve has all the same content (but more features). If for some reason Penseive doesn't work, return to this page and continue with the discussion.

@@ -314,7 +314,7 @@

Q2: Match Maker

Document the occasion

-

Please all fill out the attendance form (one submission per person per week).

+

Please all fill out the attendance form (one submission per person per week).

+ + + + + + + + + + + + + + + + + + +Discussion 0 | Data C88C Fall 2024 + + + + + + +
+ +
+
+
+

+ +Discussion 0: Getting Started + + + + + + +

+
+ + + + + + +

Congratulations, you found the Discussion 0 worksheet!

+ +

To find your discussion room, check your email. Unless you opted for the mega section, you should have received an email with your discussion group number, location, and time. All discussion groups meet in person. There are multiple groups at a time in each discussion room, so when you arrive, find your group.

+ +

Please start on Berkeley time, 10 minutes after the scheduled start time (12:40, 2:10, or 3:40). Feel free to introduce yourself to the rest of your group while you wait (and check that they really have the same group number as you do).

+ +

If you need help at any time and there's no TA in the room, join this Zoom and talk to the TA there. If you're in the waiting room, that means they are talking to another group, and they'll let you in once that's done.

+ + +

Part 0: Meet your group and learn their names [5 minutes]

+ + +

Order yourselves by birthday: January 1 at the start and December 31 at the end. Then, on your turn, say your name and where you're from, then say the same information for each person who had a turn already, starting from the most recent turn. For example, the intros might go:

+ +
    +
  • Eva: I'm Eva from Minneapolis
  • +
  • Lem: I'm Lem from San Diego, and [turning to Eva] you're Eva from Minneapolis
  • +
  • Alyssa: I'm Alyssa from Sacramento, [turning to Lem] you're Lem from San Diego, and [turning to Eva] you're Eva from Minneapolis.
  • +
+ +

If you forget someone's name or where they're from, that's fine; everybody is here to learn. When it's someone's turn, give them time to try themselves, but if they need help, offer it.

+ +

Tip: Now is a great time to write down the names of the people in your group so that you can look them up later.

+ + +

Part 1: Learn about each other [30 minutes]

+ + +

Here's a game called partitions. Each round, you will split your group into two halves with equal numbers of people (or differing by 1 if there are an odd number of people). The goal is for both groups to find a rare fact that all of their members have in common, that no one in the other group also has in common. For example, Group A may find that they are all left-handed, while Group B may find that they all collect Pokémon cards. For each round follow these steps:

+ +
    +
  • Step 1: Split into two equal halves (or differing by 1).
  • +
  • Step 2: The two groups separate for 10 minutes to talk and find some rare fact about them that they all share.
  • +
  • Step 3: After 10 minutes, regroup and have each group give their shared fact. If no one in the opposing group has that fact in common as well, then everyone in your group scores a point. (So in the above example, if Group A’s fact is that they’re all left-handed, and no one in Group B is left-handed, everyone in Group A scores a point.)
  • +
+ +

Play for 2 rounds using 2 different ways of splitting your group into halves.

+ +

Important: The facts you choose cannot be determined by sight (such as height or hair color). They also cannot be based on preferences (such as favorite TV show). Some ideas:

+ +
    +
  • Places you've been: Paris, Disneyland, In-N-Out
  • +
  • Things you've tried: zip-lining, meditation, fishing
  • +
  • Stuff you can do: ski, crochet, juggle, recite digits of pi
  • +
+ +

When you're done, it's time for the final challenge! Find a fact that's true about all of you but you don't think is true of your TA. When you're ready, check with your TA (in person or on Zoom) to see if you succeeded.

+ + +

Part 2: Solve a problem together [30 minutes]

+ + +

Imagine you can call only the following three functions:

+ +
    +
  • f(x): Subtracts one from an integer x
  • +
  • g(x): Doubles an integer x
  • +
  • h(x, y): Concatenates the digits of two different positive integers x and y. For example, h(789, 12) evaluates to 78912 and h(12, 789) evaluates to 12789.
  • +
+ +

Definition: A small expression is a call expression that contains only f, g, h, the number 5, and parentheses. All of these can be repeated. For example, h(g(5), f(f(5))) is a small expression that evaluates to 103.

+ +

What's the shortest small expression you can find that evaluates to 2024?

+ + +

Part 3: Document the occasion [5 minutes]

+ + +

Take a group selfie and share it around. You'll be glad you did at the end of the semester.

+ +

Then, please all fill out the attendance form (one submission per person per week).

+ +

You're done! If you have extra time, discuss how you might use a computer to find the shortest possible small expression that evaluates to 2024. We'll talk about this in Lecture 2.

+ + +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/disc/sol-disc01/index.html b/disc/sol-disc01/index.html new file mode 100644 index 0000000000..c66f8af04e --- /dev/null +++ b/disc/sol-disc01/index.html @@ -0,0 +1,488 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Discussion 1 | Data C88C Fall 2024 + + + + + + +
+ +
+
+
+

+ +Discussion 1: Functions + + + + + + +

+
+ + + + + + +

Find your group, and then get started on this worksheet once the TA tells you +to. It's best if everyone has a way to view this worksheet (on your phone/tablet +is fine, but a laptop is better).

+ +

Now switch to Pensieve, a shared editing app that has this same worksheet in a format that makes it easy to collaborate with your group and ask questions of an AI tutor.

+ +
    +
  • Everyone: Go to pensieve.co, log in with your @berkeley.edu email, and enter your group number as the room number (which was in the email that assigned you to this lab).
  • +
+ +

Once you're on Pensieve, you don't need to return to this page; Pensieve has all the same content (but more features). If for some reason Penseive doesn't work, return to this page and continue with the discussion.

+ + +

Ice Breaker

+ + +

Everyone say your name and some activity you enjoy doing outside. For each +activity, ask if anyone else in your group likes to do that too. (Optional: +After lab you're welcome to make plans to go do one of these activities +together.)

+ +

Then, each person share an expression that people say when they really like +something, such as "that's awesome" or "nice one" or "bruh." Each person should +try to come up with a different expression. Feel free to ask your group for help +if you're stuck. You can even use other languages than English. Then, during the +discussion, if someone says or does something well, use your expression!

+ + +

Functions

+ + +

Functions (such as pow) are called using call expressions (such as pow(10, 3) which returns 1000; 10 to the third power). The body of a function can print or return values (or both).

+ +
    +
  • When print is called anywhere, its arguments are displayed right away.
  • +
  • Executing a return statement stops the function call and provides the value for its call expression.
  • +
  • When the end of a function body is reached without a return, the function + returns None.
  • +
+ +

Tip: If a value needs to be used by code outside of a function, then return the value (instead of printing it).

+ + +

Q1: Multiply

+ + +

Implement multiply, which takes two numbers x and y. It prints out an +equation showing the result of multiplying x and y, then returns the result.

+ +

Try to multiply numbers together just once in the body of multiply so that the +Python interpreter doesn't have to perform multiplication more times than +necessary (pun intended).

+ + + + Your Answer + +
+ Run in 61A Code + +
+ + +
+ Solution + +
def multiply(x, y):
+    """Multiply x by y and print what happened.
+
+    >>> multiply(3, multiply(multiply(4, 5), 6))
+    4 * 5 = 20
+    20 * 6 = 120
+    3 * 120 = 360
+    360
+    """
+    z = x * y
+    print(x, '*', y, '=', z)
+    return z
+
+ +
+ + + + +
+Calling print on multiple arguments displays those values separated by spaces. +For example, the call expression print(1, '+', 2, '=', 3) displays 1 + 2 = 3. +
+ + +

Digits

+ + +

Each digit of a positive integer corresponds to a power of 10. Here are some +examples of manipulating digits, illustrated with n = 357 and d = 9.

+ +
    +
  • Remove the last digit of n: n // 10 is 35.
  • +
  • Remove the last two digits of n: n // pow(10, 2) is 3.
  • +
  • Add together the last two digits of n: n % 10 + n // 10 % 10 is 12.
  • +
  • Put digit d at the end of integer n: n * 10 + d is 3579.
  • +
+ + +

Q2: Cut One Out

+ + +

Implement cut, which takes non-negative integers n and k and has only a +return statement in its body. It returns a positive integer with all of the +digits of n except the digit that is k to the left of the rightmost digit +(the one's digit). If k is 0, then it returns n without its one's digit. +If there is no digit k to the right of the one's digit, then it returns n.

+ + + + Your Answer + +
+ Run in 61A Code + +
+ + +
+ Solution + +
def cut(n, k):
+    """Return n with the kth digit from the right removed.
+
+    >>> cut(3579, 2)
+    379
+    >>> cut(3579, 0)
+    357
+    >>> cut(3579, 1)
+    359
+    >>> cut(3579, 5)
+    3579
+    """
+    return n // pow(10, k + 1) * pow(10, k) + n % pow(10, k)
+
+ +
+ + +

Please don't look at the hint until everyone in your group agrees that you're stuck and +need some extra help.

+ + + +
+ +

To implement a function, it can be helpful to open a Python interpreter and +focus on an example. Here are all the pieces you need to put together to solve +this problem for the example n=3579 and k=2.

+ +
>>> n = 3579
+>>> k = 2
+>>> pow(10, k)
+100
+>>> pow(10, k + 1)
+1000
+>>> n // 1000
+3
+>>> 3 * 100
+300
+>>> 3579 % 100
+79
+>>> 300 + 79
+379
+ + +
+ + +

Document the Occasion

+ + +

Please all fill out the attendance form (one submission per person per week). Then, you can work on Lab 0 and Lab 1. It's usually best to work on lab assignments in pairs, but you can form larger groups if that is helpful.

+ + +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/disc/sol-disc02/index.html b/disc/sol-disc02/index.html new file mode 100644 index 0000000000..cd95af4e9a --- /dev/null +++ b/disc/sol-disc02/index.html @@ -0,0 +1,644 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Discussion 2 | Data C88C Fall 2024 + + + + + + +
+ +
+
+
+

+ +Discussion 2: Control, Environment Diagrams + + + + + + +

+
+ + + + + + +

If your group has fewer than 3 people, feel free to merge with another group in the room.

+ +

Now switch to Pensieve, a shared editing app that has this same worksheet in a format that makes it easy to collaborate with your group and ask questions of an AI tutor.

+ +
    +
  • Everyone: Go to pensieve.co, log in with your @berkeley.edu email, and enter your group number as the room number (which was in the email that assigned you to this lab).
  • +
+ +

Once you're on Pensieve, you don't need to return to this page; Pensieve has all the same content (but more features). If for some reason Penseive doesn't work, return to this page and continue with the discussion.

+ + +

Ice Breaker

+ + +

Say your name and a city (or place) that you like, which is not Berkeley and is +not where you have lived. Feel free to share why you like it.

+ + +

While and If

+ + +

Learning to use if and while is an essential skill. During this discussion, +focus on what we've studied in the first three lectures: if, while, +assignment (=), comparison (<, >, ==, ...), and arithmetic. Please don't +use features of Python that we haven't discussed in class yet, such as for, +range, and lists. We'll have plenty of time for those later in the course, but +now is the time to practice the use of if (textbook section +1.5.4) +and while (textbook section +1.5.5).

+ + +

Q1: Fizzbuzz

+ + +

Implement the classic Fizz Buzz +sequence. The fizzbuzz function +takes a positive integer n and prints out a single line for each integer +from 1 to n. For each i:

+ +
    +
  • If i is divisible by both 3 and 5, print fizzbuzz.
  • +
  • If i is divisible by 3 (but not 5), print fizz.
  • +
  • If i is divisible by 5 (but not 3), print buzz.
  • +
  • Otherwise, print the number i.
  • +
+ +

Try to make your implementation of fizzbuzz concise.

+ + + + Your Answer + +
+ Run in 61A Code + +
+ + +
+ Solution + +
def fizzbuzz(n):
+    """
+    >>> result = fizzbuzz(16)
+    1
+    2
+    fizz
+    4
+    buzz
+    fizz
+    7
+    8
+    fizz
+    buzz
+    11
+    fizz
+    13
+    14
+    fizzbuzz
+    16
+    >>> print(result)
+    None
+    """
+    i = 1
+    while i <= n:
+        if i % 3 == 0 and i % 5 == 0:
+            print('fizzbuzz')
+        elif i % 3 == 0:
+            print('fizz')
+        elif i % 5 == 0:
+            print('buzz')
+        else:
+            print(i)
+        i += 1
+
+ +
+ + + + +
+Be careful about the order of your if and elif clauses: try first checking if the current number is divisible by both 3 and 5, then check for just divisibility by 3 and just divisibility by 5. +
+ + + +
+ + +

Problem Solving

+ + +

A useful approach to implementing a function is to:

+ +
    +
  1. Pick an example input and corresponding output.
  2. +
  3. Describe a process (in English) that computes the output from the input using simple steps.
  4. +
  5. Figure out what additional names you'll need to carry out this process.
  6. +
  7. Implement the process in code using those additional names.
  8. +
  9. Determine whether the implementation really works on your original example.
  10. +
  11. Determine whether the implementation really works on other examples. (If not, you might need to revise step 2.)
  12. +
+ +

Importantly, this approach doesn't go straight from reading a question to writing code.

+ +

For example, in the is_prime problem below, you could:

+ +
    +
  1. Pick n is 9 as the input and False as the output.
  2. +
  3. Here's a process: Check that 9 (n) is not a multiple of any integers between 1 and 9 (n).
  4. +
  5. Introduce i to represent each number between 1 and 9 (n).
  6. +
  7. Implement is_prime (you get to do this part with your group).
  8. +
  9. Check that is_prime(9) will return False by thinking through the execution of the code.
  10. +
  11. Check that is_prime(3) will return True and is_prime(1) will return False.
  12. +
+ +

Try this approach together on the next two problems.

+ +

Important: It's highly recommended that you don't check your work using +a computer right away. Instead, talk to your group and think to try to figure +out if an answer is correct. On exams, you won't be able to guess and check +because you won't have a Python interpreter. Now is a great time to practice +checking your work by thinking through examples. You could even draw an +environment diagram!

+ +

If you're not sure about how something works or get stuck, ask for help from the course staff.

+ + +

Q2: Is Prime?

+ + +

Write a function that returns True if a positive integer n is a prime +number and False otherwise.

+ +

A prime number n is a number that is not divisible by any numbers other than +1 and n itself. For example, 13 is prime, since it is only divisible by 1 and +13, but 14 is not, since it is divisible by 1, 2, 7, and 14.

+ +

Use the % operator: x % y returns the remainder of x when divided by y.

+ + + +
+Here's a while statement that goes through all numbers above 1 and below n : + +
i = 2
+while i < n:
+    ...
+    i = i + 1
+ + + +

You can use n % i == 0 to check whether i is a factor of n. If it is, return False. +

+ + + + Your Answer + +
+ Run in 61A Code + +
+ + +
+ Solution + +
def is_prime(n):
+    """
+    >>> is_prime(10)
+    False
+    >>> is_prime(7)
+    True
+    >>> is_prime(1) # one is not a prime number!!
+    False
+    """
+    if n == 1:
+        return False
+    k = 2
+    while k < n:
+        if n % k == 0:
+            return False
+        k += 1
+    return True
+
+ +
+ + + + +
+ + +

Q3: Unique Digits

+ + +

Write a function that returns the number of unique digits in a positive integer.

+ +

Hints: You can use // and % to separate a positive integer into +its one's digit and the rest of its digits.

+ +

You may find it helpful to first define a function +has_digit(n, k), which determines whether a number n has digit k.

+ + + + Your Answer + +
+ Run in 61A Code + +
+ + +
+ Solution + +
def unique_digits(n):
+    """Return the number of unique digits in positive integer n.
+
+    >>> unique_digits(8675309) # All are unique
+    7
+    >>> unique_digits(13173131) # 1, 3, and 7
+    3
+    >>> unique_digits(101) # 0 and 1
+    2
+    """
+    unique = 0
+    while n > 0:
+        last = n % 10
+        n = n // 10
+        if not has_digit(n, last):
+            unique += 1
+    return unique
+
+# Alternate solution
+def unique_digits_alt(n):
+    unique = 0
+    i = 0
+    while i < 10:
+        if has_digit(n, i):
+            unique += 1
+        i += 1
+    return unique
+
+def has_digit(n, k):
+    """Returns whether k is a digit in n.
+
+    >>> has_digit(10, 1)
+    True
+    >>> has_digit(12, 7)
+    False
+    """
+    assert k >= 0 and k < 10
+    while n > 0:
+        last = n % 10
+        n = n // 10
+        if last == k:
+            return True
+    return False
+
+ +
+ + + + +
+One approach is to loop through every digit from 0 to 9 and check whether n has the digit. Count up the ones it has. +
+ +
+ +

We have provided two solutions:

+ +
    +
  • In one solution, we look at the current digit, and check if the rest of the + number contains that digit or not. We only say it's unique if the digit + doesn't exist in the rest. We do this for every digit.
  • +
  • In the other, we loop through the numbers 0-9 and just call has_digit on + each one. If it returns true then we know the entire number contains that + digit and we can one to our unique count.
  • +
+ +
+ +
+ + +

Document the occasion

+ + +

Please all fill out the attendance form (one submission per person per week).

+ + +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hw/sol-hw01/construct_check.py b/hw/sol-hw01/construct_check.py new file mode 100644 index 0000000000..bee096e7e4 --- /dev/null +++ b/hw/sol-hw01/construct_check.py @@ -0,0 +1,180 @@ +from ast import parse, NodeVisitor, Name + +# For error messages (student-facing) only +_NAMES = { + 'Add': '+', + 'And': 'and', + 'Assert': 'assert', + 'Assign': '=', + 'AnnAssign': '=', + 'AugAssign': 'op=', + 'BitAnd': '&', + 'BitOr': '|', + 'BitXor': '^', + 'Break': 'break', + 'Recursion': 'recursive call', + 'ClassDef': 'class', + 'Continue': 'continue', + 'Del': 'del', + 'Delete': 'delete', + 'Dict': '{...}', + 'DictComp': '{...}', + 'Div': '/', + 'Ellipsis': '...', + 'Eq': '==', + 'ExceptHandler': 'except', + 'ExtSlice': '[::]', + 'FloorDiv': '//', + 'For': 'for', + 'FunctionDef': 'def', + 'Filter': 'filter', + 'GeneratorExp': '(... for ...)', + 'Global': 'global', + 'Gt': '>', + 'GtE': '>=', + 'If': 'if', + 'IfExp': '...if...else...', + 'Import': 'import', + 'ImportFrom': 'from ... import ...', + 'In': 'in', + 'Index': '...[...]', + 'Invert': '~', + 'Is': 'is', + 'IsNot': 'is not ', + 'LShift': '<<', + 'Lambda': 'lambda', + 'List': '[...]', + 'ListComp': '[...for...]', + 'Lt': '<', + 'LtE': '<=', + 'Mod': '%', + 'Mult': '*', + 'NamedExpr': ':=', + 'Nonlocal': 'nonlocal', + 'Not': 'not', + 'NotEq': '!=', + 'NotIn': 'not in', + 'Or': 'or', + 'Pass': 'pass', + 'Pow': '**', + 'RShift': '>>', + 'Raise': 'raise', + 'Return': 'return', + 'Set': '{ ... } (set)', + 'SetComp': '{ ... for ... } (set)', + 'Slice': '[ : ]', + 'Starred': '', + 'Str': 'str', + 'Sub': '-', + 'Subscript': '[]', + 'Try': 'try', + 'Tuple': '(... , ... )', + 'UAdd': '+', + 'USub': '-', + 'While': 'while', + 'With': 'with', + 'Yield': 'yield', + 'YieldFrom': 'yield from', +} + +def check(source_file, checked_funcs, disallow, source=None): + """Checks that AST nodes whose type names are present in DISALLOW + (an object supporting 'in') are not present in the function(s) named + CHECKED_FUNCS in SOURCE. By default, SOURCE is the contents of the + file SOURCE_FILE. CHECKED_FUNCS is either a string (indicating a single + name) or an object of some other type that supports 'in'. CHECKED_FUNCS + may contain __main__ to indicate an entire module. Prints reports of + each prohibited node and returns True iff none are found. + See ast.__dir__() for AST type names. The special node name 'Recursion' + checks for overtly recursive calls (i.e., calls of the form NAME(...) where + NAME is an enclosing def.""" + return ExclusionChecker(disallow).check(source_file, checked_funcs, source) + +class ExclusionChecker(NodeVisitor): + """An AST visitor that checks that certain constructs are excluded from + parts of a program. ExclusionChecker(EXC) checks that AST node types + whose names are in the sequence or set EXC are not present. Its check + method visits nodes in a given function of a source file checking that the + indicated node types are not used.""" + + def __init__(self, disallow=()): + """DISALLOW is the initial default list of disallowed + node-type names.""" + self._disallow = set(disallow) + self._checking = False + self._errs = 0 + + def generic_visit(self, node): + if self._checking and type(node).__name__ in self._disallow: + self._report(node) + super().generic_visit(node) + + def visit_Module(self, node): + if "__main__" in self._checked_funcs: + self._checking = True + self._checked_name = self._source_file + super().generic_visit(node) + + def visit_Call(self, node): + if 'Recursion' in self._disallow and \ + type(node.func) is Name and \ + node.func.id in self._func_nest: + self._report(node, "should not be recursive") + self.generic_visit(node) + + def visit_FunctionDef(self, node): + self._func_nest.append(node.name) + if self._checking: + self.generic_visit(node) + elif node.name in self._checked_funcs: + self._checked_name = "Function " + node.name + checking0 = self._checking + self._checking = True + super().generic_visit(node) + self._checking = checking0 + self._func_nest.pop() + + def _report(self, node, msg=None): + node_name = _NAMES.get(type(node).__name__, type(node).__name__) + if msg is None: + msg = "should not contain '{}'".format(node_name) + print("{} {}".format(self._checked_name, msg)) + self._errs += 1 + + def errors(self): + """Returns the number of number of prohibited constructs found in + the last call to check.""" + return self._errs + + def check(self, source_file, checked_funcs, disallow=None, source=None): + """Checks that AST nodes whose type names are present in DISALLOW + (an object supporting the contains test) are not present in + the function(s) named CHECKED_FUNCS in SOURCE. By default, SOURCE + is the contents of the file SOURCE_FILE. DISALLOW defaults to the + argument given to the constructor (and resets that value if it is + present). CHECKED_FUNCS is either a string (indicating a single + name) or an object of some other type that supports 'in'. + CHECKED_FUNCS may contain __main__ to indicate an entire module. + Prints reports of each prohibited node and returns True iff none + are found. + See ast.__dir__() for AST type names. The special node name + 'Recursion' checks for overtly recursive calls (i.e., calls of the + form NAME(...) where NAME is an enclosing def.""" + + self._checking = False + self._source_file = source_file + self._func_nest = [] + if type(checked_funcs) is str: + self._checked_funcs = { checked_funcs } + else: + self._checked_funcs = set(checked_funcs) + if disallow is not None: + self._disallow = set(disallow) + if source is None: + with open(source_file, 'r', errors='ignore') as inp: + source = inp.read() + p = parse(source, source_file) + self._errs = 0 + + self.visit(p) + return self._errs == 0 \ No newline at end of file diff --git a/hw/sol-hw01/hw01.ok b/hw/sol-hw01/hw01.ok new file mode 100644 index 0000000000..1e2bd044c5 --- /dev/null +++ b/hw/sol-hw01/hw01.ok @@ -0,0 +1,24 @@ +{ + "name": "Homework 1", + "endpoint": "cal/c88c/fa24/hw01", + "src": [ + "hw01.py" + ], + "tests": { + "hw*.py": "doctest", + "tests/*.py": "ok_test" + }, + "default_tests": [ + "a_plus_abs_b", + "a_plus_abs_b_syntax_check", + "two_of_three", + "two_of_three_syntax_check" + ], + "protocols": [ + "file_contents", + "grading", + "analytics", + "help", + "backup" + ] +} \ No newline at end of file diff --git a/hw/sol-hw01/hw01.py b/hw/sol-hw01/hw01.py new file mode 100644 index 0000000000..eaa5aa5802 --- /dev/null +++ b/hw/sol-hw01/hw01.py @@ -0,0 +1,59 @@ +from operator import add, sub + +def a_plus_abs_b(a, b): + """Return a+abs(b), but without calling abs. + + >>> a_plus_abs_b(2, 3) + 5 + >>> a_plus_abs_b(2, -3) + 5 + >>> a_plus_abs_b(-1, 4) + 3 + >>> a_plus_abs_b(-1, -4) + 3 + """ + if b < 0: + f = sub + else: + f = add + return f(a, b) + +def a_plus_abs_b_syntax_check(): + """Check that you didn't change the return statement of a_plus_abs_b. + + >>> # You aren't expected to understand the code of this test. + >>> import inspect, re + >>> re.findall(r'^\s*(return .*)', inspect.getsource(a_plus_abs_b), re.M) + ['return f(a, b)'] + """ + # You don't need to edit this function. It's just here to check your work. + + +def two_of_three(i, j, k): + """Return m*m + n*n, where m and n are the two smallest members of the + positive numbers i, j, and k. + + >>> two_of_three(1, 2, 3) + 5 + >>> two_of_three(5, 3, 1) + 10 + >>> two_of_three(10, 2, 8) + 68 + >>> two_of_three(5, 5, 5) + 50 + """ + return min(i*i+j*j, i*i+k*k, j*j+k*k) + # Alternate solution +def two_of_three_alternate(i, j, k): + return i**2 + j**2 + k**2 - max(i, j, k)**2 + +def two_of_three_syntax_check(): + """Check that your two_of_three code consists of nothing but a return statement. + + >>> # You aren't expected to understand the code of this test. + >>> import inspect, ast + >>> [type(x).__name__ for x in ast.parse(inspect.getsource(two_of_three)).body[0].body] + ['Expr', 'Return'] + """ + # You don't need to edit this function. It's just here to check your work. + diff --git a/hw/sol-hw01/hw01.zip b/hw/sol-hw01/hw01.zip new file mode 100644 index 0000000000..1b75e44542 Binary files /dev/null and b/hw/sol-hw01/hw01.zip differ diff --git a/hw/sol-hw01/index.html b/hw/sol-hw01/index.html new file mode 100644 index 0000000000..af4c0e4926 --- /dev/null +++ b/hw/sol-hw01/index.html @@ -0,0 +1,412 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Homework 1 Solutions | Data C88C Fall 2024 + + + + + + +
+ +
+
+
+

+ +Homework 1 Solutions + + + + + + +

+
+ +

Solution Files

+

You can find the solutions in hw01.py.

+ + +
+ + +
+ +

Getting Started Videos

+ + +

These videos may provide some helpful direction for tackling the +problems on this assignment.

+ +

To see these videos, you should be logged into your berkeley.edu email. + +

YouTube link

+

+ + +

Required Questions

+ + + +

Q1: A Plus Abs B

+ + +

Python's operator module contains two-argument functions such as add and +sub for Python's built-in arithmetic operators. For example, add(2, 3) +evalutes to 5, just like the expression 2 + 3.

+ +

Fill in the blanks in the following function for adding a to the +absolute value of b, without calling abs. You may not modify any +of the provided code other than the two blanks.

+ +
def a_plus_abs_b(a, b):
+    """Return a+abs(b), but without calling abs.
+
+    >>> a_plus_abs_b(2, 3)
+    5
+    >>> a_plus_abs_b(2, -3)
+    5
+    >>> a_plus_abs_b(-1, 4)
+    3
+    >>> a_plus_abs_b(-1, -4)
+    3
+    """
+    if b < 0:
+
f = sub
else: +
f = add
return f(a, b)
+ +

Use Ok to test your code:

python3 ok -q a_plus_abs_b
+ +
+ +

Use Ok to run the local syntax checker (which checks that you didn't modify any of the provided code other than the two blanks):

+ +
python3 ok -q a_plus_abs_b_syntax_check
+ + + +
+ +

If b is positive, we add the numbers together. If b is negative, we +subtract the numbers. Therefore, we choose the operator add or sub +based on the sign of b.

+ +
+ + +

Q2: Two of Three

+ + +

Write a function that takes three positive numbers as arguments and returns +the sum of the squares of the two smallest numbers. Use only a single line +for the body of the function.

+ +
def two_of_three(i, j, k):
+    """Return m*m + n*n, where m and n are the two smallest members of the
+    positive numbers i, j, and k.
+
+    >>> two_of_three(1, 2, 3)
+    5
+    >>> two_of_three(5, 3, 1)
+    10
+    >>> two_of_three(10, 2, 8)
+    68
+    >>> two_of_three(5, 5, 5)
+    50
+    """
+
return min(i*i+j*j, i*i+k*k, j*j+k*k) + # Alternate solution +def two_of_three_alternate(i, j, k): + return i**2 + j**2 + k**2 - max(i, j, k)**2
+ +

Hint: Consider using the max or min function:

+ +
>>> max(1, 2, 3)
+3
+>>> min(-1, -2, -3)
+-3
+ +

Use Ok to test your code:

python3 ok -q two_of_three
+ +
+ +

Use Ok to run the local syntax checker (which checks that you used only a single line for the body of the function):

+ +
python3 ok -q two_of_three_syntax_check
+ + + +
+ +

We use the fact that if x>y and y>0, then square(x)>square(y). +So, we can take the min of the sum of squares of all pairs. The +min function can take an arbitrary number of arguments.

+ +

Alternatively, we can do the sum of squares of all the numbers. Then we +pick the largest value, and subtract the square of that.

+ +
+ + +

Check Your Score Locally

+ +

You can locally check your score on each question of this assignment by running

+ +
python3 ok --score
+ +

This does NOT submit the assignment! When you are satisfied with your score, submit the assignment to Gradescope to receive credit for it.

+ + +

Submit Assignment

+ + +

Submit this assignment by uploading any files you've edited to the appropriate Gradescope assignment. Lab 00 has detailed instructions.

+ +
+ + +
+ +
+ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/hw/sol-hw01/ok b/hw/sol-hw01/ok new file mode 100644 index 0000000000..88874ff1a5 Binary files /dev/null and b/hw/sol-hw01/ok differ diff --git a/index.html b/index.html index c7b1000924..14b8363a2e 100644 --- a/index.html +++ b/index.html @@ -344,13 +344,17 @@

Calendar

-HW 01: Functions +HW 01: Functions
Due Wed 9/11
+ +
@@ -451,7 +455,7 @@

Calendar

-Disc 03: Higher-Order Functions +Disc 03: Higher-Order Functions