Adjusting methods within a class - python

I am having issues with properly implementing the following:
Remove __hours and __minutes.
Adjust the implementation of the mutator and accessor methods. For
example, for __init__(hr, min, sec), validate the values, then set
__seconds = hr * 60 * 60 + min * 60 + sec. This will store the time as seconds. Adjust all the methods to work with __seconds. getSecond()
can use __seconds mod 60 to return only the seconds in the time. Test
all the methods to make sure they still work. (mod is modulus, the
remainder after a division.)
I have used this in my code self.setSecond = (hour * 60 * 60) + (minute * 60 + second)
To properly represent hour, minute and seconds to just seconds I am however having issues with implementing the rest of the program. I'm not sure if I should be printing out just seconds? Also when I change my getSecond() function to return % 60 it is not doing so. I'm assuming because I'm not properly calling it?
Here is my code thus far:
class Clock(object):
def __init__(self, hour, minute, second):
self.setHour(hour)
self.setMinute(minute)
self.setSecond = (hour * 60 * 60) + (minute * 60 + second)
def setHour(self, hour):
self.__hour = hour
if self.__hour > 23:
self.__hour = 0
elif self.__hour < 0:
self.__hour = 0
def getHour(self):
return self.__hour
def setMinute(self, minute):
self.__minute = minute
if self.__minute > 60:
self.__minute = 0
elif self.__minute < 0:
self.__minute = 0
def getMinute(self):
return self.__minute
def setSecond(self, second):
self.__second = second
if self.__second > 60:
self.__second = 0
elif self.__second < 0:
self.__second = 0
def getSecond(self):
return self.__second
def __str__(self):
if self.__hour > 11:
return 'The Time is {}:{}:{} PM'.format(self.__hour, self.__minute, self.__second)
else:
return 'The Time is {}:{}:{} AM'.format(self.__hour, self.__minute, self.setSecond)
stopwatch = Clock(3, 2, 1)
print(stopwatch)
Note: I am aware that this code isn't very pythonic but that is how I was told to keep it (I apologize).

There are 6 changes required primarily:
You don't need to maintain hours and minutes in the class. You maintain only the seconds. So remove the setHour and setMinute methods.
Because you don't maintain the hours and minutes, the getHour and getMinute methods should do the required calculation.
def getHour(self):
return int(self.__second / 3600)
def getMinute(self):
return int(self.__second / 60) % 60
In the init function, call to self.setSecond is not correct. It should be:
def __init__(self, hour, minute, second):
if hour > 23 or hour < 0:
hour = 0
if minute > 60 or minute < 0:
minute = 0
if second > 60 or second < 0:
second = 0
self.setSecond((hour * 60 * 60) + (minute * 60 + second))
And although you mentioned, your getSecond() method does not do a seconds % 60. It should be:
def getSecond(self):
return self.__second % 60
In method def __str__, instead of directly accessing the hours, minutes, seconds, use the accessor methods:
def __str__(self):
if self.getHour() > 11:
return 'The Time is {}:{}:{} PM'.format(self.getHour(), self.getMinute(), self.getSecond())
else:
return 'The Time is {}:{}:{} AM'.format(self.getHour(), self.getMinute(), self.getSecond())
The setSeconds method should not have the check for > 60 because now you will be storing a large number here:
def setSecond(self, second):
self.__second = second
if self.__second < 0:
self.__second = 0

Related

How add two entered number in hour format or seconds

