Pyschools Topic 3 Q 9 - python

I'm new to programming and I was trying out this question on Pyschools.
Can anyone help me?
Write a function that converts the time to 24hr format.
Examples
>>> time24hr('12:34am')
'0034hr'
>>> time24hr('12:15pm')
'1215hr'
This question is under conditionals.

Remove the "am" or "pm" from the end and save it off somewhere
Split on the ":", so you have hours and minutes separate
If the time is "am", print the hour unless the hour is "12", in which case print "00"
Otherwise (if the time is "pm"), print the hour + 12 unless the hour is "12", in which case print "12"
Print the minutes

def time24hr(tstr):
time_list = tstr[:-2].split(':')
time_int = [int(x) for x in time_list]
am_pm = tstr[-2:]
hours = time_int[0]
minutes = time_int[1]
if am_pm == 'am':
if hours < 12:
hours = hours + 12
return "%02d%02dhr" % (hours,minutes)
else:
return "00%2dhr" % (minutes)
else:
if hours < 12:
hours = hours + 12
return "%02d%02dhr" % (hours,minutes)
else:
return "%02d%02dhr" % (hours,minutes)

def time24hr(tstr):
newTime = ""
if "am" in tstr:
for i in tstr:
if i not in ":am":
newTime += i
if "12" in newTime[:2]:
newTime = newTime.replace("12", "00")
return newTime + "hr"
elif len(newTime) == 3:
newTime = "0" + newTime + "hr"
return newTime
elif "pm" in tstr:
for i in tstr:
if i not in "pm":
newTime += i
if "10" in newTime[:2]:
newTime = newTime.replace("10", "22")
newTime = newTime.replace(":", "")
elif "11" in newTime[:2]:
newTime = newTime.replace("11", "23")
newTime = newTime.replace(":", "")
elif "12" in newTime[:2]:
newTime = newTime.replace(":", "")
elif "1" in newTime[:1]:
newTime = newTime.replace("1", "13")
newTime = newTime.replace(":", "")
elif "2" in newTime[:1]:
newTime = newTime.replace("2", "14")
newTime = newTime.replace(":", "")
elif "3" in newTime[:1]:
newTime = newTime.replace("3", "15")
newTime = newTime.replace(":", "")
elif "4" in newTime[:1]:
newTime = newTime.replace("4", "16")
newTime = newTime.replace(":", "")
elif "5" in newTime[:1]:
newTime = newTime.replace("5", "17")
newTime = newTime.replace(":", "")
elif "6" in newTime[:1]:
newTime = newTime.replace("6", "18")
newTime = newTime.replace(":", "")
elif "7" in newTime[:1]:
newTime = newTime.replace("7", "19")
newTime = newTime.replace(":", "")
elif "8" in newTime[:1]:
newTime = newTime.replace("8", "20")
newTime = newTime.replace(":", "")
elif "9" in newTime[:1]:
newTime = newTime.replace("9", "21")
newTime = newTime.replace(":", "")
return newTime + "hr"

Comments inline
def time24hr(s):
c = s.split(':') # Split string to list ["hh", "mmAP"] AP is "am" or "pm"
h = int(c[0]) # convert hours string to integer
m = int(c[1][0:-2]) # remove "AP" from "mmAP" and convert to integer. This will handle "mAP" input correctly as well.
h = h % 12 if s[-2:] != 'pm' else 12 if h == 12 else h + 12 # convert hours to 24hr format, handling edge cases.
return "%02d%02dhr" % (h, m) # Print hours and minutes as %02d - two digits, potentially filling with zeroes

