Ludium
Sign In
Introduction to Computer Science using Python
Computation & Python Basics
01Algorithms as Recipes02The Six Operations Behind Every Program03Primitives, Syntax, and Semantics04Objects, Types, and Type Casting05Expressions, Operators, and Types06Assignment vs. EqualityProblem set0/10Practice∞
01Objects, Names, and Assignment02String Concatenation, Repetition, and len()03String Indexing and Slicing04String Immutability and the print() Function05User Input, Type Conversion, and f-strings06Comparisons, Booleans, and Logical Operators07Conditionals: if, elif, and elseProblem set0/10Practice∞
Control Flow & Iteration
01Conditional Branching: if, elif, and else02Iteration and the While Loop03While Loops, Counters, and Infinite Loops04While Loop Variables and Running Products05The for Loop and range()06The Accumulator Pattern and range()Problem set0/10MIT problem set0/2Practice∞
01The break Statement: Exiting a Loop Early02Looping Over Strings and the in Operator03Guess-and-Check: Exhaustive Enumeration04for Loops, Boolean Flags, and Cube Roots05Nested Loops and Brute-Force Search06Floats, Binary, and Floating-Point ErrorProblem set0/10Practice∞
Numbers & Algorithms
01Converting Integers to Binary (and Negatives)02Why 0.1 Can't Be Stored: Fractions in Binary03How Floats Are Stored, and Why You Never Use ==04Successive Approximation and the Loop That Never EndsProblem set0/10Practice∞
01Why Approximation Search Hits a Wall02Halving the Search Space at Every Step03Coding Bisection Search for Square Roots04Fixing Bisection Search for Numbers Below One05Newton-Raphson: Sliding Down the Tangent LineProblem set0/10MIT problem set0/1Practice∞
Functions & Abstraction
01Abstraction and Decomposition: Why Your Phone Is a Black Box02What a Function Really Is: The Specification and Its Four Parts03Writing Your First Function: From a Sentence to is_even04How a Function Call Becomes Its Value: Parameters vs. Arguments05Return vs. Print: The Mysterious None, and Functions in Real Code06Building sum_odds: Plan on Paper, Then Catch the Off-by-One BugProblem set0/10Practice∞
Scope & Higher-Order Functions
01return vs. print, and the Hidden None That Reveals a Bug02Turning Bisection Square Root Into a Reusable Function03Environments and Scope: The Rule Behind UnboundLocalError04A Function Is an Object: Naming, Passing, and Tracing Calls05Higher-Order Functions: Building apply(criteria, n)Problem set0/10Practice∞
Lambdas & Sequences
01Writing Anonymous Functions With Lambda02Tracing Nested Calls with the Environment Model03Tuples: An Ordered, Mixed-Type Sequence04Why Tuples Are Immutable: Nesting and Iteration05Tuple Unpacking: One-Line Swaps and Many Returns06The Star (*args), Lists, and Pythonic LoopsProblem set0/10MIT problem set0/3Practice∞
Mutating Lists
01Lists Mutate, Tuples Don't: The Name vs the Object02append: Growing a List and the None Trap03Dot Notation: Building and Filtering Lists04split and join: Converting Between Strings and Lists05sort vs. sorted: Mutate in Place or Return a New List06Writing Functions That Mutate a List In Place07Appending While Looping, and extend vs append08Reassignment vs Mutation, Proven with id()Problem set0/10MIT problem set0/1Practice∞
Aliases & Copies
01Cloning with L[:]: Mutating a List In Place02del, pop, and remove: Three Ways to Delete03The Loop That Skips: Removing While Iterating04Aliases vs Clones: Why L2 = L1 Is Not a Copy05Shallow vs Deep Copy: copy.copy and copy.deepcopyProblem set0/10Practice∞
Comprehensions, Testing & Debugging
01List Comprehensions: Your Build-a-List Loop in One Line02Reading Any Comprehension: Iterable, Expression, Condition03Default Parameters: Defaults Last, Keywords at the Call Site04Returning a Function Object: return g, Not return g()05Catching a Returned Function: Two Names, One Object06Unit, Regression, and Integration Testing07Black Box vs Glass Box: Where Test Cases Come From08Debugging by Bisection: Print Statements as EvidenceProblem set0/10Practice∞
Exceptions & Assertions
01try and except: Catching an Exception Instead of Crashing02Named Exception Handlers, else, finally, and raise03raise ValueError and assert: Enforcing Your Docstring04One Empty List, Four Designs: Crash, None, Default, AssertProblem set0/10Practice∞
Dictionaries
01Why Lists Fail at Lookup: Parallel Lists and Nested Search02Dictionaries: Custom Keys, Curly Braces, and KeyError03Mutating a Dictionary: Add, Overwrite, del, and in04keys(), values(), items(): Three Windows Into a Dictionary05Hashing and Immutable Keys: Why a List Can't Be a Key06Case Study: Building a Word Frequency Dictionary07Ranking Words by Deleting Them: The Cost of MutationProblem set0/10MIT problem set0/8Practice∞
Recursion
01Multiplying With Only Addition: From Loops to a Smaller Copy02Writing mult_recur: Base Case, Recursive Step, and the Call Stack03Divide and Conquer: The Regrade Chain and Writing power_recur04Recursive Factorial Acted Out: Environments and When to RecurseProblem set0/10Practice∞
01fib_recur: Two Recursive Calls and an Exploding Call Tree02Memoization: One Dictionary Cuts 11 Million Calls to 6503Counting Basketball Scores: Three Base Cases, Three Branches04Recursion on Lists: Peel One Element, Trust the Rest05Debugging a Recursive Search: Print, Fix, and Return Types06Nested Lists: Flatten, Search, and Why Loops Fall Short07Reversing a List Recursively: The Brackets That Make It Legal08deep_rev: One Type Test Reverses Every LayerProblem set0/10MIT problem set0/3Practice∞
Classes & Objects
01Class vs Instance: The Blueprint Behind Every Object02Choosing Data and Behavior: Elevators, Employees, and Stacks03class Coordinate(object): Implementing a Type vs Using It04The __init__ Constructor: Why Every Method Starts With self05Creating Instances: Coordinate(3, 4), Dot Notation, and Memory06Methods and the Dot Operator: distance, and How self Gets BoundProblem set0/10MIT problem set0/3Practice∞
Composition & Dunder Methods
01Data Attributes vs Parameter Names: What self Guarantees02Returning a Value vs Mutating the Object: Writing to_origin03Composition and ValueError: A Circle Made of Coordinate Objects04Before the Dot Becomes self: Writing a SimpleFraction Class05Every Operator Is a Method: Meet Python's Dunder Names06The __str__ Method: You Decide What print Shows07Overloading * and float() for a Fraction Class08Inside reduce: a Nested gcd and the Branch That Returns an intProblem set0/10Practice∞
Inheritance
01Data and Procedural Attributes: Building the Animal Class02Getters, Setters and __str__: Why the Method Outlives the Attribute03Attribute Abuse From Outside, and a Dictionary of Animal Objects04make_animals: Walking Two Lists in Step to Build a List of Objects05Hierarchies and Subclasses: The Three Moves a Subclass Can Make06class Cat(Animal): Inheriting __init__ and the Chain Python Climbs07Overriding __init__: Person Calls Animal.__init__ By Name08Student, a Subclass of a Subclass, and the Rabbit Class Variable09__add__ and __eq__ on Rabbits: Operator Overloading With Shared IDsProblem set0/10MIT problem set0/5Practice∞
An Object-Oriented Case Study
01Designing a Workout Class: __init__ Makes Five Attributes From Three02Two State Dictionaries: __dict__ on the Class and on the Object03A Getter That Estimates: Class Variables, None, and datetime04parser.parse and Where a Class Variable Actually Lives05class RunWorkout(Workout): Inheritance and super().__init__06One __str__ in the Parent, Three Kinds of Workout Printing07A Subclass Where Its Parent Goes, and Positional Argument Order08Overriding get_calories: How Python Picks Which Method Runs09__eq__ With super(), and the Last Word on Building ClassesProblem set0/10MIT problem set0/4Practice∞
Program Efficiency
01Correct Isn't Fast: time.time() and Three Functions Built to Be Measured02Timing Nine Input Sizes, and Four Reasons the Seconds Measure the Machine03One Unit per Operation: Costing Three Functions by Hand, Then in Code04Ten Times the Input, a Hundred Times the Work: Reading Operation CountsProblem set0/10Practice∞
01A Finer Clock: time.perf_counter and a Runtime That Never Moves02Which Parameter Costs Time? compound, sum_of, and One Linear Shape03Brute Force, Bisection, or in: Timing Three Searches to 100 Million04A Loop Inside a Loop: the diameter Function and Quadratic Growth05Counting Operations: Exact Formulas and a Program That Counts Itself06Order of Growth: What to Measure, Which Input, and the Worst Case07Big O: An Upper Bound That Only Has to Hold Past the Crossover08Big Theta: Bounded From Both Sides, Keep Only the Dominant Term09Reading Theta Off the Loops: Two Laws and Six Complexity ClassesProblem set0/10Practice∞

