NOJIRA added Levenshtein decider
This commit is contained in:
46
src/item_builder.py
Normal file
46
src/item_builder.py
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
|
import Levenshtein
|
||||||
|
|
||||||
|
from models.item import Item
|
||||||
|
from models.order import Order
|
||||||
|
|
||||||
|
|
||||||
|
class ItemBuilder:
|
||||||
|
def __init__(self, orders: List[Order]):
|
||||||
|
self.__item_names: List[str] = _flatten([o.items for o in orders])
|
||||||
|
|
||||||
|
def _translate_part(self, old: str, new: str):
|
||||||
|
self.__item_names = [i.replace(old, new) for i in self.__item_names]
|
||||||
|
|
||||||
|
def _translate_whole(self, old: str, new: str):
|
||||||
|
self.__item_names = [new if i == old else i for i in self.__item_names]
|
||||||
|
|
||||||
|
def _consolidate_names(self):
|
||||||
|
uq_item_names: List[str] = list(set(self.__item_names))
|
||||||
|
print(uq_item_names)
|
||||||
|
for idx, lhs in enumerate(uq_item_names):
|
||||||
|
for rhs in uq_item_names[idx + 1:]:
|
||||||
|
if lhs[0:2] == rhs[0:2]:
|
||||||
|
distance = Levenshtein.distance(lhs, rhs)
|
||||||
|
if distance <= 2:
|
||||||
|
print(lhs + ":" + rhs + " = " + str(distance))
|
||||||
|
self._translate_whole(lhs, rhs)
|
||||||
|
|
||||||
|
def build(self) -> List[Item]:
|
||||||
|
self._translate_part("frietje", "friet")
|
||||||
|
self._translate_part("krul friet", "twister")
|
||||||
|
self._translate_part("krulfriet", "twister")
|
||||||
|
|
||||||
|
self._consolidate_names()
|
||||||
|
|
||||||
|
items: Dict[str, int] = {}
|
||||||
|
for item_name in self.__item_names:
|
||||||
|
if item_name not in items:
|
||||||
|
items[item_name] = 0
|
||||||
|
items[item_name] += 1
|
||||||
|
return sorted([Item(n, a) for n, a in items.items()])
|
||||||
|
|
||||||
|
|
||||||
|
def _flatten(t: List[List]) -> List:
|
||||||
|
return [item for sublist in t for item in sublist]
|
||||||
13
src/main.py
13
src/main.py
@@ -3,7 +3,8 @@ import datetime
|
|||||||
from cachetools import cached, TTLCache
|
from cachetools import cached, TTLCache
|
||||||
from flask import render_template
|
from flask import render_template
|
||||||
|
|
||||||
from models.dto import DTO
|
from models.order import Order
|
||||||
|
from models.order_total import OrderTotal
|
||||||
from repository import Repository
|
from repository import Repository
|
||||||
|
|
||||||
|
|
||||||
@@ -22,19 +23,19 @@ def anonymize_name(name: str) -> str:
|
|||||||
|
|
||||||
|
|
||||||
@cached(cache=TTLCache(maxsize=1, ttl=10))
|
@cached(cache=TTLCache(maxsize=1, ttl=10))
|
||||||
def _get_data() -> DTO:
|
def _get_data() -> OrderTotal:
|
||||||
cutoff = datetime.datetime.now() - datetime.timedelta(days=4)
|
cutoff = datetime.datetime.now() - datetime.timedelta(days=2)
|
||||||
|
|
||||||
rows_to_process = [row for row in _repository.load_rows()
|
rows_to_process = [row for row in _repository.load_rows()
|
||||||
if row and datetime.datetime.strptime(row[0], '%d-%m-%Y %H:%M:%S') > cutoff]
|
if row and datetime.datetime.strptime(row[0], '%d-%m-%Y %H:%M:%S') > cutoff]
|
||||||
|
|
||||||
result = DTO()
|
result = OrderTotal()
|
||||||
|
|
||||||
for row in rows_to_process:
|
for row in rows_to_process:
|
||||||
result.add(
|
result.add(Order(
|
||||||
applicant_name=anonymize_name(row[1]),
|
applicant_name=anonymize_name(row[1]),
|
||||||
item_names=[item_name.lower().strip() for item_name in row[2:]],
|
item_names=[item_name.lower().strip() for item_name in row[2:]],
|
||||||
)
|
))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
from typing import List, Dict
|
|
||||||
|
|
||||||
from models.item import Item
|
|
||||||
from models.order import Order
|
|
||||||
|
|
||||||
|
|
||||||
class DTO:
|
|
||||||
def __init__(self):
|
|
||||||
self.__applicants: List[str] = []
|
|
||||||
self.__items: Dict[str, int] = {}
|
|
||||||
self.__orders: List[Order] = []
|
|
||||||
|
|
||||||
def add(self,
|
|
||||||
applicant_name: str,
|
|
||||||
item_names: List[str]
|
|
||||||
) -> None:
|
|
||||||
self.__applicants.append(applicant_name)
|
|
||||||
|
|
||||||
for item_name in item_names:
|
|
||||||
if item_name not in self.__items:
|
|
||||||
self.__items[item_name] = 0
|
|
||||||
self.__items[item_name] += 1
|
|
||||||
|
|
||||||
order = Order(applicant_name, item_names)
|
|
||||||
self.__orders.append(order)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def items(self) -> List[Item]:
|
|
||||||
return sorted([Item(name, amount) for name, amount in self.__items.items()])
|
|
||||||
|
|
||||||
@property
|
|
||||||
def item_count(self) -> int:
|
|
||||||
return sum(self.__items.values())
|
|
||||||
|
|
||||||
@property
|
|
||||||
def applicants(self) -> List[str]:
|
|
||||||
return sorted(self.__applicants)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def orders(self) -> List[Order]:
|
|
||||||
return sorted(self.__orders)
|
|
||||||
@@ -3,10 +3,10 @@ from typing import List
|
|||||||
|
|
||||||
class Order:
|
class Order:
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
name: str,
|
applicant_name: str,
|
||||||
items: List[str]):
|
item_names: List[str]):
|
||||||
self.name = name
|
self.name = applicant_name
|
||||||
self.items = items
|
self.items = item_names
|
||||||
|
|
||||||
def __lt__(self: "Order",
|
def __lt__(self: "Order",
|
||||||
other: "Order"
|
other: "Order"
|
||||||
|
|||||||
29
src/models/order_total.py
Normal file
29
src/models/order_total.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
from typing import List, Dict
|
||||||
|
|
||||||
|
from item_builder import ItemBuilder
|
||||||
|
from models.item import Item
|
||||||
|
from models.order import Order
|
||||||
|
|
||||||
|
|
||||||
|
class OrderTotal:
|
||||||
|
def __init__(self):
|
||||||
|
self.__orders: List[Order] = []
|
||||||
|
|
||||||
|
def add(self, order: Order) -> None:
|
||||||
|
self.__orders.append(order)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def items(self) -> List[Item]:
|
||||||
|
return ItemBuilder(self.__orders).build()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def item_count(self) -> int:
|
||||||
|
return sum([len(o.items) for o in self.__orders])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def applicants(self) -> List[str]:
|
||||||
|
return sorted([o.name for o in self.__orders])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def orders(self) -> List[Order]:
|
||||||
|
return sorted(self.__orders)
|
||||||
@@ -2,4 +2,5 @@ cachetools==4.2.2
|
|||||||
flask==2.0.1
|
flask==2.0.1
|
||||||
google-api-python-client==2.20.0
|
google-api-python-client==2.20.0
|
||||||
google-auth-httplib2==0.1.0
|
google-auth-httplib2==0.1.0
|
||||||
google-auth-oauthlib==0.4.6
|
google-auth-oauthlib==0.4.6
|
||||||
|
python-Levenshtein==0.12.2
|
||||||
Reference in New Issue
Block a user