[73] | 1 | from __future__ import annotations
|
---|
| 2 | from datetime import datetime
|
---|
| 3 |
|
---|
| 4 | from geniusweb.progress.Progress import Progress
|
---|
| 5 |
|
---|
| 6 |
|
---|
| 7 | class ProgressRounds (Progress):
|
---|
| 8 | '''
|
---|
| 9 | progress in terms of number of rounds. The round has to be updated by the
|
---|
| 10 | user of this class, calling {@link #advance()}. immutable.
|
---|
| 11 | '''
|
---|
| 12 |
|
---|
| 13 | def __init__(self, duration:int, currentRound:int, endtime:datetime):
|
---|
| 14 | '''
|
---|
| 15 | @param duration length max number of rounds, must be positive (not 0)
|
---|
| 16 | @param currentRound the current round number (can be from 0 to deadlne).
|
---|
| 17 | When = deadline, it means the progress has gone past
|
---|
| 18 | the deadline.
|
---|
| 19 | @param end the termination time of this session.
|
---|
| 20 | WARNING due to a bug in python for windows, this value must be
|
---|
| 21 | at least 100000 seconds above jan. 1, 1970.
|
---|
| 22 | '''
|
---|
| 23 | if duration <= 0:
|
---|
| 24 | raise ValueError("deadline must be positive but is " + str(duration))
|
---|
| 25 | if currentRound < 0 or currentRound > duration:
|
---|
| 26 | raise ValueError("current round must be inside [0," + str(duration) + "]")
|
---|
| 27 | self._duration = duration
|
---|
| 28 | self._currentRound = currentRound
|
---|
| 29 | self._endtime = endtime
|
---|
| 30 |
|
---|
| 31 | def getTerminationTime(self) -> datetime:
|
---|
| 32 | return self._endtime
|
---|
| 33 |
|
---|
| 34 | def getDuration(self):
|
---|
| 35 | '''
|
---|
| 36 | @return max number of rounds, positive integer (not 0)
|
---|
| 37 | '''
|
---|
| 38 | return self._duration
|
---|
| 39 |
|
---|
| 40 | def getEndtime(self):
|
---|
| 41 | return self._endtime
|
---|
| 42 |
|
---|
| 43 | def getCurrentRound(self) -> int:
|
---|
| 44 | '''
|
---|
| 45 | @return the current round. First round is 0. It is recommended that you
|
---|
| 46 | use the functions in {@link Progress} instead of this, to ensure
|
---|
| 47 | your code works with all implementations of Progress including
|
---|
| 48 | future developments.
|
---|
| 49 | '''
|
---|
| 50 | return self._currentRound
|
---|
| 51 |
|
---|
| 52 | def getTotalRounds(self) -> int:
|
---|
| 53 | '''
|
---|
| 54 | @return total number of rounds. It is recommended that you use the
|
---|
| 55 | functions in {@link Progress} instead of this, to ensure your
|
---|
| 56 | code works with all implementations of Progress including future
|
---|
| 57 | developments.
|
---|
| 58 | '''
|
---|
| 59 | return self._duration
|
---|
| 60 |
|
---|
| 61 | def get(self, currentTimeMs:int) -> float:
|
---|
| 62 | # deadline and current both are limited to MAXINT is 32 bits; double
|
---|
| 63 | # fits 52
|
---|
| 64 | # bits so this should not result in accuracy issues
|
---|
| 65 | ratio:float = self._currentRound / self._duration;
|
---|
| 66 | if ratio > 1:
|
---|
| 67 | ratio = 1;
|
---|
| 68 | elif ratio < 0:
|
---|
| 69 | ratio = 0;
|
---|
| 70 | return ratio;
|
---|
| 71 |
|
---|
| 72 | def isPastDeadline(self, currentTimeMs:int) -> bool:
|
---|
| 73 | return self._currentRound >= self._duration or \
|
---|
| 74 | currentTimeMs > int(1000 * datetime.timestamp(self._endtime))
|
---|
| 75 |
|
---|
| 76 | def advance(self) -> "ProgressRounds" :
|
---|
| 77 | '''
|
---|
| 78 | @return new ProgressRounds with round 1 advanced (or this, if
|
---|
| 79 | currentRound= duration). This is up to the user, as it is up to
|
---|
| 80 | the used protocol what exactly is a round.
|
---|
| 81 | '''
|
---|
| 82 | if self._duration == self._currentRound:
|
---|
| 83 | return self
|
---|
| 84 | return ProgressRounds(self._duration, self._currentRound + 1, self._endtime)
|
---|
| 85 |
|
---|
| 86 | def __hash__(self):
|
---|
| 87 | return hash((self._currentRound, self._duration))
|
---|
| 88 |
|
---|
| 89 | def __eq__(self, other):
|
---|
| 90 | return isinstance(other, self.__class__) \
|
---|
| 91 | and self._currentRound == other._currentRound \
|
---|
| 92 | and self._duration == other._duration \
|
---|
| 93 | and self._endtime == other._endtime
|
---|
| 94 |
|
---|
| 95 | def __repr__(self):
|
---|
| 96 | return "ProgressRounds[" + str(self._currentRound) \
|
---|
| 97 | +" of " + str(self._duration) \
|
---|
| 98 | +"," + str(datetime.timestamp(self._endtime)) + "]"
|
---|