nextcloud / cookbook

šŸ² A library for all your recipes
https://apps.nextcloud.com/apps/cookbook
GNU Affero General Public License v3.0
522 stars 89 forks source link

Enhancement: Recalculate ingredient quantity (e.g. double it) #116

Closed nivekznews closed 1 year ago

nivekznews commented 4 years ago

Often people want to double or cut in halve the amount that should be cooked or baked.

Suggestion: Provide the possibility to multiply the amount of ingredient's quantity temporarily.


Depends on #340

mrzapp commented 4 years ago

Agreed, I would want this feature too.

The issue is that knowing what is the numerical part of an ingredient is a bit tough, since literally any string is permitted as a recipe ingredient according to schema.org/Recipe.

For instance:

Unless we implement some restriction on ingredient input, which prevents the above ingredient formats and potentially angers some users, this feature cannot work.

Have you perhaps seen a good way to work around this issue?

Teifun2 commented 4 years ago

I have once read through the schema.org issue on this topic. (The one i linked matrix)

One proposed solution was to use the supply tag to store the recipe ingredients.

We could save the ingredients with (amount, type, name) in the supply tag and to support data recovery and the current schema.org idea, we could then save one variant of this data in the ingredients tag. This would lead to data duplication in the JSON. We could only expose the supply tag to the users and fill the ingredients tag in the background. This is exactly the same as the above mentioned proposed solution.

"supply": [
  {
    "@type": "HowToSupply",
    "name": "rolled oats",
    "requiredQuantity": {
      "@type": "QuantitativeValue",
      "value": 100,
      "unitCode": "GRM"
    }
  }
],
"recipeIngredient": [
  "100g rolled oats"
]
mrzapp commented 4 years ago

@Teifun2 I like that solution, and I support that we would start saving and inputting recipes this way.

The problem is that no one else on the internet agrees (yet), so the ingredient recalculator would only work on manually entered recipes.

I think solving this issue inevitably leads to 3 tasks:

Teifun2 commented 4 years ago

@mrzapp Yes. I agree. Especially the parser will be difficult :/

I think that all that should not be included into the goals of the next release, rather it could be the main focus of the version after that.

mrzapp commented 4 years ago

@Teifun2 agreed, we'll keep it in "to do" for now

spikusmax commented 4 years ago

Hi again,

Just wondering if you need to actually modify the way ingredient quantities are stored. Could one not specify that if no numerical value was found the ingredient would be listed as a text string with the value of the division/multiplication happened to the front. So if a recipe called for:

...and you wanted to double it the results would be:

That way the internet does not get angered, output is functional if not perfect, and individual recipe holders then have the ability to modify their recipes for more streamlined conversions next time? These days recipes frequently only have one or two ingredients that aren't indicated as a numerical value, it would not be a huge burden on the individual cook to have to quality control the output of the quantity conversion script.

Cheers,

Spike

mrzapp commented 4 years ago

@spikusmax is on to something. What say you @Teifun2, should we not think too much ahead and actually just write a "lazy" parser in JavaScript?

Mannshoch commented 4 years ago

If you cook, doubling would work. But not when you bake. Here you would need two or three recipes for different quantity to calculate a quantity curve per ingredient so you could calculate for specific amount of people.

ghost commented 4 years ago

I was wondering if this could be extended to do unit conversion?

Mannshoch commented 4 years ago

Is there somewhere a kind of unit-table where units and their value are listed? I only know https://en.wikipedia.org/wiki/Cooking_weights_and_measures If there is no table we should create one with basic data.

jessechahal commented 3 years ago

I just thought i would mention here that if https://github.com/nextcloud/cookbook/issues/364 ends up being implemented you could have different serving sizes == unique version/tag of a recipe. I think most people won't change a given recipe portion/serving sizes regularly. They will probably have 1-3 different sizes that they care about and consistently use (which may be different from original recipe). You wouldn't have to deal with ingredients being written using imprecise measurement systems (code wise) or trying to include ingredient ratio's within a recipe for automatic serving conversation.

christianll9 commented 3 years ago

@jessechahal I don't think that this is what the final user wants. Then the user needs to manually compute the different sizes again. Recalculation of ingredients is a core feature in the most digital cookbooks. Actually, I think a simple calculator implemented only on front-end side would be sufficient enough. I like the simple solution @spikusmax proposed.

LucaBernstein commented 3 years ago

Hey all, what's the status on this one? I would really appreciate recalculation for my recipes šŸ˜„ Cheers šŸ˜· P.S.: If you need help I would be happy to look into this or provide my two cents.

