Skip to content

Instantly share code, notes, and snippets.

@qubitz
Created March 24, 2017 02:45
Show Gist options
  • Select an option

  • Save qubitz/dd3f49289872358724be87c1c8778328 to your computer and use it in GitHub Desktop.

Select an option

Save qubitz/dd3f49289872358724be87c1c8778328 to your computer and use it in GitHub Desktop.
Clean code practice with Python!
inputNotReceived = True
while inputNotReceived:
try:
# Get starting time from user (hours, minutes)
enteredTime = input("Enter starting time (HH:MM): ").strip().split(':')
startHour, startMinute = map(int, enteredTime) # may throw ValueError
if (1 >= startHour or startHour >= 12) and (0 > startMinute or startMinute >= 60):
print("Entered time not valid")
else:
inputNotReceived = False # successful input
except ValueError:
print("Must enter a time (ex: 5:09)")
inputNotReceived = True
while inputNotReceived:
try:
# Get timer value from user (hours)
enteredTimerHour = input("Enter timer value: ")
timerHour = int(enteredTimerHour)
if timerHour < 0:
print("Entered value not valid")
else:
inputNotReceived = False
except ValueError:
print("Must enter a number")
sumHours = startHour + timerHour
if 0 > sumHours or sumHours > 12:
endHour = sumHours % 12
else:
endHour = sumHours
endTime = "{0}:{1:02d}".format(endHour, startMinute)
print(endTime)
class Time:
"""Represents and manipulates hours and minutes"""
def __init__(self, hour=12, minute=0):
valid_hour, valid_minute = Time.make_valid(hour, minute)
self.__hour = valid_hour
self.__minute = valid_minute
def __str__(self):
return "{0}:{1:02}".format(self.__hour, self.__minute)
def __add__(self, other):
return Time.add_minute(Time.add_hour(self, other.__hour),
other.__minute)
def get_hour(self):
return self.__hour
def get_minute(self):
return self.__minute
def is_valid_time(self):
return Time.is_valid_hour(self.__hour) and Time.is_valid_minute(self.__minute)
def add(self, other):
result_time = self + other
self.__hour = result_time.__hour
self.__minute = result_time.__minute
@staticmethod
def add_hour(other, hour):
"""
:rtype: Time
"""
return Time(other.__hour + hour, other.__minute)
@staticmethod
def add_minute(other, minute):
return Time(other.__hour, other.__minute + minute)
@staticmethod
def is_valid_hour(hour):
return 1 <= hour <= 12
@staticmethod
def is_valid_minute(minute):
return 0 <= minute < 60
@staticmethod
def make_valid(hour, minute):
valid_minute, carryover_hour = Time.make_valid_minute(minute)
valid_hour = Time.make_valid_hour(hour)
return valid_hour + carryover_hour, valid_minute
@staticmethod
def make_valid_hour(hour):
if not Time.is_valid_hour(hour):
valid_hour = hour % 12
else:
valid_hour = hour
return valid_hour
@staticmethod
def make_valid_minute(minute):
"""
:param minute:
:return:
"""
if not Time.is_valid_minute(minute):
valid_minute = minute % 60
carryover_hour = minute // 60
else:
valid_minute = minute
carryover_hour = 0
return valid_minute, carryover_hour
@staticmethod
def from_string(time_str):
"""
Semi-constructor from string
:param time_str: String representing time (ex: 5:09)
:return: Time object represented by time_str
"""
hour, minute = map(int, time_str.strip().split(":"))
return Time(hour, minute)
def get_time_from_user(time_kind):
"""
Prompts for "time_kind time" and returns inputted time
:rtype: Time
"""
try:
entered_time = (input("Enter " + time_kind + " time (HH:MM): "))
return Time.from_string(entered_time)
except ValueError:
print("Must enter a time (ex: 5:09)")
return get_time_from_user(time_kind)
except ImportError:
print("Entered time not valid (1-12)")
return get_time_from_user(time_kind)
startTime = get_time_from_user("start")
timerTime = get_time_from_user("timer")
endTime = startTime + timerTime
print("End time: " + str(endTime))
def isValidHour(hour):
return (1 <= hour and hour <= 12)
def isValidMinute(minute):
return (0 <= minute < 60)
def isValidTime(hour, minute):
return (isValidHour(hour) and isValidMinute(minute))
def getStartTime():
try:
# Get starting time from user (hours, minutes)
enteredTime = input("Enter starting time (HH:MM): ").strip().split(':')
startHour, startMinute = map(int, enteredTime) # may throw ValueError
if not isValidTime(startHour, startMinute):
print("Entered time not valid")
startHour, startMinute = getStartTime()
except ValueError:
print("Must enter a time (ex: 5:09)")
startHour, startMinute = getStartTime()
return startHour, startMinute
def isValidTimerHour(timerHour):
return timerHour > 0
def getTimerHour():
try:
# Get timer value from user (hours)
enteredTimerHour = input("Enter timer value: ")
timerHour = int(enteredTimerHour)
if not isValidTimerHour:
print("Entered value not valid")
timerHour = getTimerHour()
except ValueError:
print("Must enter a number")
timerHour = getTimerHour()
return timerHour
def calculateEndHour(startHour, timerHour):
sumHours = startHour + timerHour
if not isValidHour(sumHours):
endHour = sumHours % 12
else:
endHour = sumHours
return endHour
def printEndTime(endHour, endMinute):
endTime = "{0}:{1:02d}".format(endHour, endMinute)
print(endTime)
startHour, startMinute = getStartTime()
timerHour = getTimerHour()
endHour = calculateEndHour(startHour, timerHour)
printEndTime(endHour, startMinute)
@qubitz
Copy link
Author

qubitz commented Mar 24, 2017

Wanted to practice some clean coding with some inspiration from Clean Code: A Handbook of Agile Software Craftsmanship with my new Python skillzz.

Each file offers a different implementation, each better than the last. The order goes:

  • Time_expanded.py (most mundane)
  • Time_shortended.py (functional)
  • Time_OOP.py (uses abstraction! aka best)

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