This worked for me better. I improved this based on the accepted answer.
Instead of using a loop to convert the list to integers, I call the values from the actual list and declare the variable as int type. Simple!
I still see no reason to add hours + 12 when the time is am and less than 12 hours–12hr and 24hr time format have the same format for am time, an exception of 12 am. Therefore, I just return the initial values from the function for the morning, and when it is exactly 12, I return hours %12 to have 00 am.
def time24hr(tstr):
time_list = tstr[:-2].split(':')
t_list_int = []
for e in time_list:
t_list_int.append(e)
minutes = int(time_list[1])
hours = int(time_list[0])
am_pm = tstr[-2:]
if am_pm == 'am':
if hours == 12:
return "%02d%02dhr" % (hours%12,minutes)
elif hours <12:
return "%02d%02dhr" %(hours, minutes)
else:
if hours == 12:
return "%02d%02dhr" %(hours, minutes)
elif hours <12:
return "%02d%02dhr" %(hours+12, minutes)
print(time24hr('9:34pm'))
print(time24hr('12:00am'))

def time24hr(tstr):
time=tstr.replace(':','')
if 'am' in time:
tim=int(time.replace('am',''))
elif 'pm' in time:
tim=int(time.replace('pm',''))
mini=tim%100
hour=tim//100
if mini<10:
mini='0'+str(mini)
else:
mini=str(mini)
if 'am' in time:
if hour<10:
hour='0'+str(hour)
elif hour==12:
hour='0'+str(hour-12)
time1=time.replace('am','')
time1=str(hour)+str(mini)+'hr'
elif 'pm' in time:
if hour<12:
hour=12+hour
elif hour==12:
hour=hour
time1=time.replace('pm','')
time1=str(hour)+str(mini)+'hr'
return time1

def time24hr(tstr):
a = tstr
b = int(a[:2])+12
if a[-2:] =='am' and a[:2]=='12':
return '\'00'+a[3:-2]+'hr\''
elif a[-2:]=='pm' and a[:2]=='12':
return '\'12'+a[3:-2]+'hr\''
else:
if a[-2:] =='pm':
return "\'"+str(b)+a[3:-2]+'hr\''
else:
return "'"+a[:2]+a[3:-2]+'hr\''
print time24hr('12:15pm')
# '1215hr'
print time24hr('12:15pm')
print time24hr('12:34am')
# '0034hr'
print time24hr('08:34am')
# '0834hr'
print time24hr('08:34pm')
'2034hr'

For me it works (but it isn't too pretty :'C):
def time24hr(tstr):
a=list(tstr)
if len(a)==6:
a.insert(0,'0')
if a[5]=='a' and a[0]=='1' and a[1]=='2':
del a[2]
del a[4:6]
a.append('h')
a.append('r')
a[0]='0'
a[1]='0'
w=''.join(a)
return w
elif a[5]=='p':
del a[2]
del a[4:6]
a.append('h')
a.append('r')
x=a[0]+a[1]
print x
y=int(x)
print y
if y<12:
z=y+12
g=str(z)
a[0:2]=g
w=''.join(a)
return w
else:
w=''.join(a)
return w
else:
del a[2]
del a[4:6]
a.append('h')
a.append('r')
w=''.join(a)
return w

Related

I get a spare output out of nowhere