Coding challenges on searching smarter: bisection search, logarithmic time, and newton-raphson — MIT problem set

Problem 1Coding Bisection Search for Square Roots

Choosing an Interest Rate by Bisection Search

MIT 6.100L Introduction to CS and Programming Using Python, Fall 2022 · Problem set 1, 4) Part C: Choosing an Interest Rate — ps1c.py · Dr. Ana Bell · CC BY-NC-SA 4.0 · MIT publishes no solution for this set; the worked solution is ours

Write the body of lowest_rate_of_return(initial_deposit), MIT's Part C program: use bisection search to find the lowest rate of return r that grows an initial deposit into the down payment on a house in 3 years.

In Part A and B, you explored how (1) the percentage of your salary saved each month and (2) a semi-annual raise affects how long it takes to save for a down payment given a fixed rate of return, r.

In Part C, we will have a fixed initial amount and the ability to choose a value for the rate of return, r. Given an initial deposit amount, our goal is to find the lowest rate of return that enables us to save enough money for the down payment in 3 years.

User Inputs. MIT's program reads one value with input() and casts it as a float: the initial amount in your savings account (initial_deposit). Here the parameter initial_deposit stands in for that input() call. It already holds the number the user would have typed, so use it exactly as you would have used the value input() returned. Write your program under MIT's two comment headers in the starter and keep the last line, return r, steps, which hands your two output variables to the tests.

