Homework 1

Due Tuesday 29-Aug, at 10:00pm


To start

  1. Create a folder named ‘hw1’
  2. Download hw1.py to that folder
  3. Edit hw1.py and modify the functions as required
  4. When you have completed and fully tested hw1, submit hw1.py to Gradescope. For this hw, you may submit up to 20 times (which is way more than you should require), but only your last submission counts.

Some important notes

  1. This homework is solo. You may not collaborate or discuss it with anyone outside of the course, and your options for discussing with other students currently taking the course are limited. See the academic honesty policy for more details.
  2. After you submit to Gradescope, make sure you check your score. If you aren’t sure how to do this, then ask a CA or Professor.
  3. There is no partial credit on Gradescope testcases. Your Gradescope score is your Gradescope score.
  4. Read the last bullet point again. Seriously, we won’t go back later and increase your Gradescope score for any reason. Even if you worked really hard and it was only a minor error…
  5. Do not hardcode the test cases in your solutions.
  6. The starter hw1.py file includes test functions to help you test on your own before you submit to Gradescope. When you run your file, problems will be tested in order. If you wish to temporarily bypass specific tests (say, because you have not yet completed some functions), you can comment out individual test function calls at the bottom of your file in main(). However, be sure to uncomment and test everything together before you submit! Ask a CA if you need help with this.
  7. Remember the course’s academic integrity policy. Solving the homework yourself is your best preparation for exams and quizzes; cheating or short-cutting your learning process in order to improve your homework score will actually hurt your course grade long-term.
  8. Do not use string indexing, loops, lists, list indexing, or recursion this week. The autograder will reject your submission entirely if you do.