Hi I want to add two elements in the class in Python with magic method 'add' and 'radd' ,that they show the time, the elements can be entered in two different formats: in seconds or in the hour format'16: 03: 43 '
Someone can guide me how can i add seconds with format hour:
(65480 seconds + 16:03:43 hour)
class UserTime:
def __init__(self,uTime):
self.time=uTime
self.backup=0
def __add__(self, other):
return self.time + other.time
'''def conv_ToHours(self,seconds):
seconds = seconds % (24 * 3600)
hour = seconds // 3600
seconds %= 3600
minutes = seconds // 60
seconds %= 60
return "%d:%02d:%02d" % (hour, minutes, seconds)'''
def conve_ToSeconds(self):
"""Get seconds from time."""
h, m, s = self.time.split(':')
return int(h) * 3600 + int(m) * 60 + int(s)
def __add__(self, other):
global x
x=int(self.conve_ToSeconds())+int(other.conve_ToSeconds())
return x
def conv_ToHours(self):
if x> 0 :
seconds = x
seconds = seconds % (24 * 3600)
hour = seconds // 3600
seconds %= 3600
minutes = seconds // 60
seconds %= 60
return "%d:%02d:%02d" % (hour, minutes, seconds)
else:
print('Wrong Wrong')
x= int(input('enter time:'))
y = int(input('enter time: '))

How convert seconds in minutes and seconds (mm:ss)

Is it possible to convert seconds into minutes and seconds with this format "mm:ss"?
I try to use datetime.timedelta(seconds=seconds) but it returns hh:mm:ss format.
Thanks in advance!
You can use divmod for this.
hours, remainder = divmod(someSecondsValue, 3600)
minutes, seconds = divmod(remainder, 60)
print(f"{minutes:02}:{seconds:02}")
You can get number of minutes by dividing by 60
and number of seconds by calculating reminder by 60.
total_seconds = 10000
minutes = int(total_seconds / 60)
seconds = total_seconds % 60
print(f"{minutes}:{seconds}")
You could also make a small custom time class and use __format__ to control how you wanna print it out:
class MyTime:
def __init__(self, seconds: int):
self.total_seconds = seconds
def __format__(self, format_spec: str) -> str:
if format_spec == 'm':
minutes = self.total_seconds // 60
seconds = self.total_seconds % 60
return f'{minutes:02}:{seconds:02}'
if format_spec == 'h':
hours = self.total_seconds // 3600
minutes = (self.total_seconds - hours * 3600) // 60
seconds = self.total_seconds % 60
return f'{hours:02}:{minutes:02}:{seconds:02}'
# ...other formats...
return str(self.total_seconds)
x = MyTime(3674)
print(f'Seconds: {x}') # 3674
print(f'Minutes & seconds: {x:m}') # 61:14
print(f'Hours & minutes & seconds: {x:h}') # 01:01:14

How to code a function that converts label to seconds?

