Skip to content

Commit

Permalink
Merge pull request #6 from JordanWelsman/develop
Browse files Browse the repository at this point in the history
To-do list complete. Tests pass. Merging now.
  • Loading branch information
JordanWelsman authored Feb 4, 2023
2 parents 18cfcad + 8684be0 commit 1faa2f4
Show file tree
Hide file tree
Showing 11 changed files with 910 additions and 3 deletions.
9 changes: 9 additions & 0 deletions jutl/timers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Import submodule files so
# classes and functions are usable at
# 'from jutl.timers import _' level.
from .stopwatch import *
from .timer import *

# Only show functions specified in
# submodule files to the outside world.
__all__ = stopwatch.__all__, timer.__all__
181 changes: 181 additions & 0 deletions jutl/timers/stopwatch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Module imports
from time import time

# External class visibility
__all__ = ['Stopwatch']


class Stopwatch():
"""
Class which acts as a stopwatch
with time and lap methods.
"""
def __init__(self, name: str = None):
"Initialization method."
self.name: str = name
self._start_time: float
self._stop_time: float
self.total_time: float = None
self._laps: list[float] = []
self.lap_times: list[float] = []

def __repr__(self) -> str:
"""
Tells the interpreter how
to represent this class.
"""
if self.name is None:
if self.total_time is None:
return "Stopwatch()"
else:
return f"Stopwatch({round(self.total_time, 2)}s)"
else:
if self.total_time is None:
return f"Stopwatch({self.name})"
else:
return f"Stopwatch({self.name}, {round(self.total_time, 2)}s)"

def __call__(self):
"""
Tells the interpreter what to
do when an object of this
class is called directly.
"""
if self.lap_times:
for n, time in enumerate(self.lap_times):
print(f"Lap {n+1}: {round(time, 2)}s")
else:
print("There are no lap times.")

def __len__(self) -> int:
"""
Tells the interpreter what to
consider this class' length.
"""
return len(self._laps)

def __iter__(self) -> iter:
"""
Tells the interpreter what to
iterate over when iterator methods
are called on this class.
"""
return iter(self.lap_times)

def __eq__(self, other) -> bool:
"""
Tells the interpreter how this class
handles equal operators.
"""
return self.total_time == other.total_time

def __ne__(self, other) -> bool:
"""
Tells the interpreter how this class
handles not equal operators.
"""
return self.total_time != other.total_time

def __gt__(self, other) -> bool:
"""
Tells the interpreter how this class
handles greater than operators.
"""
return self.total_time > other.total_time

def __ge__(self, other) -> bool:
"""
Tells the interpreter how this class
handles greater or equal operators.
"""
return self.total_time >= other.total_time

def __lt__(self, other) -> bool:
"""
Tells the interpreter how this class
handles less than operators.
"""
return self.total_time < other.total_time

def __le__(self, other) -> bool:
"""
Tells the interpreter how this class
handles less than or equal operators.
"""
return self.total_time <= other.total_time

def __add__(self, other) -> float:
"""
Tells the interpreter how to sum these objects.
"""
return self.total_time + other.total_time

def __sub__(self, other) -> float:
"""
Tells the interpreter how to subtract these objects.
"""
return self.total_time - other.total_time

def __mul__(self, multiplier) -> float:
"""
Tells the interpreter how to subtract these objects.
"""
return self.total_time * multiplier

def __truediv__(self, other) -> float:
"""
Tells the interpreter how to subtract these objects.
"""
return self.total_time / other.total_time


def start(self):
"""
Starts the stopwatch by
initializing an object attribute.
"""
self._start_time = time()


def lap(self, lap_time: float = None):
"""
Adds the current time to the lap time
list and records the time since the
start or time of the last recorded lap.
"""
if lap_time:
self._laps.append(lap_time)
else:
self._laps.append(time())
if not self.lap_times:
self.lap_times.append(self._calculate_time(self._start_time, self._laps[-1]))
else:
self.lap_times.append(self._calculate_time(self._laps[-2], self._laps[-1]))


def stop(self):
"""
Stops the stopwatch and calculates
the total time passed.
"""
self._stop_time = time()
self.total_time = self._calculate_time(self._start_time, self._stop_time)
self.lap(self._stop_time)


def _calculate_time(self, time1: float, time2: float) -> float:
"""
Returns the difference in time where t2>t1.
"""
return time2 - time1


def reset(self):
"""
Resets all stopwatch attributes.
"""
self._start_time = None
self._stop_time = None
self.total_time = None
self._laps.clear()
self.lap_times.clear()
181 changes: 181 additions & 0 deletions jutl/timers/timer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Module imports
from time import time, sleep

