Saturday 16 July 2016

Stop Watch!

Code

This was an assignment for the Python Course I took on Coursera, Interactive Python Programming. It's written in a web-based Python shell called CodeSkulptor developed by the course instructors, and comes with some of Python's libraries as well as some gui commands built into it. It's a simple game where you hit the stop button just as the clock hits the second mark. You can run it by hitting the play button at the top left hand off the page.

Anyone who knows about computers will likely know that that computers don't keep track of time in minutes and hours. Instead it's just one giant chunk of miliseconds. So one minute is 60 seconds*10 miliseconds.

One way I could have solved this is to write some long tedious if/elif loop, where I say something like:

----------------------------
msec = total_time%10

if msec == 10:
    msec_counter = 0
    sec_counter = 1
    if sec_counter == 60:
        sec_counter = 0
        minute_counter = 1
----------------------------

and so on for hours and days. Personally, I don't like code with too many nested loops, because it's hard to read, and logic errors can crop up easily. It also makes it challenging to edit later. Instead, I like to use functions to break up the computations.

I looked for other ways to implement this, and this is where I think I fell in love with using mathematics to implement solutions. I could do this in a much clearer way (to me at least) then writing long-winded loops with the added bonus that I can use that function later on.

This is the implementation I ended up using:

----------------------------
def format(t):
    # using euclid division a = bq + r
    # where a = t, b = 600(60 secs)
    # q = minutes(t/b), r = remainder
 
    def euclid_division(t):
        r = t-600*(t/600)       # collapsed equation using a = bq+r
        return r                      # we want to find remainder (r), therefore
                                          # the new equation is r = a - bq
                                          # where a is t, b is 600, and q is quotient
     
    def euclid_division_min(t):
        r = euclid_division(t)     # collapsed equation from a = bq+r
        loc_min = (t -r)/600       # we try to find out how many minutes given t deciseconds
        return loc_min               # so new equation is q = (a - r)/b
                                               # where a = t, r is derived from function euclid_division(t)
                                               # and b is 600. q is given "loc_min" as variable name here
                             
    # declare global variables
    global decisec                # declared global var for later use to keep score.
    decisec = t%10              # decisecond portion easily found with modulo.
    # local variables
    sec = euclid_division(t)/10
    min = euclid_division_min(t)
 
    if sec < 10:                      # if string.zfill() function exist, would be a lot simpler
        sec = "0" + str(sec)     # but since it's not loaded, longer, clumsier way neccesary

    if min < 10:
        min = "0" + str(min)
     
     
    return str(min) + ":" + str(sec) + "." + str(decisec)
----------------------------

The solution I happened upon uses euclidean division, a = bq + r. Within this equation are all the ingredients I need to find the second, minute, hour for implementing the clock. We can find the msec portion with modulo, and the second/minute portion can be found with the two functions euclid_division() and euclid_division_min().

No comments:

Post a Comment