def seconds_to_label_converter(seconds):
hours = divmod(seconds,3600)[0]
minutes = divmod(seconds-(hours*3600),60)[0]
remaining_seconds = seconds-((hours*3600)+(minutes*60))
if remaining_seconds == 0 and hours == 0 and minutes == 0:
time_label = "No info"
elif hours > 1:
time_label = f"{hours} Hours {minutes} Minutes {remaining_seconds} Seconds"
elif hours == 1:
time_label = f"{hours} Hour {minutes} Minutes {remaining_seconds} Seconds"
elif hours == 0 and minutes > 1:
time_label = f"{minutes} Minutes {remaining_seconds} Seconds"
elif hours == 0 and minutes == 1:
time_label = f"{minutes} Minute {remaining_seconds} Seconds"
elif hours == 0 and minutes == 0:
time_label = f"{remaining_seconds} Seconds"
print(time_label)
seconds_to_label_converter(21254)
I have a "seconds to label converter" like this. Now I need a function that will do the opposite. But I don't know how to do it.
for example:
label_to_seconds_converter("5 Hours 54 Minutes 14 Seconds")
# >>> OUTPUT = 21254
Try this. Extract specific strings using re and then extract numbers
import re
def seconds_to_label_converter(seconds):
x=re.findall(r'\b\d+\s*hour[s]?\b',seconds.lower())
y=re.findall(r'\b\d+\s*minute[s]?\b',seconds.lower())
z=re.findall(r'\b\d+\s*second[s]?\b',seconds.lower())
secs=0
if x:
for i in re.findall(r'\d+',''.join(x)):
secs +=3600*int(i)
if y:
for i in re.findall(r'\d+',''.join(y)):
secs +=60*int(i)
if z:
for i in re.findall(r'\d+',''.join(z)):
secs +=int(i)
return secs
print(seconds_to_label_converter('4 hours 50 seconds'))
Returns
14450
print(seconds_to_label_converter('4 hours 10 minutes 50 seconds'))
returns
15050
print(seconds_to_label_converter('5 Hours 54 Minutes 14 Seconds'))
Returns
21254
You could do something like this:
def text_to_second(txt: str):
items = [int(x) if x.isnumeric() else x for x in txt.split() ]
seconds = 0
for i in range(0,len(items),2):
a = items[i+1]
if a.lower()=="hours" or a.lower()=="hour":
seconds += 3600*items[i]
elif a.lower()=="minutes" or a.lower()=="minute":
seconds += 60*items[i]
elif a.lower()=="seconds" or a.lower()=="second":
seconds += items[i]
return seconds
print(text_to_second("5 Hours 54 Minutes 14 Seconds"))
#output: 21254
Another option would be to use the zip function:
def label_to_seconds_converter(label: str) -> int:
label_list = label.split()
seconds = 0
for amount, word in zip(label_list[::2], label_list[1::2]):
if "hour" in word.lower():
seconds += int(amount) * 3600
elif "minute" in word.lower():
seconds += int(amount) * 60
else:
seconds += int(amount)
return seconds
print(label_to_seconds_converter("5 Hours 54 Minutes 14 Seconds"))
result
21254
try this :
def label_to_seconds(label):
times = re.findall(r'\b\d+\s*[hours|minutes|seconds]?\b', label.lower())
list_len = len(times)
if list_len == 3:
return int(times[0].strip()) * 3600 + int(times[0].strip()) * 60 + int(times[0].strip())
if list_len == 2:
return int(times[0].strip()) * 60 + int(times[1].strip())
if list_len == 1:
return int(times[0].strip())
else:
print('Invalid Format')

Time residual function in Python

I have 2 fields in the database: confirmed_at and preparation_time
I would like to get two simple functions that should return:
(a) the time residual
and
(b) the % of time remaining.
This is my logic which I am trying to achieve:
when order is confirmed_at I update the database with datetime.now() and preparation_time is indicated in minutes and stored as integer (for example 5 min is stored as 5)
completed_time is confirmed_at + preparation_time
time_remaining is completed_time - now()
order status is completed_time / now() * 100
These are my functions but I cannot make them work:
def get_remaining_time(self):
start_time = datetime(self.confirmed_at)
end_time = (start_time + datetime.timedelta(0,self.preparation_time*60)).time() # days, seconds.
return end_time - datetime.now()
def get_order_status(self):
end_time = (datetime(self.confirmed_at) + datetime.timedelta(0,self.preparation_time*60)).time()
return end_time / datetime.now() * 100
What kind of type returned from functions? If it's timedelta - just turn it into date.
So here it is the solution that I've managed to work out
def get_remaining_time(self):
start_time = self.confirmed_at
end_time = start_time + timedelta(
0, self.preparation_time * 60
) # days, seconds.
return end_time - timezone.now()
def get_time_left(self):
left = self.get_remaining_time()
sec = int(left.total_seconds())
if sec > 60:
return "{} minutes".format(int(sec / 60))
elif sec < 60 and sec > 0:
return "{} seconds".format(sec)
else:
return 0
def get_order_status(self):
left = int(self.get_remaining_time().total_seconds())
if left < 0:
return 100
else:
return round((1 - left / (self.preparation_time * 60)) * 100)

So I want to make a clock in Python that displays both A.M. and P.M