Writing the Program. Write a program to calculate the minimum rate of return r needed in order to reach your goal of a sufficient down payment in 3 years, given an initial_deposit. To simplify things, assume:

  1. The cost of the house that you are saving for is $800,000.
  2. The down payment is 25% of the cost of the house.

Use the following formula for compound interest in order to calculate the predicted savings amount given a rate of return r, an initial_deposit, and months:

amount_saved = initial_deposit * (1 + r / 12) ** months

You will use bisection search to determine the lowest rate of return r that is needed to achieve a down payment on a $800,000 house in 36 months. Since hitting this exact amount is a bit of a challenge, we only require that your savings be within $100 of the required down payment. For example, if the down payment is $1000, the total amount saved should be between $900 and $1100 (exclusive).

Your bisection search should update the value of r until it represents the lowest rate of return that allows you to save enough for the down payment in 3 years. r should be a float (e.g. 0.0704 for 7.04%). Assume that r lies somewhere between 0% and 100% (inclusive).

Outputs.

  1. The variable steps should reflect the number of steps your bisection search took to get the best r value (i.e. steps should equal the number of times that you bisect the testing interval).
  2. The variable r should be the lowest rate of return that allows you to save enough for the down payment in 3 years.

Notes

  • There may be multiple rates of return that yield a savings amount that is within $100 of the required down payment on a $800,000 house. The grader will accept any of these values of r.
  • If the initial deposit amount is greater than or equal to the required down payment minus $100, then the best savings rate is 0.0.
  • If it is not possible to save within $100 of the required down payment in 3 years given the initial deposit and a rate of return between 0% and 100%, r should be assigned the value None. Note: the value None is different than "None". The former is Python's version of a null value, and the latter is a string.
  • Depending on your stopping condition and how you compute the amount saved for your bisection search, your number of steps may vary slightly from the example test cases. Running the tests should give you a good indication of whether or not your number of steps is close enough to the expected solution.
  • If a test is taking a long time, you might have an infinite loop! Check your stopping condition.

Testing. MIT's three manual test cases, as calls to your function. MIT's program prints Best savings rate: and Steps in bisection search:; your function returns the pair r, steps instead.

print(lowest_rate_of_return(65000))  # (0.380615234375, 12)
print(lowest_rate_of_return(150000))  # (0.09619140625, 11)
print(lowest_rate_of_return(1000))  # (None, 0)

As MIT notes, your best savings rate may be very close to these numbers rather than equal to them, and your number of steps may vary with how you implemented your bisection search. The tests accept any r whose savings land within $100 of the down payment and a step count within 2 of MIT's, except MIT's own tester case of an initial deposit of 187401, which must take exactly 12 steps. Neither special case (0.0 or None) checks the number of steps.

Adapted for the browser: MIT's ps1c.py script is wrapped in the function lowest_rate_of_return(initial_deposit), as MIT's own put_in_function.py does, so the parameter replaces the input() call and the function returns r, steps instead of printing them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def lowest_rate_of_return(initial_deposit):
    """
    initial_deposit (float): the initial amount in your savings account; it
        stands in for input("Enter the initial deposit: ").

    Returns r, steps: the lowest rate of return r (a float, or 0.0 or None as
    the notes say) and the number of steps your bisection search took.
    """
    #########################################################################
    ## Initialize other variables you need (if any) for your program below ##
    #########################################################################


    ##################################################################################################
    ## Determine the lowest rate of return needed to get the down payment for your dream home below ##
    ##################################################################################################


    return r, steps

Scratchpad— run any Python to test ideas
1
2
3
4
5
# Scratchpad — run any Python here to test ideas.
# Anything you write below stays separate from the problem's tests.

print("hello, world")

Python runtime ready in a moment
Python runtime ready in a moment
Visible tests · 4Examples — click to expand
?
MIT tester Part C Test 1: initial deposit 65000
?
MIT tester Part C Test 2: initial deposit 187401
?
MIT tester Part C Test 3: initial deposit 1000 can never reach the down payment
?
PDF Test Case 2: initial deposit 150000
Hidden tests · 5Bodies hidden — pass/fail only
?
Hidden test 1
?
Hidden test 2
?
Hidden test 3
?
Hidden test 4
?
Hidden test 5