Problems


  1. Breaking the ice on Piazza [5 pts]
    This task is very easy. Make a post on Piazza asking a valid question about this homework OR answering one of questions posted by other students about this homework. Make sure your post is public and that it follows the academic integrity policy.

  2. isValidYearOfBirth(year) [5 pts]
    Imagine that you are writing a software that validates personal information entered by the users. Write the function isValidYearOfBirth(year) which, given a value year, returns True if it is an integer value that represents a valid year of birth, False otherwise. Keep in mind that, according to Wikipedia, the oldest person was born in 1907.

  3. numberOfPoolBalls(rows) [5 pts]
    Pool balls are arranged in rows where the first row contains 1 pool ball and each row contains 1 more pool ball than the previous row. Thus, for example, 3 rows contain 6 total pool balls (1+2+3). With this in mind, write the function numberOfPoolBalls(rows) that takes a non-negative int value, the number of rows, and returns another int value, the number of pool balls in that number of full rows. For example, numberOfPoolBalls(3) returns 6. We will not limit our analysis to a "rack" of 15 balls. Rather, our pool table can contain an unlimited number of rows. Hint: you may want to briefly read about Triangular Numbers. Also, remember not to use loops!

  4. getTheCents(n) [10 pts]
    Write the function getTheCents(n) which takes a value n (which represents a payment in US dollars) as input and returns the number of cents in the payment. If n is an int, the function should return 0, as it has 0 cents; otherwise, if it isn't a float, it should also return 0, because a non-number payment make no cents (ha!). You can assume that n will have up to 2 decimal places. For instance,
    getTheCents(3) == 0 getTheCents(3.00) == 0 getTheCents(3.96) == 96 getTheCents(3.95) == 95 getTheCents(3.1) == 10 getTheCents(3.11) == 11

  5. isPerfectCube(n) [10 pts]
    Write the function isPerfectCube(n) that takes a possibly-non-int value, and returns True if it is an int that is a perfect cube (that is, if there exists an integer m such that m**3 == n), and False otherwise. Do not crash on non-ints nor on negative ints.

  6. isSymmetricNumber(n) [20 pts]
    We define a number as symmetric if it is an integer, non-negative, and its left and right halves are identical. For example, 99 and 2020 are duplicated numbers, but 4554 and 789987 are not. With this in mind, write the function isSymmetricNumber(n), which takes a value n and returns True if n is a symmetric number and False otherwise. Notes: The numbers can be arbitrarily large. For example, 444555666444555666 is a symmetric number.

  7. Circle Intersection [20 pts]
    Two circles in a plane intersect in zero, one, two, or infinitely many points. The latter case occurs only in the case of two identical circles. The first case (zero points of intersection) occurs whenever the distance between the centers of the circles is greater than the sum of the radii or the distance between the center is less than the absolute value of the difference in their radii.
    • distance(x1,y1,x2,y2) First, you must write a helper function distance(x1, y1, x2, y2) to find the distance between two points. This function takes four int or float values representing two points and returns the distance between those points.
    • circleIntersection(xa,ya,ra,xb,yb,rb) Your task is to write a function circleIntersection(xa,ya,ra,xb,yb,rb) that will take six values as input parameters. These values represent the coordinates (xa,ya) of the center of circle A, and the radius ra of A, followed by the coordinates (xb,yb) of the center of circle B, and the radius rb of B. Your function should return the number of intersection points (only the number, not the points). There are 4 possible cases:

      The circles do not touch each other. This could be because one is contained in the other circle, or they are too far apart from each other. In these cases your function should return value 0.


      No intersection


      The circles intersect at a single point: either they touch internally or externally. In these cases your function should return value 1.


      1-point intersection (a)
      1-point intersection (b)


      The circles intersect at two points. Your function should return value 2.


      2-point Intersection


      The circles intersect at infinitely many points, i.e., they fully overlap. Your function should return infinity. In Python you can represent positive infinity as float(''inf'')


      Overlap


    Hint: You should use the distance function that you just wrote in the first part to help you solve this problem. Remember to use almostEqual or math.isclose (instead of ==) when comparing floats!

  8. colorBlender(rgb1, rgb2, midpoints, n) [25 pts]
    This problem implements a color blender, inspired by this tool. In particular, we will use it with integer RGB values (it also does hex values and RGB% values, but we will not use those modes). Note that RGB values contain 3 integers, each between 0 and 255, representing the amount of red, green, and blue respectively in the given color, where 255 is "entirely on" and 0 is "entirely off".

    For example, consider this case. Here, we are combining crimson (rgb(220, 20, 60)) and mint (rgb(189, 252, 201)), using 3 midpoints, to produce this palette (using our own numbering convention for the colors, starting from 0, as the tool does not number them):

    color0: rgb(220, 20, 60) color1: rgb(212, 78, 95) color2: rgb(205, 136, 131) color3: rgb(197, 194, 166) color4: rgb(189, 252, 201)

    There are 5 colors in the palette because the first color is crimson, the last color is mint, and the middle 3 colors are equally spaced between them.

    So we could ask: if we start with crimson and go to mint, with 3 midpoints, what is color #1? The answer then would be rgb(212, 78, 95).

    One last step: we need to represent these RGB values as a single integer. To do that, we'll use the first 3 digits for red, the next 3 for green, the last 3 for blue, all in base 10 (decimal, as you are accustomed to). Hence, we'll represent crimson as the integer 220020060, and mint as the integer 189252201.

    With all that in mind, write the function colorBlender(rgb1, rgb2, midpoints, n), which takes two integers representing colors encoded as just described, a non-negative integer number of midpoints, and a non-negative integer n, and returns the nth color in the palette that the tool creates between those two colors with that many midpoints. If n is out of range (too small or too large), return None.

    For example, following the case above: colorBlender(220020060, 189252201, 3, 1) returns 212078095

    Hint: RGB values must be ints, not floats. When calculating midpoint colors, you can mostly use the built-in round function. However, the built-in round function has one major flaw: it varies in whether it chooses to round .5 up or down (ugh!). You can fix this by doing an extra check for whether a number is <number>.5 and choosing to always round up in that case.