proper recursive finding of conversions

This commit is contained in:
Emi Vasilek 2023-11-14 13:36:49 +01:00
parent 5fd453759b
commit ffa0253193
4 changed files with 71 additions and 25 deletions

View file

@ -1,4 +1,5 @@
from abc import abstractmethod
from collections import defaultdict
import sys
from typing import Dict, List, Any, Optional, Set
import os
@ -117,29 +118,54 @@ class Ingredient(Element):
conversions.append(conversion)
self["conversions"] = conversions
def convert(
self, amount: float, unitfrom: Unit, unitto: Unit, scannedunits: List[Unit] = []
) -> Optional[float]:
# TODO: this can not solve conversions when we have kg -> g and g -> piece
if unitto == unitfrom:
return amount
conversions = (
self["conversions"] + unitfrom["conversions"] + unitto["conversions"]
)
for conv in conversions:
ratio: float = conv["ratio"]
if (
conv["from"]["name"] == unitfrom["name"]
and conv["to"]["name"] == unitto["name"]
):
return amount * ratio
if (
conv["to"]["name"] == unitfrom["name"]
and conv["from"]["name"] == unitto["name"]
):
return amount / ratio
def dfs(
self,
conversions: Dict[str, Dict[str, float]],
startname: str,
endname: str,
visited: Optional[List[str]] = None,
) -> Optional[List[str]]:
if visited is None:
visited = []
if startname == endname:
return visited + [startname]
for nextunit in conversions[startname].keys():
if nextunit in visited:
continue
result = self.dfs(conversions, nextunit, endname, visited+[startname])
if result is not None:
return result
return None
def convert(
self, amount: float, unitfrom: Unit, unitto: Unit
) -> Optional[float]:
conversions: Dict[str, Dict[str, float]] = defaultdict(dict)
# construct node tree
convs = self["conversions"]
for unit in self.ctx.units.units:
convs += unit["conversions"]
for conv in convs:
fromname = conv["from"]["name"]
toname = conv["to"]["name"]
conversions[fromname][toname] = conv["ratio"]
conversions[toname][fromname] = 1 / conv["ratio"]
# find path between conversions
path = self.dfs(conversions, unitfrom["name"], unitto["name"])
if path is None:
print(
f'WARNING: {self["name"]} has a known price, but conversion {unitfrom["name"]} -> {unitto["name"]} not known'
)
return None
assert len(path) != 0
oldelem = path[0]
for elem in path[1:]:
amount *= conversions[oldelem][elem]
oldelem = elem
return amount
def getprice(self, amount: float, unit: Unit) -> Optional[float]:
if "prices" not in self.dct:
return None
@ -190,6 +216,9 @@ class PriceDBs:
self.pricedbs.append(pricedb)
return self.ctx.issues
def __repr__(self) -> str:
return self.pricedbs.__repr__()
class PriceDB(Element):
def load(self, dct: Dict[str, Any]) -> None:
@ -258,6 +287,19 @@ class Recipe(Element):
subrecipes.append(rp)
self["subrecipes"] = subrecipes
price: Optional[int] = 0
ingswithprice = 0
ingswithoutprice = 0
for ing in ingredients:
if ing["price"] is None:
ingswithoutprice += 1
continue
ingswithprice += 1
price += ing["price"]
if ingswithoutprice != 0 or len(ingredients) == 0:
price = None
self["price"] = price
class Builder:
def __init__(self) -> None:

View file

@ -1,3 +1,6 @@
{% macro price(rec) -%}
{% if rec.price == None %}?{%else%}{{rec.price|round(1)|numprint}}{% endif %} CZK
{%- endmacro %}
<!DOCTYPE html>
<html lang="en">
<head>
@ -8,4 +11,4 @@
<body>
{% block body %}{% endblock %}
</body>
</html>
</html>

View file

@ -3,6 +3,6 @@
{%block body %}
<h1>Recipes</h1>
{% for recipe in recipes %}
<li><a href="{{ recipe.outpath }}">{{ recipe.title }}</a></li>
<li>{{price(recipe)}} <a href="{{ recipe.outpath }}">{{ recipe.title }}</a></li>
{% endfor %}
{%endblock%}
{%endblock%}

View file

@ -1,6 +1,6 @@
{% extends "base.html" %}
{% macro ingredientpart(ing) -%}
{% if ing.price != None %}{{ing.price|round(1)|numprint}}{%else%} ?{%endif%} {{ing.amount|amountprint}} {{ing["unit"].name}} {{ ing.name }}
{{price(ing)}} {{ing.amount|amountprint}} {{ing["unit"].name}} {{ ing.name }} {{ing.note}}
{%- endmacro %}
{% macro ingredient(ing) -%}
@ -22,6 +22,7 @@
{% for ing in rec.ingredients %}
<li>{{ingredient(ing)}}</li>
{% endfor %}
price: {{ price(rec) }}
{% endif %}
{% if rec.steps|length != 0 %}
<h3>Steps</h3>