My code right here emits a strange output, it gives me the second part of inp_a even though I didn`t ask for it. couldn't find the reason why.
Thanks in advance for the help
inp_a = input("What`s the time you want to start from? ")
military_time = input("is it AM or PM: ").upper()
inp_b = input("How long would you like to wait? ")
day = input("What`s the day today?\nThe day must be one of the weekdays ")
inp_a = inp_a.split(":")
inp_b = inp_b.split(":")
day = day.lower()
if military_time == "AM":
inp_a[0] = inp_a[0]
elif military_time == "PM":
inp_a[0] = int(inp_a[0]) + 12
inp_a[0] = str(inp_a[0])
try:
convert_a1 = int(inp_a[0])
convert_a2 = int(inp_a[1])
convert_b1 = int(inp_b[0])
convert_b2 = int(inp_b[1])
except:
print("-"*50)
print("One of the inputs is incorrect, try again")
while True:
if day == "sunday":
break
elif day == "monday":
break
elif day == "tuesday":
break
elif day == "wednsday":
break
elif day == "thursday":
break
elif day == "friday":
break
elif day == "saturday":
break
else:
print(day,"is not one of the weekdays try again")
quit()
rl_time = int(inp_a[0])*60 + int(input(inp_a[1]))
time2add = int(inp_b[0]*60) + int(input(inp_b[1]))
result = rl_time + time2add
hh = result // 60
mm = result % hh
The error is in this part of the code:
rl_time = int(inp_a[0])*60 + int(input(inp_a[1]))
time2add = int(inp_b[0]*60) + int(input(inp_b[1]))
You're calling input again for no reason, and input prompts the user with its argument (in this case inp_a[1], which is the extra output you're seeing). If you enter something it'll do the same thing on the next line with inp_b[1].
Here's a fixed version of the full thing -- you can simplify a lot by just doing the int conversion once, rather than converting to int, converting back to str, back to int, etc. You also had your while loop in the wrong spot if the intent is to re-prompt the user for new values when something is incorrect.
while True:
inp_a = input("What`s the time you want to start from? ")
military_time = input("is it AM or PM: ").upper()
inp_b = input("How long would you like to wait? ")
day = input("What`s the day today?\n"
"The day must be one of the weekdays"
).lower()
try:
ah, am = map(int, inp_a.split(":"))
bh, bm = map(int, inp_b.split(":"))
except (TypeError, ValueError):
print("Time must be entered as HH:MM")
continue
if day not in ("monday", "tuesday", "wednesday", "thursday", "friday"):
print(f"{day.title()} is not one of the weekdays, try again.")
continue
break
if military_time == "PM":
ah += 12
rl_time = ah * 60 + am
time2add = bh * 60 + bm
result = rl_time + time2add
hh, mm = divmod(result, 60)

A function that can take timestamp from user as input and convert it into a total number of seconds

I've been trying to write a script that would accept a text as a timestamp from the user, convert it to a total number of seconds, and then start a timer. For example
Time: 1h:1m:30s
>> 3690s
I've come up with this solution for taking the timestamp from the user
def toSecond(timestring):
t = 0
remove_space = lambda str: str.replace(" ", "")
timestring = remove_space(timestring)
try:
if (":") in timestring:
time = timestring.split(":")
try:
for i in time:
if i[-1] in ("s", "S" "M", "m", "h", "H") and i[0].isnumeric():
if i[-1] in ("h", "H"):
t += int(i[:-1]) * 3600
elif i[-1] in ("m", "M"):
t += int(i[:-1]) * 60
else:
t += int(i[:-1])
else:
print("No num or no char Provided")
except IndexError:
print("nothing provided")
else:
if (
timestring[-1] in ("s", "S" "M", "m", "h", "H")
and timestring[0].isnumeric()
):
if timestring[-1] in ("h", "H"):
t += int(timestring[:-1]) * 3600
elif timestring[-1] in ("m", "M"):
t += int(timestring[:-1]) * 60
else:
t += int(timestring[:-1])
elif timestring.isnumeric():
t += int(timestring)
else:
print("No time Provided")
except ValueError:
print("Error Value")
return t
This solution is working, However, I was wondering how can I do this more shorter and more efficiently.
Extract the hours, minutes and seconds and then use datetime.timedelta like this:
from datetime import timedelta
ts = "1h:1m:30s"
time_indicators = ["H", "h", "M", "m", "S", "s"]
for ind in time_indicators:
ts = ts.replace(ind, "")
hours, minutes, seconds = ts.split(":")
print(timedelta(hours=int(hours), minutes=int(minutes), seconds=int(seconds)).total_seconds())
If you want to catch bad user input - using split then a regex:
import re
UNIT_TO_SECONDS = {
'h': 3600,
'm': 60,
's': 1
}
def parse_part(part):
match = re.match(r'^(\d+)([HhMmSs])$', part)
if match is None:
raise ValueError(f'"{part}" is not a valid part of time')
return (int(match.group(1)),match.group(2).lower() )
def to_seconds_part(part):
nb, unit = parse_part(part)
return nb * UNIT_TO_SECONDS[unit]
def to_seconds(user_input):
parts = user_input.split(':')
parts_seconds = list(map(to_seconds_part, parts))
return sum(parts_seconds)