So I have this here.
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours = 2
if Hours == 12:
Hours = 1
Minutes = 0
break
ReadLine = ("\t{0:>2} : {1:>2}\r").format(Hours, Minutes)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
Just for the record, I have made sure that the indentations are correct, they look a little screwy here. And I realize that I have nothing set for A.M./P.M. as of yet.. Any help is appreciated for this noob.
Thank you - Matt.
Edit:
>>> 2: 0 2: 0 2: 0
This is what is printing out now, the minutes have not updated. I'm obviously missing something. Once again thanks for any help, and I am sorry if this is a repeat, I have searched for an answer, but none was found. Thanks - Matt.
Edit #2- I figured it out. I used a bit of both of the answers, and whilst I accept the fact that it will be slow it does what I want it to do.
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
AM_PM = "AM" if Hours < 12 else "P.M"
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours += 1
if Hours == 24:
Hours = 1
Minutes = 0
break
ReadLine = ("\t{:>2} : {:>2} {}\r").format(Hours, Minutes, AM_PM)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
You know, it seems no matter how hard I try, I cannot get this darned indentation to look right. Oh well, I hope you can understand it's just tabbed a bit to the right.
your code print nothing because you put the code that print to stdout inside the if statements. so it would print only when Minutes == 60 and Hours == 12 (which will never happend because of you dont increament Hours as meantioned in the comments.
try this:
import sys
import os
import time
def clock():
Minutes = 0
Hours = 1
ampm = "AM"
while True:
Minutes += 1
if Minutes == 60:
Minutes = 0
Hours += 1
if Hours == 12:
Hours = 1
Minutes = 0
ampm = ("AM" if (ampm == "PM") else "PM")
ReadLine = ("\t{0:>2} : {1:>2} {2} \r").format(Hours, Minutes,ampm)
sys.stdout.write(ReadLine)
sys.stdout.flush()
time.sleep(60)
clock()
import datetime
then = now = datetime.datetime.now()
minutes = 0
hours = 0
while True:
now = datetime.datetime.now()
if (now-then).total_seconds() > 60:
then += datetime.timedelta(minutes=1)
minutes += 1
if minutes == 60:
minutes = 0
hours += 1
if hours == 24:
hours = 0
am_pm = "AM" if hours < 12 else "PM"
print("{:>2}:{:>02} {}".format((hours+11)%12+1, minutes, am_pm))
Note that I do away with time.sleep as it's not guaranteed to sleep for exactly the time requested (indeed you will always be running slightly slow by that clock) and instead compare a current time to the last time a minute passed and see if the total seconds are more than 60. If so, increment minutes, if minutes is 60, increment hours and check for rollover and am_pm switch. Afterwards, print the time.
If you're wanting to stretch your legs a little, try implementing it in a class! Ooh ooh, and threading too!
import datetime
import threading
import queue
class Clock(object):
def __init__(self, current_time=None):
if isinstance(current_time, datetime.datetime):
hours, minutes = current_time.hour, current_time.minute
else:
hours = minutes = 0
self.hours = hours
self.minutes = minutes
self.q = queue.Queue()
def checkTime(self):
try:
self.q.get_nowait() # time has updated, or exception thrown
self.updateTime()
self.q.task_done()
except queue.Empty:
pass # time hasn't updated
def updateTime(self, num_mins=1):
self.minutes += 1
if self.minutes == 60:
self.minutes = 0
self.hours += 1
if self.hours == 24:
self.hours = 0
print(self)
def minutePassed(self):
then = datetime.datetime.now()
while True:
now = datetime.datetime.now()
if (now-then).total_seconds() > 60:
then += datetime.timedelta(minutes=1)
self.q.put('_') # put something there, doesn't matter what
def __str__(self):
am_pm = "AM" if self.hours < 12 else "PM"
return "{:>2}:{:>02} {}".format((self.hours+11)%12+1,
self.minutes, am_pm)
def start(self):
t = threading.Thread(target=self.minutePassed)
t.daemon=True
t.start()
while True:
self.checkTime()
clock = Clock(datetime.datetime.now())
clock.start()

Categories