# CMU 15-112 Fall 2016: Fundamentals of Programming and Computer Science Homework 1 (Due Saturday 3-Sep, at 6pm)

• Except for the 1-hour meeting with your TA, this hw is SOLO. See the syllabus for details.
• To start:
1. Create a folder named 'week1'
3. Edit hw1.py using pyzo
4. When you are ready, submit hw1.py to autolab. For this hw, you may submit up to 20 times (which is way more than you should require), but only your last submission counts.
• Do not use strings, loops, lists, or recursion this week.
• Do not hardcode the test cases in your solutions.

1. 1-Hour TA-Led Practice Session [20 pts]
For this exercise, you need to attend a 1-hour week1 practice session with one of your TA's from your assigned recitation. Your TA's will contact you via email with numerous different times when they will offer these 1-hour sessions. You need to attend one of these by 6pm Saturday night. The sooner, the better, as this will be a great help for you prior to starting hw1. Note: you only get credit for attending if you are on time and stay the whole time. You have nothing to submit for this -- the TA's will take attendance and will enter this directly into Autolab, so you then receive the points for attending. Never mind the points, though: this is an invaluable time to practice with an expert, and to let you see just how wonderfully helpful it is to work with our TA's!

2. fabricYards(inches) [20 pts]
Fabric must be purchased in whole yards. Write the function fabricYards(inches) that takes the number of inches of fabric desired, which you may assume is a non-negative int, and returns as an int the smallest number of whole yards of fabric that must be purchased.

3. fabricExcess(inches) [20 pts]
Write the function fabricExcess(inches) that takes the number of inches of fabric desired, which is a non-negative int, and returns the number of inches of excess fabric that must be purchased (as purchases must be in whole yards). Hint: you may want to use fabricYards, which you just wrote!

4. isRightTriangle(x1, y1, x2, y2, x3, y3) [20 pts]
Write the function isRightTriangle(x1, y1, x2, y2, x3, y3) that takes 6 int or float values that represent the vertices (x1,y1), (x2,y2), and (x3,y3) of a triangle, and returns True if that is a right triangle and False otherwise. You may wish to write a helper function, distance(x1, y1, x2, y2), which you might call several times. Also, remember to use almostEqual (instead of ==) when comparing floats.

5. colorBlender(rgb1, rgb2, midpoints, n) [20 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):
• color #0: rgb(220,20,60)
• color #1: rgb(212,78,95)
• color #2: rgb(205,136,131)
• color #3: rgb(197,194,166)
• color #4: 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
You can find some other test cases in the test function provided for you in hw1.py.

6. Bonus/optional: bonusFindIntRootsOfCubic(a,b,c,d) [3 pts]
Write the function bonusFindIntRootsOfCubic(a,b,c,d) that takes the int or float coefficients a, b, c, d of a cubic equation of this form:
y = ax3 + bx2 + cx + d
You are guaranteed the function has 3 real roots, and in fact that the roots are all integers.  Your function should return these 3 roots in increasing order.  How does a function return multiple values?  Like so:
return root1, root2, root3
To get started, you'll want to read about Cardano's cubic formula here (great stuff!).  Then, from that page, use this formula:

x   =   {q + [q2 + (r-p2)3]1/2}1/3   +   {q - [q2 + (r-p2)3]1/2}1/3   +   p

where:

p = -b/(3a),   q = p3 + (bc-3ad)/(6a2),   r = c/(3a)

This isn't quite as simple as it seems, because your solution for x will not only be approximate (and not exactly an int, so you'll have to do something about that), but it may not even be real!  Though the solution is real, the intermediate steps may include some complex values, and in these cases the solution will include a (possibly-negligibly-small) imaginary value.  So you'll have to convert from complex to real (try c.real if c is complex), and then convert from real to int.

Great, now you have one root.  What about the others?  Well, we can divide the one root out and that will leave us with a quadratic equation, which of course is easily solved.  A brief, clear explanation of this step is provided here.  Don't forget to convert these to int values, too!

So now you have all three int roots.  Great job!  All that's left is to sort them.  Now, if this were later in the course, you could put them in a list and call a built-in function that will sort for you.  But it's not, so you can't.  Instead, figure out how to sort these values using the limited built-in functions and arithmetic available this week.  Then just return these 3 values and you're done.