Skip to content

Instantly share code, notes, and snippets.

@westurner
Created October 12, 2014 10:00
Show Gist options
  • Save westurner/c007a335ea01daf7f0b0 to your computer and use it in GitHub Desktop.
Save westurner/c007a335ea01daf7f0b0 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# encoding: utf-8
from __future__ import print_function
"""
clock_hands
__________________
| 12 |
| |
| |
|9 0 3|
| |
| |
|_______6________|
__________________
| 60 |
| |
| |
|45 0 15|
| |
| |
|_______30_______|
"""
from collections import namedtuple
Time = namedtuple('Time', 'hour min sec')
Time.__str__ = lambda x: ('%02d:%02d:%02d' % x)
Time.total_seconds = lambda x: (
(x.hour * 60 * 60) +
(x.min * 60) +
x.sec)
Solution = namedtuple('Solution', 'time hour_hand minute_hand diff')
Solution.__str__ = lambda x: ('%s : %.2f %.2f [%.2f]' %
(x.time, x.hour_hand, x.minute_hand, x.diff))
def time():
for hour in range(24):
for min_ in range(60):
for second in range(60):
yield Time(hour, min_, second)
def clock_hands(hour, min, second=0):
"""
mainfunc
Args
-----
hour (int) -- 0-23
min (int) -- 0-59
"""
degrees_an_hour = 360 / 12.
degrees_an_hour_minute = degrees_an_hour / 60.
degrees_an_hour_minute_second = degrees_an_hour_minute / 60.
degrees_a_minute = (360 / 60)
degrees_a_second = degrees_a_minute / 60.
_hour = hour % 12
hour_hand = (
(degrees_an_hour * _hour) +
(degrees_an_hour_minute * min) +
(degrees_an_hour_minute_second * second))
minute_hand = (
(degrees_a_minute * min) +
(degrees_a_second * second))
second_hand = (360 / 60) * second
hour_hand = hour_hand % 360
minute_hand = minute_hand % 360
return hour_hand, minute_hand, second_hand
def straight_line(one, two, tolerance=1):
diff = one - two
if (((180 - tolerance) <= abs(diff) <= (180 + tolerance)) or
((0 - tolerance) <= diff <= tolerance)):
return diff
return None
def find_intersections():
for t in time():
hour_hand, minute_hand, second_hand = clock_hands(*t)
h, m, s = t
diff = straight_line(hour_hand, minute_hand, tolerance=1)
if diff is not None:
s = Solution(Time(h,m,s), hour_hand, minute_hand, diff)
yield s
def group_intersections(iterable, threshold=180):
prev_seconds = None
run = []
for s in iterable:
if prev_seconds is None:
prev_seconds = s.time.total_seconds()
if s.time.total_seconds() - prev_seconds <= threshold:
run.append(s)
else:
yield run
run = []
prev_seconds = s.time.total_seconds()
import unittest
class Test_clock_hands(unittest.TestCase):
def test_time(self):
for group in group_intersections(find_intersections()):
print('\n')
for intersection in group:
print(intersection)
raise Exception()
def test_clock_hands(self):
IO = (
((12, 00), (0, 0, 0)),
((03, 00), (90, 0, 0)),
((06, 00), (180, 0, 0)),
((9, 00), (270, 0, 0)), #
((06, 15), ((180 + ((360 / 12. / 60.) * 15)), 90, 0)),
)
for i, o in IO:
output = clock_hands(*i)
self.assertEqual(o, output)
def main(*args):
import logging
import optparse
import sys
prs = optparse.OptionParser(usage="%prog : args")
prs.add_option('-v', '--verbose',
dest='verbose',
action='store_true',)
prs.add_option('-q', '--quiet',
dest='quiet',
action='store_true',)
prs.add_option('-t', '--test',
dest='run_tests',
action='store_true',)
args = args and list(args) or sys.argv[1:]
(opts, args) = prs.parse_args()
if not opts.quiet:
logging.basicConfig()
if opts.verbose:
logging.getLogger().setLevel(logging.DEBUG)
if opts.run_tests:
sys.argv = [sys.argv[0]] + args
import unittest
sys.exit(unittest.main())
clock_hands()
if __name__ == "__main__":
import sys
sys.exit(main())
@westurner
Copy link
Author

Usage:

python ./clockhands.py -t

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment