aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--geldschieberbot.py57
-rw-r--r--tanken.py57
-rwxr-xr-xtest.py24
3 files changed, 72 insertions, 66 deletions
diff --git a/geldschieberbot.py b/geldschieberbot.py
index 79cb643..969540f 100644
--- a/geldschieberbot.py
+++ b/geldschieberbot.py
@@ -7,8 +7,6 @@ import os
import subprocess
import sys
-import tanken
-
# Path where our data is stored persistent on disk
STATE_FILE = os.environ["GSB_STATE_FILE"]
@@ -591,7 +589,51 @@ class Geldschieberbot:
return {'err': f'unknown car subcommand "{args[1]}".'}
- def _tanken(self, sender, args, msg) -> dict[str, str]:
+ def parse_tank_bill(self, _drives: list[str], fuel_charge: int,
+ service_charge: int):
+ """Parse and distribute the tank bill across all passangers"""
+ passengers: dict[str, dict[str, int]] = {}
+ distance = 0.
+ drives = [d.split(' ') for d in _drives]
+
+ for drive in drives:
+ try:
+ drive_distance = int(drive[0])
+ except (IndexError, ValueError):
+ return None, "Lines have to start with the driven distance!"
+
+ # calculate overall distance
+ distance += drive_distance
+
+ # collect distances per passenger
+ drive_passengers = self.expand_aliases(drive[1:])
+ for passenger in drive_passengers:
+ passengers.setdefault(passenger, {
+ "distance": 0,
+ "cost": 0,
+ "service_charge": 0
+ })["distance"] += drive_distance
+
+ # calculate cost per kilometer
+ if distance <= 0:
+ return None, "Driven distance must be greater than 0!"
+
+ c_km = fuel_charge / distance
+
+ for drive in drives:
+ drive_distance = int(drive[0])
+ drive_passengers = self.expand_aliases(drive[1:])
+ # calculate cost per drive split among passengers
+ c_d = int(c_km * drive_distance / (len(drive_passengers)))
+ sc_d = int(service_charge * drive_distance /
+ (len(drive_passengers)))
+ for passenger in drive_passengers:
+ passengers[passenger]["cost"] += c_d
+ passengers[passenger]["service_charge"] += sc_d
+
+ return passengers, None
+
+ def tanken(self, sender, args, msg) -> dict[str, str]:
"""Split a tank across all passengers"""
if len(args) < 2:
return {
@@ -617,12 +659,9 @@ class Geldschieberbot:
elif len(args) > 3 and args[3] in self.available_cars:
car = args[3]
- service_charge = 0
- if car:
- service_charge = self.available_cars[car]
-
- parts, err = tanken.tanken(msg[1:], amount, service_charge)
+ service_charge = self.available_cars.get(car, 0)
+ parts, err = self.parse_tank_bill(msg[1:], amount, service_charge)
if err:
return {'err': err}
@@ -925,7 +964,7 @@ class Geldschieberbot:
'usage': self.usage,
'transfer': self.transfer,
'cars': self.cars,
- 'tanken': self._tanken,
+ 'tanken': self.tanken,
'fuck': self.fuck,
'rewind': self.fuck,
'undo': self.fuck,
diff --git a/tanken.py b/tanken.py
deleted file mode 100644
index 2c65c73..0000000
--- a/tanken.py
+++ /dev/null
@@ -1,57 +0,0 @@
-"""Utilities to support splitting fuel and car maintainance costs"""
-
-import typing as T
-
-PassengerResult = dict[str, int]
-Results = dict[str, PassengerResult]
-TankenFailure = T.Tuple[None, str]
-TankenSuccess = T.Tuple[Results, None]
-TankenResult = T.Union[TankenSuccess, TankenFailure]
-
-
-# cost should be given in cents
-def tanken(_drives: list[str], cost: int, service_charge=0) -> TankenResult:
- """calculate costs per passange for one tank load"""
- passengers = {}
- distance = 0.
- drives = [d.split(' ') for d in _drives]
-
- for drive in drives:
- try:
- drive_distance = int(drive[0])
- except (IndexError, ValueError):
- return None, "Lines have to start with the driven distance!"
-
- # calculate overall distance
- distance += drive_distance
-
- # collect distances per passenger
- for passenger in drive[1:]:
- if passenger not in passengers:
- passengers[passenger] = {
- "distance": drive_distance,
- "cost": 0,
- "service_charge": 0
- }
- else:
- passengers[passenger]["distance"] += drive_distance
-
- # calculate cost per kilometer
- if distance <= 0:
- return None, "Driven distance must be greater than 0!"
-
- c_km = cost / distance
-
- for drive in drives:
- drive_distance = int(drive[0])
- # calculate cost per drive split among passengers
- c_d = int(c_km * drive_distance / (len(drive) - 1))
- for passenger in drive[1:]:
- passengers[passenger]["cost"] += c_d
-
- # calculate service charge per drive split among passengers
- sc_d = int(service_charge * drive_distance / (len(drive) - 1))
- for passenger in drive[1:]:
- passengers[passenger]["service_charge"] += sc_d
-
- return passengers, None
diff --git a/test.py b/test.py
index d279e0b..e839536 100755
--- a/test.py
+++ b/test.py
@@ -514,6 +514,30 @@ charlie:
\t<- bob 3.00
\tBalance: 6.00""")
+ def test_tanken_all(self):
+ res = run_bot(self, num[alice], "!tanken 10\n10 all")
+ self.assertEqual(res.stdout, \
+"""alice: 10km = fuel: 3.33, service charge: 0.00
+bob: 10km = fuel: 3.33, service charge: 0.00
+charlie: 10km = fuel: 3.33, service charge: 0.00
+New Balance:
+alice:
+\t<- bob 3.33
+\t<- charlie 3.33
+\tBalance: 6.66""")
+
+ def test_tanken_alias(self):
+ run_bot(self, num[alice], f"!alias alob {alice} {bob}")
+ res = run_bot(self, num[charlie], "!tanken 8\n10 alob")
+ self.assertEqual(res.stdout, \
+"""alice: 10km = fuel: 4.00, service charge: 0.00
+bob: 10km = fuel: 4.00, service charge: 0.00
+New Balance:
+charlie:
+\t<- alice 4.00
+\t<- bob 4.00
+\tBalance: 8.00""")
+
class TestCarsAdd(unittest.TestCase):