Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Module for parsing shopping lists and dinner menus and compiling shopping lists.
groceries
Tools for parsing human readable shopping lists and recipe ingredients.
pip install groceries-tobiasli
groceries
contains a set of classes that solve a lot of shopping and food-related problems:
Ingredient
is a container for a food item, and parses amount, unit and item name from an arbitrary string. The base structure for an Ingredient
string is Optional[amount] Optional[unit] grocery_name, Optional[comment]
.GroceryList
is a container for Ingredients
and handles summation of all ingredients, as well as algebra.Cookbook
is a container for Recipe
, and make them searchable.Menu
is the class returned when you use a Cookbook
to parse an actual, typed shopping list. It contains the recipes and ingredients that are parsed from the shopping list.Ingredient
is a class that takes any arbitrary string describing an
amount of an grocery item. The amount and unit is generalized and with
the formatting in groceries
the unit can be represented in
from groceries import Ingredient
print(repr(Ingredient('10 2/3 tbs soy sauce')))
# <Ingredient object: 1.60 dl soy sauce: <Unit: volume: [liter, litre, liters, ...]>>
To simply get the most reasonable representation of the Ingredient
,
simply convert it to a string:
print(Ingredient('302.3949133 grams baked beans'))
# 1 lbs baked beans
GroceryList
is the base component for most of the functionality in groceries
. A GroceryList
accepts groceries
as strings on a human readable format. They are added to a GroceryList
as Ingredient
instances.
from groceries import GroceryList
gl = GroceryList()
gl.add_ingredients([
'2 pounds sugar',
'2 kg sugar',
'chocolate',
'1/4 floz foo',
'1 2/9 tbs foo'
])
print(gl)
# <GroceryList object: 3 ingredients
# chocolate,
# 0.26 dl foo,
# 2907.18 g sugar
# >
GroceryList
instances can be added, subtracted with other GroceryLists
. They can also be multiplied with skalars.
gl = gl - GroceryList(ingredients=['953.5 g sugar', 'chocolate']) * 2
print(gl)
# <GroceryList object: 2 ingredients
# 0.26 dl foo,
# 1.00 kg sugar
# >
The GroceryList
class is used to represent ingredients in recipes. Recipe
is a class that contains information
on how to cook a specific meal. You can have multiple Recipes
and add them to a Cookbook
.
The recipes are searchable both on name and tags.
# Demo scripts for grocery readme.
from groceries import Recipe, Cookbook
recipe1 = Recipe(
name='Carbonara',
tags=['pasta', 'fast', 'egg', 'bacon'],
time=20,
serves=2,
how_to='''Cook pasta. As pasta is preparing, fry bacon.
When bacon is done, add frozen pees and continue frying until pees are cooked.
Mix finished pasta with bacon and pees. Add eggs and grated parmesan and stir.
Season with salt and pepper.''',
ingredients=[
'150 g spaghetti',
'100 g bacon',
'100 g frozen green pees',
'2 eggs',
'50 g parmesan',
'salt',
'pepper'
])
recipe2 = Recipe(name="Mac'n cheese", tags=['pasta', 'fast'], time=5, serves=2,
how_to='''Cook mac. Add cheese. serve.''', ingredients=['150 g maccaroni', '100 g cheese', ])
recipe3 = Recipe(name='Chocolate', tags=['sweet', 'dessert'], time=2, serves=2, how_to='''Eat chocolate.''',
ingredients=['200 g chocolate'])
cookbook = Cookbook(recipes=[recipe1, recipe2, recipe3])
# Accepts fuzzy string matching:
print(cookbook.find_recipe('mac cheese'))
# <Recipe object: Mac'n cheese>
# Mac'n cheese is the first match for pasta, but searches are cycling.
# So when performing a category match again you won't be presented
# with the same recipe again:
print(cookbook.find_recipe('pasta'))
# <Recipe object: Carbonara>
Menu
is a class for parsing an entire weeks worth of shopping,
with syntax for meals on specific days as well as regular groceries.
# Continuation from previous code block.
menu = cookbook.parse_menu('''Monday: mac cheese
Tuesday: sweet
Wednesday: pasta
2 tbs coffee
1 floz baked beans
1 banana
2 banana
4 liters coffee''')
print(menu.generate_processed_menu_str())
# Monday: Mac'n cheese til 2
# Tuesday: Chocolate til 2
# Wednesday: Carbonara til 2
# 0.30 dl coffee
# 0.30 dl baked beans
# 1 banana
# 2 banana
# 4 l coffee
print(menu.groceries)
# <GroceryList object: 13 ingredients
# 100 g bacon,
# 0.30 dl baked beans,
# 3 banana,
# 100 g cheese,
# 200 g chocolate,
# 4.03 l coffee,
# 2 eggs,
# 100 g frozen green pees,
# 150 g maccaroni,
# 50 g parmesan,
# pepper,
# salt,
# 150 g spaghetti
# >
groceries
has built in functionality to change whatever configuration
defines the units, ingredient rules and formatting.
To change a particular config, either
groceries.configs.config_types
.To finally set a specific config, use configs.set_config()
.
from groceries import config, language
print(config.language.language_name)
# 'English'
config.set_config(language.norwegian.language)
print(config.language.language_name)
# 'Norwegian'
A special condition applies if you are changing unit configs.
For Units, specifically, we need to reload the unit definition if the
config relating to unit handling is changed. This is done via
units.reload_units()
from groceries import config, configs, units, Ingredient
print(Ingredient('2 lbs butter'))
# 2 lb butter
But we want to force a different config for units. We want to use a
purely metric unit definition that will always format Ingredient
s as
metric.
To do that we have to find the unit definition that we want, and set that config. Since we are changing the units, we also have to reload the units.
config.set_config(configs.unit_definition.metric.unit_definition)
units.units.reload_units()
The new formatting will yield metric, as inches is removed from the formatting definition.
print(Ingredient('2 lb butter'))
# 907.18 g butter
So, happy shopping!
FAQs
Module for parsing shopping lists and dinner menus and compiling shopping lists.
We found that groceries-tobiasli demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.