15-112 Spring 2015 Homework 4
Due Sunday, 8-Feb, at 10pm

Read these instructions first!
  1. Group Study Session [0 pts, not graded]
    Note: This is the only non-SOLO part of the hw. This technically is not part of the hw, as we will no longer require study groups as part of your hw. However, as previously noted, our sincere hope is that you are forming good habits, and will elect to use the various forms of small-group and large-group study effectively for the rest of 112 and beyond. So form your own study groups, and collaborate (where allowed, on practice problems) effectively!

  2. f14 Quiz 4 [10 pts, manually graded]
    In a triple-quoted string at the top of your hw file, include the solutions to f14's quiz4 (except for the bonus, which you should skip (or do for fun if you wish)).

  3. leastFrequentLetters(s) [10 pts] [autograded]
    Write the function leastFrequentLetters(s), that takes a string s, and ignoring case (so "A" and "a" are treated the same), returns a lowercase string containing the least-frequent alphabetic letters that occur in s, each included only once in the result and then in alphabetic order. So:
       leastFrequentLetters("aDq efQ? FB'daf!!!")
    returns "be". Note that digits, punctuation, and whitespace are not letters! Also note that seeing as we have not yet covered lists, sets, maps, or efficiency, you are not expected to write the most efficient solution. Finally, if s does not contain any alphabetic characters, the result should be the empty string ("").

  4. bestStudentAndAvg [15 pts, autograded]
    See f14-midterm1 #7. Note that this is autograded.

  5. patternedMessage [15 pts, autograded]
    See s14-hw3. Be sure to carefully read the writeup, including the very helpful hints at the top of the document.

  6. displayKineticText [50 pts, manually graded]
    Include this function, without modification, in your code:
    def displayKineticText(text, color):
        stepAnimation.run(kineticTextAnimation, width=500, height=250,
                          timerDelay=25, text=text, color=color)
    
    Then, write the function kineticTextAnimation(canvas, width, height, step, text, color) so that displayKineticText("Amazing!", "blue") produces the animation described in this video. It may also help to watch this video, which shows the animation without pauses or voiceover.

    As with the step animations in hw3, you do not have to match exactly, but you must be reasonably close, and you must match exactly those aspects of the animation described precisely in the video. Note also that you must use a variable-width font, specifically "Arial", and so the bounding boxes around each letter may differ in width and perhaps also in height depending on the specific letter.

    To do this, you will probably want to use the textSize function as demonstrated here (note the box drawn around the text):
    import stepAnimation
    from Tkinter import *
    
    def textSize(canvas, text, font):
        # Note that tkFont.Font.measure(text) and tkFont.Font.metrics("linespace")
        # were both unreliable, producing wrong results in some cases.
        # This is a bit crufty, but generally works...
        temp = canvas.create_text(0, 0, text=text, anchor=NW, font=font)
        (x0, y0, x1, y1) = canvas.bbox(temp)
        canvas.delete(temp)
        return (x1-x0, y1-y0)
    
    def textSizeDemoAnimation(canvas, width, height, step, text, color):
        left = step % width
        top = 20
        font = "Arial " + str(step%100) + " bold"
        canvas.create_text(left, 20, text=text, font=font, fill=color, anchor=NW)
        (textWidth, textHeight) = textSize(canvas, text, font)
        canvas.create_rectangle(left, 20, left+textWidth, 20+textHeight)
    
    stepAnimation.run(textSizeDemoAnimation, width=400, height=90, timerDelay=10,
                      text="Fantastic!", color="brown")
    

    Hint: You have the textSize function we provided, which tells you the width of a string in a certain font. You could use it to find the widths of some substrings of that string. Then you could use the difference of those widths to determine the width of an individual letter. Similarly, you could find the left edge of a centered text if you knew its center position (which of course you do) and its width. Right? And then you could use the left edge and the width-to-the-kth-character to find the left edge of the kth-character. Hope this helps!

  7. Bonus/Optional: getEvalSteps() [2.5 pts, autograded]
    Write getEvalSteps(expr) from f14-hw4.

  8. Bonus/Optional: Fun with Tortoises! [2.5 pts, manually graded]
    Write either runTortoiseProgramWithErrorChecking or runTortoiseProgramWithLoops (but not both) from f14-hw4.