# Alarm clock printing

I know there must be an easier way to write this but I'm stuck in over-complicating mindset instead of just following the Zen of Python. Please help me simplify this.

Given a day of the week encoded as 0=Sun, 1=Mon, 2=Tue, ...6=Sat, and a boolean indicating if we are on vacation, return a string of the form "7:00" indicating when the alarm clock should ring. Weekdays, the alarm should be "7:00" and on the weekend it should be "10:00". Unless we are on vacation -- then on weekdays it should be "10:00" and weekends it should be "off".

alarm_clock(1, False) → '7:00'
alarm_clock(5, False) → '7:00'
alarm_clock(0, False) → '10:00'

def alarm_clock(day, vacation):

weekend = "06"
weekdays = "12345"
if vacation:
if str(day) in weekend:
return "off"
else:
return "10:00"
else:
if str(day) in weekend:
return "10:00"
else:
return "7:00"


I don't think it can get much simpler than this (Pythonic, easy to read, performance great enough to never be a bottleneck):

def alarm_clock(day, vacation):
weekend = int(day) in (0, 6)
if weekend and vacation:
return 'off'
elif weekend or vacation:
return '10:00'
return '7:00'


I came up with this after creating a weekend boolean value and then checking the return values alarm_clock should have:

return_values = {
# (weekend, vacation): Return value,
(True, True): 'off',
(True, False): '10:00',
(False, True): '10:00',
(False, False): '7:00'
}


As you can see, if both are True (if weekend and vacation:), we should return 'off', and if one of them is True (if weekend or vacation:), we should return 10:00 regardless of which one. Else return 7:00

• I see you omitted the word "else", is that Pythonic? Commented Jul 10, 2015 at 16:43
• @noob81 That's everyone's personal preference, but it's often considered more pythonic to emit the "else" Commented Jul 10, 2015 at 16:46
• @noob81 Actually, I take that back. It's just everyone's personal preference, there's absolutely no guidelines to whether you should emit it or not. Often depends on the situation :) Commented Jul 10, 2015 at 17:25
1. You don't use weekdays.
2. You can have two return statements. (Shown below).

This keeps the same logic, it just removes the need for so meany return statements.

def alarm_clock(day, vacation):
weekend = "06"
if vacation:
return "off" if str(day) in weekend else "10:00"
else:
return "10:00" if str(day) in weekend else "7:00"


I would improve it further by adding a check, that you enter a number 0-6.

if not (0 <= day <= 6):
return "-:--"


1. using 10:00 as default:
2. only check for weekend
3. you might replace (str(day) in weekend) by (0 == day %6) but it is harder to understand

Code:

def alarm_clock(day, vacation):
weekend = "06"
if vacation and (str(day) in weekend):
return "off"
else:
if not (str(day) in weekend):
return "7:00"
return "10:00"


The bit more cryptic version:

def alarm_clock(day, vacation):
if vacation and 0 == day % 6:
return "off"
else:
if 0 != day % 6:
return "7:00"
return "10:00"

• if str(day) not in weekend would be the preferred construction according to PEP8. Commented Jul 10, 2015 at 15:54

Building on @Joe Wallis' answer, I would shorten it as follows:

def alarm_clock(day, vacation):
weekend = "06"

times = {"weekend": "10:00", "weekday": "7:00"}
if vacation:
times = {"weekend": "off", "weekday": "10:00"}

return times['weekend'] if str(day) in weekend else times['weekday']


Which could be further shortened to (detrimental to readability though):

def alarm_clock(day, vacation):
times = {"weekend": "off", "weekday": "10:00"} if vacation \
else {"weekend": "10:00", "weekday": "7:00"}

return times['weekend'] if str(day) in "06" else times['weekday']


The advantages are that you have a dict with the weekend/weekday times, so you only need one generic return statement. The magic/hardcoded string in the further shortened version is a no-no though. Furthermore, you could extend the function to allow for custom times to be passed in, as such:

def alarm_clock(day, vacation, times={}):
times = times.get('regular', {"weekend": "10:00", "weekday": "7:00"})
if vacation:
times = times.get('vacation', {"weekend": "off", "weekday": "10:00"})

return times['weekend'] if str(day) in "06" else times['weekday']


You can then call it as such:

times = {'regular': {'weekend': "9:00", "weekday": "7:00"}, "vacation": {"weekend": "12:00", "weekday": "6:00"}}
alarm_clock(2, False, times)