christianlupus commented 3 years ago

I am sorry, I am not aware of anyone taking this special topic forward yet. We are only a few free-time developers, so, unfortunately, we cannot give any guarantees when things are going to be implemented. There are quite involved updates running in the background at the moment and this should allow simpler development for further enhancements.

What sort of help could you provide, @LucaBernstein? Coding? Architecture? Testing possibilities? ...?

LucaBernstein commented 3 years ago

At first I'm open to discussions regarding this feature (e.g. how to handle calculation, as the schema does not really provide separate quantity, unit and descriptions fields but to me it looks rather like the values have to be extracted from the ingredients text fields) I'm looking forward to a simpler development setup as I personally find the current one, which I looked into a few minutes, not beginner-friendly. So, sure, I would also be open to coding and testing. šŸ˜ƒ

christianlupus commented 3 years ago

Regarding a dev setup, you can look at https://github.com/christianlupus/nextcloud-docker-debug. It should work but there was a change to xdebug 3 recently that could cause issues but nevertheless...

And btw you are right, the current schema does not allow the semantic definition of measurement values. There is a PR against the current schema.org to overcome that shortcoming.

dowerner commented 3 years ago

I am here because I also would like to have the quantities updated if I change the number of servings in the recipe. For now I resorted to downloading the source code and compiling it myself. As proposed by @christian96l I do all the calculation in the front-end. I just replaced the "Servings" with an input tag and added a callback to it that updates the quantites. All quantities you want to have updated you have to write in curly braces (e.g. "{2} pinches of salt"). Not the most elegant solution but it works for me and it only took me like 2h to get working (I'm a total noob when it comes to web development).

Let me know if anyone is interested in this workaround. image

malconsei commented 3 years ago

I'm a bit puzzled here. IMHO it's clear that the schema.org approach is flawed and it's preventing this (and other) apps from implementing extremely useful features like computing the right quantities for the desired servings and converting between units. Since the issue on schema.org is open since 2015, it's probably easier to convince the US to switch to the metric system than to change the schema - but couldn't cookbook work around this, by either

Also, just who else is using the schema, and is it worth sticking to it to the point of hurting functionality?

Teifun2 commented 3 years ago

@malconsei Well all recipe sites that you can import to nextcloud are using the schema.

But i agree that there is maybe potential to "sturcutre" the recipeIngredient fields in a way that this plugin could still "parse" the units. But in case of an export it would still look relatively normal?

Still the conversion stuff has a lot of problems attached to it. Different units / different unit steps. Language support? etc. Maybe this could also be an option feature to activate.

malconsei commented 3 years ago

@Teifun2 oh, I never stumbled in a cooking website with any kind of recipe export, but that's very good to know and I will look for some.

I clearly don't know enough about the ecosystem. However: Is exporting really a core functionality? How often would a user do it, and can't they sanitise the data manually? Myself, I wanted to use the app for my own recipes and I'd love to be able to convert amounts if a third person (after covid) is eating dinner, instead of the usual two; I don't have many recipes so if I export them it'd be easy to change some values. Intercompatibility in other fields is way more complex and nobody seems to make a big deal of it - e.g. trying to transfer my pictures collection from one tool to another preserving tags, transformations and stuff.

I think @spikusmax proposal was clever and easy to implement, but it seems it hasn't been pursued. I can see difficulties with "7 oz" per person leading to "1Ā¾ cups" for two ppl, but the language in this case will virtually always be English, so at least translations don't interfere. In other countries, afaik a similar case will mostly be with "spoons" or "teaspoons", but they'll either be full or 1/2 and the computation is easy by mind.

christianlupus commented 3 years ago

@Teifun2 oh, I never stumbled in a cooking website with any kind of recipe export, but that's very good to know and I will look for some.

You most probably used them. The import feature of the cookbook app relies solely on these meta data.

I clearly don't know enough about the ecosystem. However: Is exporting really a core functionality? How often would a user do it, and can't they sanitise the data manually?

The problem is not the export but the import. We are planning to do #340 which allows storing additional data to each recipe. So, the storage could be covered. Once it is in a structured form, we can export it (on all sorts of mediums) without much hassle.

The problem is that existing installations exist with huge databases of recipes. Telling these users that, sorry, their collection work will be neglected and they have to reimport or even manually reformat all their recipes will not make them happy. Additionally, one of our main development claims is to use standard JSON+LD for storage to allow external programs of 3rd parties to access the complete database. As we would leave the standard world all these will break as well.

So in general we only have two options: Either the standard gets extended or we have to store locally without any standard in the background. The latter might look simpler but will prevent us from automated parsing. To be honest, missing automated parsing will cause a wave of requests to, please, please, make the import work again to extract the data correctly so that recalculation is working. This will be a hide and seek play as it will be highly language (and page) dependant and might break in any case later. Therefore I'd rather go with the standardized way of things.

Intercompatibility in other fields is way more complex and nobody seems to make a big deal of it - e.g. trying to transfer my pictures collection from one tool to another preserving tags, transformations and stuff.

This is due to these standards involved there. The EXIF metadata is stored in a standardized way. It is not that compatibility comes from nothing. Intelligent people make a huge deal out of it to cover all cases. We try the same with e recipe data. Success is not yet there but if you are interested, you can help with the issue there.

I think @spikusmax proposal was clever and easy to implement, but it seems it hasn't been pursued. I can see difficulties with "7 oz" per person leading to "1Ā¾ cups" for two ppl, but the language in this case will virtually always be English, so at least translations don't interfere. In other countries, afaik a similar case will mostly be with "spoons" or "teaspoons", but they'll either be full or 1/2 and the computation is easy by mind.

It is not so easy. We have at least German, Spanish and Italian in the mix as well (those languages I see during reviewing issues). So there are in fact non-English languages. And not all languages handle the amounts the same. Some use decimal amounts (like 125 grams) others use fractions (1/2 cup). How are the fractional numbers >1 formated? 1 1/2 or 1Ā½? Or even some unicode magic? Those are just the most prominent examples I can think of.

l-mb commented 2 years ago

I'm a recent user to Cookbook and was wondering about this feature.

I understand the concerns of deviating from the standard data format, but this could be done in a backwards-compatible way: recipes without the extended metadata would function just as they did before, and those created or annotated with the scalar/unit/description would get more features.

The underlying data format is the root issue - customizing how that's displayed for certain users and preferences in the ingredient list (or later in the references in the steps), how to scale (from number of servings, to a base ingredient, to 20cm vs 10" cake pan, target amount, possibly more?), possibly even offering a "parsing assistant" that aids conversion (because most of the ingredients will, in fact, be in the <digit><unit> <label> format, so it could be quite useful) is a future concern.

Standards are lovely. But standards that hold back development of key functionality are not. Another way of progressing standards is by implementing extensions and showing how useful they are, and then those get folded back into the standard's next version.

christianlupus commented 2 years ago

I understand the concerns of deviating from the standard data format, but this could be done in a backwards-compatible way: recipes without the extended metadata would function just as they did before, and those created or annotated with the scalar/unit/description would get more features.

Not exactly. One of the basic concepts of the app is to provide access to standardized JSON data also for 3rd party apps/programs using the folder sync function of the desktop client. We would have to replace the existing data structure with the augmented one. There is no guarantee that these apps will still work afterward.

Adding an additional field to the JSON data is for sure possible (at least with #340) but then we are in the sync problem. What should happen if the user changes a value? Should we somehow generate the non-structured value? Or should we parse each time a plain string hoping for the best? Or is it the obligation of the user to keep things in sync?

The underlying data format is the root issue - customizing [...] is a future concern.

This is perfectly true.

Standards are lovely. But standards that hold back development of key functionality are not. Another way of progressing standards is by implementing extensions and showing how useful they are, and then those get folded back into the standard's next version.

This is only partly true. If we were a big player like google, we could dictate (to a certain point at least), how the standard is formed/evolving. We are too tiny to do this just by a mere wish. I tried to get the necessary things inserted into the standard but I am no guy of semantic web or ontologies. If there is anyone out there to help, you are welcome to step forward. Then we can try to get things rolling together.

ipped commented 2 years ago

I am here because I also would like to have the quantities updated if I change the number of servings in the recipe. For now I resorted to downloading the source code and compiling it myself. As proposed by @christian96l I do all the calculation in the front-end. I just replaced the "Servings" with an input tag and added a callback to it that updates the quantites. All quantities you want to have updated you have to write in curly braces (e.g. "{2} pinches of salt"). Not the most elegant solution but it works for me and it only took me like 2h to get working (I'm a total noob when it comes to web development).

Let me know if anyone is interested in this workaround. image

This looks like a simple and great solution: Leave the underlying data as it is and only adjust the numbers that are displayed. I'm curious, however, why you restrict recalculating to numbers enclosed within curly brackets. Why not adjust the amount if the ingredient text begin with a number to stay compatible with conventional number-unit-ingredient syntax? (To cover numbers with decimal separators and fractions as well, this regex could be used: ^\d+[\.|\,|/]?\d*) If the ingredient doesn't begin with a number, simply display e.g. 2x "a pinch of salt" as suggested by @spikusmax.

Concerning unit conversion I'd suggest to go for the simple solution for now and leave the unit as it is. It's not perfect to see 1000 g flour when it could be displayed as 1 kg flour but this should not hold back this important new conversion feature.

As for non-linear conversion necessary for baking as mentioned by @Mannshoch, I'd see this as a rather special use case and up to the baker to adjust the automatically calculated values if need be or not use automatic recalculation.

ksmolder commented 2 years ago

There's a popular Flemish cooking website called "Dagelijkse kost": https://dagelijksekost.een.be/gerechten/toast-met-boschampignons-creme-van-aardpeer-en-citroenricotta. If you scroll down to the ingredients list ("Ingrediƫnten"), you can set the number of servings you want to cook, and the ingredients will adjust automatically. This leads to a really nice user experience...

dowerner commented 2 years ago

@ipped You are right that regex could actually improve my workaround quite a bit. To be honest, I was setting up Nextcloud and just did a very quick adjustment that worked well until now. I may update and use your suggestions if it doesn't mess up my existing recipes too much.

j0hannesr0th commented 1 year ago

Hello, I migrated all my recipes from Tandoor to Nextcloud Cookbook. Now I'm missing this feature, which Tandoor has.

I think Tandoor is storing the unit, amount and name separately so scaling and calculating is easy.

Since this issue already exists since 2019 and hasn't been resolved yet I guess the chances are high that a refactoring to the "Tandoor way of storing data" is too complex?

christianlupus commented 1 year ago

The problem with this is that the recipe schema does not provide a way to store the data separated into number, unit, and name. Instead the standard we are sticking to dictates a pure string.

Currently, we try to stick with said standard to allow this party apps to understand our data. Extending the structure might be possible but at the same time might break this support.

This, any change here needs some considerations to be done. It is not forgotten and still stands open.

j0hannesr0th commented 1 year ago

@christianlupus do I understand this correctly?

You try to stick with the standard when exposing the stored data via REST-API that third-party apps/tools understand the data?

If yes, then internally we could store the data separately and when exposing the data we can concat it like this (pseudo code):

$x = '%s %s %s';
$singleString = sprintf($x, $amount, $unit, $ingredient);

So for third-party apps nothing will change since it's still one single string which will be delivered via REST-API. On the other hand we can update the docu that this string will always be delivered in this specific format (amount unit ingredient). Third-party apps are then able to parse it correctly too and implement a calculator/scaler too. We in the Nextcloud Cookbook can parse it correctly too and implement the calculator.

Extra bonus: the database will be normalized since we do not store "g" as a unit or "milk" as an ingredient 100+ (just an estimation depending on your recipes) times.

christianlupus commented 1 year ago

Hello @j0hannesr0th,

well, that is not 100% true what you are assuming here. There are in fact three ways to access the recipes that I am aware of: The website and the REST API you have already identified. There is also one Android app (and as far as I know one desktop app) that makes use of the file synchronization apps of Nextcloud to sync the recipes to the local store and use that set. This means that the JSON files in the storage must be conforming with the standard as well.

We have the idea to add additional data in a separate per-recipe JSON file (#340) that contains custom information. This one will not stick to the standard and we can use it to store for example the decomposed ingredient values.

Once there is a storage location available, we need to think about how to migrate the current data (aka the pure strings) into the structured format. There are already some ideas but no ultimate solution so far.

github-actions[bot] commented 1 year ago

This PR/issue depends on:

j0hannesr0th commented 1 year ago

@christianlupus ping me if you made a decision. I want to help on this feature.

j0hannesr0th commented 1 year ago

Sorry @christianlupus I have to ping you again.

What about adding a regex as a quick win?

Using regex on the input of the ingredient:

So the input is structured in: amount unit ingredient.

Now only ingredients in the given format are accepted. Nothing changes for third-party apps since still one single string will be delivered.

Once all ingredients of the recipe are "migrated" into the new format we can show the calculator and if they are not migrated correctly we show a button "migrate" and open a view where the user has to update the ingredients of the specific recipe. So the user can update step by step and they don't have to convert all recipes at once.

What are your thoughts about this?

seyfeb commented 1 year ago

So the input is structured in: amount unit ingredient.

How would you handle things like:

(there are certainly more of these typically and arguably useful ingredient descriptions)

is minced meat a different ingredient than meat? Should it be "meat (minced)", where meat is the ingredient and minced is simply a kind of preparation (you might have the tools at home)?

j0hannesr0th commented 1 year ago

@seyfeb

How would you handle things like:

* a pinch of salt

* pepper to taste

* 1 tsp. dried or fresh basil

* 500g broccoli, alternatively cauliflower

So basically Iā€™d suggest to structure it like this:

  1. any positive float value with only two decimal places (n.XX)
  2. followed by whitespace
  3. any char unlimited length
  4. followed by whitespace
  5. any char unlimited length

OR we could even allow

  1. any positive float value with only two decimal places (n.XX)
  2. followed by whitespace
  3. any char unlimited length

The only important thing is, that we have the amount separated from the other parts.

Thereā€™s even no need to add the regex on the input as a validation. Itā€™s possible to check all ingredients just in time if they have the ā€žcorrectā€œ syntax. If they have it, we show the calculator ā€“ if not, we disable it. The calculator just has to parse the ingredient and split by whitespace.

Example recipe ā€žbutter bread with cressā€œ (2 servings): grafik

When clicking the + or - sign the numbers only change on client side. The ā€žalgorithmā€œ is: amount / storedServings * clientServings

recipe ā€žbutter bread with cressā€œ (changed to 6 servings): grafik

Of course we donā€™t show the computing path ā€“ itā€™s just for better understanding. I know grammatically itā€™s not correct to say ā€ž3 piece of butterā€œ ā€“ but who cares? In my opinion most of the people do care more about this feature instead of grammatically perfect recipes.

Zocker1999NET commented 1 year ago

Itā€™s possible to check all ingredients just in time if they have the ā€žcorrectā€œ syntax. If they have it, we show the calculator ā€“ if not, we disable it.

I think it may be better to let the calculator be enabled, but on entries which don't follow the expected syntax to write out (with italic formatting so the user knows, it was added by the calculator):

3 times of pinch of salt

and when the user hovers with the mouse over the italic part, an explanation could show up saying "We didn't found a number to increase/decrease this ingredient. We expect it to be number (of) name." so the user knows how to fix this if this is not appropriate, e.g. if the original contains an ingredient called "a pinch of salt" or "three bananas" (which need to be "1 pinch of salt" & "3 bananas").

Just disabling the calculator could feel cumbersome if you have a big library of "not appropriate" recipes where you then would be required to fix every single ingredient before you can finally use the calculator on them. At least having this fallback enables user to at least use the calculator without needing to fix it right away, as especially IMO if ingredients have no number, the amount of them is most often not that important (e.g. spices), while for other ingredients having the calculator really helps (e.g. flour).

j0hannesr0th commented 1 year ago

@christianlupus @seyfeb

I can implement it as described in my last post.

Do you merge it, if I develop it? I don't want to invest time for a merge request which will never be merged.

Eothred commented 1 year ago

How would you handle things like:

* a pinch of salt

* pepper to taste

* 1 tsp. dried or fresh basil

* 500g broccoli, alternatively cauliflower

Talking from experience using another app, I would say if you multiply the initial numbers for each bullet that suffices. E.g. for "a pinch of salt", nothing happens but I remember I've multiplied by X so should probably increase accordingly compared to the default recipe. If a recipe says "one banana", I simply edit my recipe and put "1 banana" so that the multiplier works. I did not find this unreasonable or problematic I would say.

Multiplier that only works on the initial number (also without space for unit, such as "500g"), is afaik much easier and robust to implement, and solves 95% of the issue. Personally I would not see the need to spend tremendous effort to solve the last 5%.

christianlupus commented 1 year ago

Let's discuss the PR of @j0hannesr0th in a separate discussion to keep here only to separate the technical discussions a bit.

GVLLIFESTYLE commented 1 year ago

when will be the next release with those new features?

christianlupus commented 1 year ago

The next release will be done once the outstanding issues are solved. There are a few minor issues to be addressed and one security concern. There is not yet a final schedule but it should not be too long.

GVLLIFESTYLE commented 8 months ago

any update on the release date of this feature?

seyfeb commented 8 months ago

It has been released a month ago, see 0.10.3 in the CHANGELOG.

GVLLIFESTYLE commented 8 months ago

thanks