# External class visibility
__all__ = ['Timer']


class Timer():
"""
Class which acts as a timer
with time methods.
"""
def __init__(self, name: str = None):
"Inisialization method."
self.name: str = name
self._start_time: float
self._pause_time: float = None
self._paused_time: float = None
self._stop_time: float
self.total_time: float = None

def __repr__(self) -> str:
"""
Tells the interpreter how
to represent this class.
"""
if self.name is None:
if self.total_time is None:
return "Timer()"
else:
return f"Timer({round(self.total_time, 2)}s)"
else:
if self.total_time is None:
return f"Timer({self.name})"
else:
return f"Timer({self.name}, {round(self.total_time, 2)}s)"

def __call__(self):
"""
Tells the interpreter what to
do when an object of this
class is called directly.
"""
if self.total_time:
print(f"{self.name} total time: {round(self.total_time, 2)}s")
else:
print("There is no recorded time.")

def __len__(self):
"""
Tells the interpreter what to
consider this class' length.
"""
if self.total_time // 60 == 1:
return int(self.total_time // 60)
elif self.total_time // 3600 == 1:
return int(self.total_time // 3600)
else:
return int(self.total_time)

def __eq__(self, other) -> bool:
"""
Tells the interpreter how this class
handles equal operators.
"""
return self.total_time == other.total_time

def __ne__(self, other) -> bool:
"""
Tells the interpreter how this class
handles not equal operators.
"""
return self.total_time != other.total_time

def __gt__(self, other) -> bool:
"""
Tells the interpreter how this class
handles greater than operators.
"""
return self.total_time > other.total_time

def __ge__(self, other) -> bool:
"""
Tells the interpreter how this class
handles greater or equal operators.
"""
return self.total_time >= other.total_time

def __lt__(self, other) -> bool:
"""
Tells the interpreter how this class
handles less than operators.
"""
return self.total_time < other.total_time

def __le__(self, other) -> bool:
"""
Tells the interpreter how this class
handles less than or equal operators.
"""
return self.total_time <= other.total_time

def __add__(self, other) -> float:
"""
Tells the interpreter how to sum these objects.
"""
return self.total_time + other.total_time

def __sub__(self, other) -> float:
"""
Tells the interpreter how to subtract these objects.
"""
return self.total_time - other.total_time

def __mul__(self, multiplier) -> float:
"""
Tells the interpreter how to subtract these objects.
"""
return self.total_time * multiplier

def __truediv__(self, other) -> float:
"""
Tells the interpreter how to subtract these objects.
"""
return self.total_time / other.total_time


def start(self):
"""
Starts the timer by
initializing an object attribute.
"""
self._start_time = time()


def pause(self, duration: float = None):
"""
Pauses the timer.
"""
self._pause_time = time()
if duration:
sleep(duration)


def resume(self):
"""
Resumes the timer.
"""
if self._paused_time:
self._paused_time += self._calculate_time(self._pause_time, time())
else:
self._paused_time = self._calculate_time(self._pause_time, time())


def stop(self):
"""
Stops the timer and calculates
the total time passed.
"""
if self._pause_time and not self._paused_time: # if stopped while paused
self.resume()
self._stop_time = time()
self.total_time = self._calculate_time(self._start_time, self._stop_time)


def _calculate_time(self, time1: float, time2: float) -> float:
"""
Returns the difference in time where t2>t1.
"""
return time2 - time1


def reset(self):
"""
Resets all timer attributes.
"""
self._start_time = None
self._pause_time = None
self._paused_time = None
self._stop_time = None
self.total_time = None
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Arguments
git_name = "jutils"
pypi_name = "jutl"
version = "0.2.0"
version = "0.3.0"
python_version = ">=3.10"

# Long description from README.md
Expand Down Expand Up @@ -36,13 +36,13 @@
long_description_content_type='text/markdown',
author='Jordan Welsman',
author_email='jordan.welsman@outlook.com',
url='https://pypi.org/project/'+pypi_name+"/",
url='https://pypi.org/project/'+pypi_name+'/',
download_url='https://github.com/JordanWelsman/jutils/tags',
package_data={f'{pypi_name}': jutils_package_data},
python_requires=python_version,
# jutils package information
classifiers=[
'Development Status :: 3 - Alpha',
'Development Status :: 4 - Beta',
'Intended Audience :: Developers',
'Intended Audience :: Education',
'License :: OSI Approved :: MIT License',
Expand Down
Empty file added test/formatting/test_color.py
Empty file.
Empty file added test/formatting/test_text.py
Empty file.
Empty file added test/formatting/test_utils.py
Empty file.
Loading

0 comments on commit 1faa2f4

Please sign in to comment.