datetime format over 24 hours

I'm trying to add time and have the output as hh:mm:ss, but when datetime gets over 24 hours it becomes x Days, hh:mm:ss. Is there anyway to only have hh:mm:ss greater than 24 hours?
import datetime
from datetime import timedelta
# intro
print("Welcome to TimeCalc")
print("Calculating Durations")
clear = True
while clear == True:
# first input
firstNumber = True
while firstNumber == True:
time_1 = input("Please enter a time [hh:mm:ss] including 0s: ")
if len(time_1) > 0 and len(time_1) >= 8 and time_1[-6] == ":" and time_1[-3] == ":" and int(time_1[-5:-3]) < 60 and int(time_1[-2:]) < 60:
hours_1 = time_1[:-6]
minutes_1 = time_1[-5:-3]
seconds_1 = time_1[-2:]
hours_1 = int(hours_1)
minutes_1 = int(minutes_1)
seconds_1 = int(seconds_1)
firstNumber = False
else:
print("Invalid Syntax")
time_1 = datetime.timedelta(hours=hours_1, minutes=minutes_1, seconds=seconds_1)
cont = True
while cont == True:
# second input
secondNumber = True
while secondNumber == True:
time_2 = input("Please enter a time to add [hh:mm:ss] including 0s: ")
if len(time_2) > 0 and len(time_2) >= 8 and time_2[-6] == ":" and time_2[-3] == ":" and int(time_2[-5:-3]) < 60 and int(time_2[-2:]) < 60:
hours_2 = time_2[:-6]
minutes_2 = time_2[-5:-3]
seconds_2 = time_2[-2:]
hours_2 = int(hours_2)
minutes_2 = int(minutes_2)
seconds_2 = int(seconds_2)
secondNumber = False
else:
print("Invalid Syntax")
time_2 = datetime.timedelta(hours = hours_2, minutes = minutes_2, seconds = seconds_2)
total = time_1 + time_2
print("The total duration is: " + str(total))
# continue, clear, or exit
choice = input("Continue: Y | Clear: N | Exit: X: ")
if choice == "Y" or choice == "y":
time_1 = total
elif choice == "N" or choice == "n":
cont = False
elif choice == "X" or choice == "x":
quit()
after total variable, can you try to put this code, maybe this is not a super solution but it works
seconds = int(total.total_seconds())
minutes, seconds = divmod(seconds, 60)
hours, minutes = divmod(minutes, 60)
print("The total duration is: {h:02d}:{m:02d}:{s:02d}".format(h=hours,
m=minutes, s=seconds))
Use the .strftime() method to format your datetime string.
For example,
>>> import datetime
>>> d = datetime.delta(hours=1)
>>> dt = datetime.datetime(2017,10,30,23,10,10) + d
>>> dt.strftime("%H:%M:%S")
'00:10:10'
Hope it help.

Update date in Python

