proper recursive finding of conversions
This commit is contained in:
parent
5fd453759b
commit
ffa0253193
4 changed files with 71 additions and 25 deletions
84
recipes.py
84
recipes.py
|
@ -1,4 +1,5 @@
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
from collections import defaultdict
|
||||||
import sys
|
import sys
|
||||||
from typing import Dict, List, Any, Optional, Set
|
from typing import Dict, List, Any, Optional, Set
|
||||||
import os
|
import os
|
||||||
|
@ -117,29 +118,54 @@ class Ingredient(Element):
|
||||||
conversions.append(conversion)
|
conversions.append(conversion)
|
||||||
self["conversions"] = conversions
|
self["conversions"] = conversions
|
||||||
|
|
||||||
def convert(
|
def dfs(
|
||||||
self, amount: float, unitfrom: Unit, unitto: Unit, scannedunits: List[Unit] = []
|
self,
|
||||||
) -> Optional[float]:
|
conversions: Dict[str, Dict[str, float]],
|
||||||
# TODO: this can not solve conversions when we have kg -> g and g -> piece
|
startname: str,
|
||||||
if unitto == unitfrom:
|
endname: str,
|
||||||
return amount
|
visited: Optional[List[str]] = None,
|
||||||
conversions = (
|
) -> Optional[List[str]]:
|
||||||
self["conversions"] + unitfrom["conversions"] + unitto["conversions"]
|
if visited is None:
|
||||||
)
|
visited = []
|
||||||
for conv in conversions:
|
if startname == endname:
|
||||||
ratio: float = conv["ratio"]
|
return visited + [startname]
|
||||||
if (
|
|
||||||
conv["from"]["name"] == unitfrom["name"]
|
for nextunit in conversions[startname].keys():
|
||||||
and conv["to"]["name"] == unitto["name"]
|
if nextunit in visited:
|
||||||
):
|
continue
|
||||||
return amount * ratio
|
result = self.dfs(conversions, nextunit, endname, visited+[startname])
|
||||||
if (
|
if result is not None:
|
||||||
conv["to"]["name"] == unitfrom["name"]
|
return result
|
||||||
and conv["from"]["name"] == unitto["name"]
|
|
||||||
):
|
|
||||||
return amount / ratio
|
|
||||||
return None
|
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]:
|
def getprice(self, amount: float, unit: Unit) -> Optional[float]:
|
||||||
if "prices" not in self.dct:
|
if "prices" not in self.dct:
|
||||||
return None
|
return None
|
||||||
|
@ -190,6 +216,9 @@ class PriceDBs:
|
||||||
self.pricedbs.append(pricedb)
|
self.pricedbs.append(pricedb)
|
||||||
return self.ctx.issues
|
return self.ctx.issues
|
||||||
|
|
||||||
|
def __repr__(self) -> str:
|
||||||
|
return self.pricedbs.__repr__()
|
||||||
|
|
||||||
|
|
||||||
class PriceDB(Element):
|
class PriceDB(Element):
|
||||||
def load(self, dct: Dict[str, Any]) -> None:
|
def load(self, dct: Dict[str, Any]) -> None:
|
||||||
|
@ -258,6 +287,19 @@ class Recipe(Element):
|
||||||
subrecipes.append(rp)
|
subrecipes.append(rp)
|
||||||
self["subrecipes"] = subrecipes
|
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:
|
class Builder:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
{% macro price(rec) -%}
|
||||||
|
{% if rec.price == None %}?{%else%}{{rec.price|round(1)|numprint}}{% endif %} CZK
|
||||||
|
{%- endmacro %}
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
@ -8,4 +11,4 @@
|
||||||
<body>
|
<body>
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
{%block body %}
|
{%block body %}
|
||||||
<h1>Recipes</h1>
|
<h1>Recipes</h1>
|
||||||
{% for recipe in recipes %}
|
{% 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 %}
|
{% endfor %}
|
||||||
{%endblock%}
|
{%endblock%}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% macro ingredientpart(ing) -%}
|
{% 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 %}
|
{%- endmacro %}
|
||||||
|
|
||||||
{% macro ingredient(ing) -%}
|
{% macro ingredient(ing) -%}
|
||||||
|
@ -22,6 +22,7 @@
|
||||||
{% for ing in rec.ingredients %}
|
{% for ing in rec.ingredients %}
|
||||||
<li>{{ingredient(ing)}}</li>
|
<li>{{ingredient(ing)}}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
price: {{ price(rec) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if rec.steps|length != 0 %}
|
{% if rec.steps|length != 0 %}
|
||||||
<h3>Steps</h3>
|
<h3>Steps</h3>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue