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 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:
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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%}
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue