# CMU 15-112 Fall 2016: Fundamentals of Programming and Computer Science Lab 9 (Due Saturday 29-Oct, at 8pm, no extensions or grace days)

• This lab is Collaborative. No solo work allowed. Work in groups of 2-3 (and the same group the whole time). See the syllabus for more details.
• Everything in this lab must be recursive! No iteration allowed! In particular, you may not use 'for' or 'while' anywhere.
• You also may not use 'zip' or 'join' (which generally are not useful here, but in one or two cases could be used to avoid the recursive solution you should be finding).
• Starter files: lab9.py and cs112_f16_wk9.py
• This week you may use up to 6 submissions. Only your last submission counts.
• The autograder will check correctness, but we will have to manually grade some problems to confirm you followed the restrictions, such as only using one line or only using map/filter/reduce/lambda.
• Do not hardcode the test cases in your solutions.

Write the function alternatingSum(L) that takes a possibly-empty list of numbers, L, and returns their alternating sum, where every other value is subtracted rather than added. For example:
alternatingSum([1,2,3,4,5]) returns 1-2+3-4+5 (that is, 3)
If L is empty, return 0.

2. powerSum(n, k) [15 pts] [autograded]
Write the function powerSum(n, k) that takes two possibly-negative integers n and k and returns the so-called power sum:
1**k + 2**k + ... + n**k
If n is negative, return 0. Similarly, if k is negative, return 0.

Write the function powersOf3ToN(n) that takes a possibly-negative float or int n, and returns a list of the positive powers of 3 up to and including n, or None (not an empty list) if no such values exist. As an example, powersOf3ToN(10.5) returns [1, 3, 9].

4. myJoin(L, sep) [7.5 pts] [autograded]
Using reduce, map, and lambda, write the one-line function myJoin(L, sep) that takes a non-empty list L and a string sep, and without calling sep.join(L), works roughly the same as that -- returning a single string with the values in L separated by the sep. So:
myJoin(['a','b','c'], '-') returns 'a-b-c'
Unlike sep.join(L), your function must work even if L contains non-strings. So:
myJoin([1, 2, 3], '@@') returns '1@@2@@3'
Remember that you may not call join, and your solution must be only one line of Python.

5. myCount(fn, L) [7.5 pts] [autograded]
Using reduce, filter, and lambda, write the one-line function myCount(fn, L) that takes a function fn and a non-empty list L, and returns the number of values in L where the function fn returns True, so that it basically works the same as this function (though without iteration, of course):
def myCount(fn, L): result = 0 for val in L: if (fn(val) == True): result += 1 return result
Remember that your solution must be only one line of Python.

6. Line class [40 pts] [autograded]
Write the Line class so that it passes testLineClass, and uses the OOP constructs we learned this week as appropriate.
def testLineClass(): print('Testing Line class...', end='') assert(str(Line(2,5)) == "y=2x+5") assert(str(Line(2,-5)) == "y=2x-5") assert(str(Line(0,5)) == "y=5") assert(str(Line(1,5)) == "y=x+5") assert(str(Line(-1,5)) == "y=-x+5") assert(str(Line(0,-5)) == "y=-5") assert(str(Line(0,0)) == "y=0") line1 = Line(2,3) assert(str(line1) == "y=2x+3") assert(line1.getSlope() == 2) assert(type(line1.getSlope()) == int) assert(line1.getIntercept() == 3) line2 = Line(6,-5) assert(str(line2) == "y=6x-5") assert(line2.getSlope() == 6) assert(line2.getIntercept() == -5) (x,y) = line1.getIntersection(line2) # (2, 7) assert(almostEqual(x, 2) and almostEqual(y, 7)) line3 = Line(2, -3) (x,y) = line3.getIntersection(line2) # (0.5, -2) assert(almostEqual(x, 0.5) and almostEqual(y, -2)) # parallel lines do not intersect assert(Line(2,3).getIntersection(Line(2,4)) == None) assert(line3.isParallelTo(line1) == True) assert(line3.isParallelTo(line2) == False) # getHorizontalLine returns a line that is horizontal # to the given line, intersecting at the given x value. line4 = line3.getHorizontalLine(4) assert(str(line4) == "y=5") assert(line4.getSlope() == 0) assert(line4.getIntercept() == 5) assert(Line(1, 2) == Line(1, 2)) assert(Line(1, 2) != Line(1, 3)) assert(not (Line(1, 2) == "don't crash here!")) s = set() assert(Line(1, 2) not in s) s.add(Line(1, 2)) assert(Line(1, 2) in s) s.remove(Line(1, 2)) assert(Line(1, 2) not in s) print('Passed.')