Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Timestamp and keeping track of time
-
You have even a button for this
-
room_with_stimes_dict = {} room_with_etimes_dict = {} room_start_times_dict = {} class Room (object): def __init__ (self, room_num = None, assigned_house_keeper = None, room_start_time = None, room_end_time = None, room_start_cleaning = None, iso_type = None, running_time = None, assigned_nurse = None, assigned_patient = None): self.room_num = room_num self.assigned_house_keeper = assigned_house_keeper self.room_start_time = room_start_time self.room_end_time = room_end_time self.iso_type = iso_type self.running_time = running_time self.assigned_nurse = assigned_nurse self.assigned_patient = assigned_patient room_with_stimes_dict = {} room_with_etimes_dict = {} room_start_times_dict = {} def __str__(self): return f'Room: {self.room_num} \nAssigned Nurse: {self.assigned_nurse} \nIso Type: {self.iso_type}' def room_start_time(self): room_start_time = datetime.datetime.now() room_start_times_dict [self.room_num] = room_start_time.strftime('%H:%M') return bed_start_time def bed_start_time(self): self.bed_start_time = datetime.datetime.now() room_with_stimes_dict [self.room_num] = self.bed_start_time.strftime('%H:%M') return self.bed_start_time def bed_end_time(self): self.bed_end_time = datetime.datetime.now() room_with_etimes_dict [self.room_num] = self.bed_end_time.strftime('%H:%M') return self.bed_end_time def add_room(self): pass #list of dirty rooms dirty_rooms = [430, 6218, 520, 452, 444, 423,660,123,877,223,254,220,659,315,550,5228] room_1 = Room() room_1.room_num = 430 room_1.iso_type = 'COVID' room_2 = Room() room_2.room_num = 6218 room_2.iso_type = 'None' room_3 = Room() room_3.room_num = 654 room_3.iso_type = 'influenza' room_4 = Room() room_4.room_num = 220 room_4.iso_type = 'None' #room start time start_t1 = room_1.bed_start_time() #time delay time.sleep(9) #room end time end_t1 = room_1.bed_end_time() time.sleep(3) start_t2 = room_2.bed_start_time() time.sleep(12) end_t2 = room_2.bed_end_time() time.sleep(3) start_t3 = room_3.bed_start_time() time.sleep(7) end_t3 = room_3.bed_end_time() time.sleep(3) start_t4 = room_4.bed_start_time() time.sleep(1) end_t4 = room_4.bed_end_time() #amount of time taken to clean the room elapsed_t1 = end_t1 - start_t1 elapsed_t2 = end_t2 - start_t2 elapsed_t3 = end_t3 - start_t3 elapsed_t4 = end_t4 - start_t4 #total time to clean all rooms total_time = elapsed_t1 + elapsed_t2 + elapsed_t3 + elapsed_t4 #avg time to clean a room avg_time = total_time / 4 #unsorted list of times times = [elapsed_t1, elapsed_t2, elapsed_t3, elapsed_t4] #sorted list by length of time. longest time is first sorted_times = sorted(times, reverse=True) #prints sorted list print(sorted_times,'\n') #test code print('Elapsed Time 1:') print(elapsed_t1,'\n') print('Elapsed Time 2:') print(elapsed_t2,'\n') print('Elapsed Time 3:') print(elapsed_t3,'\n') print('Total Time:') print(total_time,'\n') print('Avg Time:') print(avg_time,'\n') print('Room # and Start Times') print(room_with_stimes_dict, '\n') print('Room # and End Times') print(room_with_etimes_dict)
-
-
strftime('%H:%M')
You are storing in your global dicts only to the nearest minute. But your sleeps are a few seconds!
It is a really bad idea to have both an instance attribute, and an instance method with the same name.... because methods are attributes, so your init code is not doing what you think it is.
I'm honestly surprised this even runs, because it would seem you are overriding your various time methods with None inside your init method.
You also have some issues with missing"self" in a at least one method... Does this code actually run without error?
-
@resserone13, started thinking what this would look like in ”modern Python”, using data classes that came in 3.7 but need to be installed in Pythonista (Python 3.6) via stash.
Here’s a quick sketch that uses naive datetimes and does not cover per-bed times, among other failings:
from datetime import datetime, timedelta from typing import List from dataclasses import dataclass, field, asdict log_time_resolution = 60 # or 1 minute @dataclass(unsafe_hash=True) class Bed: number: int @dataclass(unsafe_hash=True) class HouseKeeper: name: str @dataclass class Room: number: int assigned: HouseKeeper beds: List[Bed] = field( default_factory=lambda: [ Bed(i) for i in range(1, 4+1) ]) def __hash__(self): return self.number @dataclass class Cleaning: room: Room housekeeper: HouseKeeper start_time: datetime = None end_time: datetime = None def end(self, end_time=None): self.end_time = end_time or datetime.now() @property def started(self): return bool(self.start_time) @property def completed(self): return bool(self.start_time and self.end_time) @property def duration(self): return (self.end_time - self.start_time) if self.completed else None def match(self, **kwargs): query = set(kwargs.items()) content = set(self.__dict__.items()) return query.issubset(content) class CleaningLog(list): def start_cleaning(self, room, housekeeper=None, start_time=None): housekeeper = housekeeper or room.assigned cleaning = Cleaning( room=room, housekeeper=housekeeper, start_time=start_time or datetime.now(), ) self.append(cleaning) return cleaning def total_time(self, **kwargs): seconds = sum([ cleaning.duration for cleaning in self if cleaning.completed and cleaning.match(**kwargs) ], timedelta()).seconds return timedelta(seconds=round(seconds, log_time_resolution)) if __name__ == '__main__': # Usage example import faker fake = faker.Faker() # 5 rooms with different housekeepers rooms = [ Room(number=i, assigned=HouseKeeper(name=fake.name())) for i in range(1, 5+1) ] first_room, second_room = rooms[:2] log = CleaningLog() # First cleaning by the assigned housekeeper # (Providing a time to simulate time passing) cleaning = log.start_cleaning(first_room) cleaning.end(datetime.now() + timedelta(minutes=10)) # Second cleaning by another housekeeper cleaning2 = log.start_cleaning( first_room, housekeeper=second_room.assigned, start_time=datetime.now() + timedelta(minutes=15), ) cleaning2.end(datetime.now() + timedelta(minutes=30)) # Get the total cleaning time of the first room: print( f'Total for Room {first_room.number}:', log.total_time(room=first_room) ) # Or first room by the assigned housekeeper: total_time = log.total_time( room=first_room, housekeeper=first_room.assigned, ) print( f'Total for {first_room.assigned.name}:', total_time )
-
@JonB your right. It was the strftime(). I’m only keeping track of minutes and my test code is only seconds. The code output looks like this.
[datetime.timedelta(0, 12, 2110), datetime.timedelta(0, 9, 5850), datetime.timedelta(0, 7, 1252), datetime.timedelta(0, 1, 2087)]
Elapsed Time 1:
0:00:09.005850Elapsed Time 2:
0:00:12.002110Elapsed Time 3:
0:00:07.001252Total Time:
0:00:29.011299Avg Time:
0:00:07.252825Room # and Start Times
{430: '12:56:42', 6218: '12:56:54', 654: '12:57:09', 220: '12:57:19'}Room # and End Times
{430: '12:56:51', 6218: '12:57:06', 654: '12:57:16', 220: '12:57:20'}
Room: 430
Assigned Nurse: None
Iso Type: COVID -
@mikael thanks for the response. I’m going to review this and learn. I’m sure you can tell I’m just starting out. I write my code with Pythonista on my iPhone 11. Your code looks completely different then mine.
-
@resserone13, I know that it is a very different approach and I am sorry for that, since it does not necessarily help you progress with yours. I tried to think what I would recommend for your code, and found I had to define a potential data model for myself first.
If there is something there that you can reuse, great. And please ask if I can clarify how something works or – even better – why I chose to do something in a specific way.
If it helps, I have also used Pythonista almost exclusively on my iPhone for years now. Of course the typing can be clumsy, but nothing prevents you from incrementally building something significant.
-
@mikael @mikael for sure. I been reviewing your code and I have picked up a few things. Like I have no Boolean test in my code and nothing really checking things. I also watched a video on data class and understand a bit more of why use chose them and why there is less code.
Why did you put end_time = end_time or datetime.now()
I’m guessing it so that end_time at least have a value of NONE.
And is this to check to se if the cleaning was started
@property def started(self): return bool(self.start_time)
-
I really like https://docs.python.org/3/library/doctest.html and we insist on them in submissions to https://github.com/TheAlgorithms/Python It allows us to run 700 pytests every time someone contributes code. Doctests really helps our contributors focus on quality and on finding corner cases in their code.
-
-
Why did you put
end_time = end_time or datetime.now()
It works together with having the
end_time=None
default in the method signature. If the method is not given anend_time
, it is None, and then it gets the value ofdatetime.now()
.It is essentially a 1-line version of:
if not end_time: end_time = datetime.now()
You can also use
and
in a similar way, but with a different meaning. E.g.:some_value = obj and obj.attribute
I.e., if
obj
isNone
,obj.attribute
will not get called (which would raise an exception), andsome_value
gets assigned theNone
.This is again a more concise version of:
some_value = obj if obj: some_value = obj.attribute
... or the much uglier (to me):
some_value = obj.attribute if obj else obj
And is this to check to se if the cleaning was started
@property def started(self): return bool(self.start_time)
Yes, but it is not really used in this code, and not very useful either, because the main way to get a
cleaning
object is with thestart_cleaning
method, so it is always at least started when you have it. -
This post is deleted!