so here is my problem, I am trying to do a little program that gives the user the next date when he will have to pay rent.
Here is my code:
curdate = datetime.date(2015, 01, 01)
rent_date = datetime.date(curdate.year, curdate.month+1, 01)
one_day = datetime.timedelta(days = 1)
one_week = datetime.timedelta(weeks = 1)
one_month = datetime.timedelta(weeks = 4)
def rent_date_calc(cd, rd):
if cd.month == 12:
rd.replace(cd.year+1, 01, 01)
else:
rd.replace(cd.year, cd.month+1, 01)
def time_pass(rd, cd, a, al):
if rd < cd:
for a in al:
a.finances -= a.rent
move_fwd = raw_input("Would you like to move forward one day(1), one week (2) or one month (3)?")
if move_fwd == "1":
curdate += one_day
elif move_fwd == "2":
curdate += one_week
else:
curdate += one_month
time_pass(rent_date, curdate, prodcomp, prodcomps)
rent_date_calc(curdate, rent_date)
print "Rent date: " + str(rent_date)
The problem I have is that rent_date always stays the same (2015-02-01)
Any idea why?
Your code is not altering anything because datetime is an immutable object, and when you call replace on it, it returns a new datetime, instead of modifying the first one.
You should return the new object from the function and assign it back to rent_date:
def rent_date_calc(cd, rd):
if cd.month == 12:
return rd.replace(cd.year+1, 01, 01)
else:
return rd.replace(cd.year, cd.month+1, 01)
...
rent_date = rent_date_calc(curdate, rent_date)
Your functions have to return a new rent date. You just need to add the following lines in your code:
return cd
new_rent_date = rent_date_calc(curdate, rent_date)
====================================================================
curdate = datetime.date(2015, 1, 1)
rent_date = datetime.date(curdate.year, curdate.month+1, 1)
one_day = datetime.timedelta(days = 1)
one_week = datetime.timedelta(weeks = 1)
one_month = datetime.timedelta(weeks = 4)
def rent_date_calc(cd, rd):
if cd.month == 12:
new_date = rd.replace(cd.year+1, 1, 1)
else:
new_date = rd.replace(cd.year, cd.month+1, 1)
return new_date
def time_pass(rd, cd, a, al):
if rd < cd:
for a in al:
a.finances -= a.rent
# Not sure what this function should return...
move_fwd = raw_input("Would you like to move forward one day(1), one week (2) or one month (3)?")
if move_fwd == "1":
curdate += one_day
elif move_fwd == "2":
curdate += one_week
else:
curdate += one_month
# time_pass(rent_date, curdate, prodcomp, prodcomps)
new_rent_date = rent_date_calc(curdate, rent_date)
print "Rent date: " + str(new_rent_date)

How to count elapsed time on Python

I have the following code:
def base(nomor)
day = localtime.tm_wday
time = localtime.tm_hour
no = str(nomor)
dosen = cek_dosen(no)
if dosen == 'null':
no_dosen()
elif dosen != 'null':
ada_dosen()
matkul = cek_jadwal(day,time,dosen)
if matkul == 'null':
no_jadwal()
elif matkul != 'null':
ada_jadwal()
pertemuan = cek_pertemuan(matkul)
print pertemuan
if pertemuan > 1:
cek_before(pertemuan)
filename = ''.join([dosen, matkul, str(pertemuan), ".pptx"])
else:
filename = ''.join([dosen, matkul, str(pertemuan), ".pptx"])
grabfile(filename)
os.system(''.join(["loimpress ",filename]))
pertemuan = pertemuan + 1
update_pertemuan(pertemuan,matkul)
mulai()
if __name__ == '__main__':
mulai()
while True:
data = port.read()
count += 1
if count == 1:
if str(data) != start:
nomor = ''
count = 0
elif 2 <= count <= 13:
nomor = nomor + str(data)
elif count == 16 and str(data) == stop:
base(nomor)
nomor = ''
count = 0
I want to count time elapse from after data = port.read() until after grabfile(filename). I've used start = time.time() after data = port.read and end = time.time() after grabfile, time = end - start, but it stuck after data = port.read() so I use Ctrl + C to stop that. If I put start = time.time() after no = str(nomor), I get Attribute Error : 'int' object has no attribute 'time'.
How do I count the elapsed time?
from time import clock
start = clock()
...
print "Time taken = %.5f" % (clock() - start)
Summarized:
import datetime
if __name__ == "__main__":
d1 = datetime.datetime.now()
data = port.read()
# Do more things ...
tdelta = datetime.datetime.now() - d1
print(tdelta.total_seconds()) # This is your answer
Take a look at the python timeit module.
Basic example:
>>> import timeit
>>> timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)

Categories

Resources