Overview
Souschef is a desktop smart cooking sidekick, offering personalised guidance every step of the way. From recipe
recommendations just for you, to meal planning and inventory management, SousChef has everything you need to improve
life in the kitchen.
Our users interact via CLI and GUI created with JavaFX. Written in Java, experience what many are enjoying.
Summary of contributions
-
Code contributed: [Functional code]
-
Major enhancement: added the ability to manage ingredients
-
What it does: Allows the user to track the stock of ingredients, view recipe according to ingredient and check shop amount.
-
Justification: This is a practical feature which would enhance user experience of cooking preparation.
-
Highlights: Rather than mere stock tracking, this feature contains functions providing cognitive shortcut for users. Also, it enables proper integration between information related to ingredient and recipe.
-
-
Major enhancement: restructured entire logic component
-
Justification: This was necessary to enable integration across multiple features, while maintaining efficiency by distinguishing shared processes and making use of general classes.
-
Highlights: This enables both modularization and efficient integration of features.
-
-
Other contributions:
Contributions to the User Guide
Given below are sections I contributed to the User Guide. They showcase my ability to write documentation targeting end-users. |
Ingredient Manager Commands (Only applicable in ingredient context)
Add an ingredient: add
Adds an ingredient to the ingredient manager.
Format:
add NAME AMOUNT SERVING_UNIT DATE
Sort and list all ingredients: list
Shows a list of ingredients in ingredient manager. Ingredients are sorted by date, so that the ingredients with
earlier date
are placed high in order.
Format:
list
Edit ingredient info: edit
Edit an existing ingredient in ingredient manager.
Format:
edit INDEX FIELD_NAME NEW_VALUE [MORE FIELD_NAME NEW_VALUE]…
Find ingredient: find
Find ingredients in ingredient manager whose name contains any of the given keywords.
Format:
find KEYWORD [MORE_KEYWORDS]…
Delete ingredient: delete
Delete ingredient in ingredient manager according to its index in the last shown list.
Format:
delete INDEX
Clear all ingredients: clear
Clears all ingredients in ingredient manager.
Format:
clear
Ingredient-Recipe Query Commands (Only applicable in cross context)
View Recipes based on Ingredients view
By default, the page show the recipe list that is same with the recipe list shown in recipe context at the point of
initiation of the
application. User can
filter or sort the recipes
based on ingredients contained in recipes. Also, needed amounts of ingredients are calculated by considering the number
of
serving units and ingredients stored in ingredient manager, so
that
user can take a look by applying select command later.
Format:
view NUMBER_OF_SERVINGS [include [inventory] KEYWORD [MORE_KEYWORDS]…] [prioritize [inventory] KEYWORD
[MORE_KEYWORDS]…]
View needed amounts of ingredients for a Recipe select
For a recipe in the list shown as a result of above command(3.4.1.), user can view amounts of respective ingredient
in the recipe
that
needs to be additionally prepared. It reflects number of serving units and
refers to Ingredient Manager to get the amount of ingredients the user currently have.
Format:
select INDEX
List all recipes and undo calculation: list
Shows a list of recipes. It restores the default state of the list, undoing the calculation resulting from 'view
recipes based on ingredients'
command(3.4.1.).
Format:
list
Contributions to the Developer Guide
Given below are sections I contributed to the Developer Guide. They showcase my ability to write technical documentation and the technical depth of my contributions to the project. |
Logic component
API :
Logic.java
-
Logic
uses theAppContentParser
class to parse the user command. -
AppContentParser
passes necessary model to each feature parser such asIngredientParser
according to the context. -
This results in a
Command
object which is executed by theLogicManager
. -
The command execution can affect the
Model
(e.g. adding an ingredient) and/or raise events. -
The result of the command execution is encapsulated as a
CommandResult
object which is passed back to theUi
.
Given below is the Sequence Diagram for interactions within the Logic
component for the execute("add onion 100
gram 10-23-2018")
API call.
Ingredient Manager
Total management of ingredients that user currently have
Ingredient Manager is an address book of ingredients, with some basic functions similar to that of a normal address
book such as
add, edit, delete and list. Additionally, Ingredient Manager has some useful functions specific for management of
ingredients.
Firstly, serving units can be converted to a common serving unit with reference to the serving unit dictionary.
Conversion to a common serving unit is necessary to enable arithmetic calculation between amounts. Also, it is easier to
compare
between ingredients when the amounts are shown in common serving units. Secondly, when you apply the list command,
ingredients are sorted by date. Since ingredients have to be consumed in a limited period, it keeps user be reminded of
old ingredients.
Current implementation of serving units dictionary
Ingredient Manager uses gram
for the common serving unit. Serving unit dictionary is implemented with static
HashMap
in
IngredientServingUnit
class, which
contains
names of a serving unit as a key and a IngredientServingUnitDefinition object as a value.
IngredientServingUnitDefinition
has three fields, which are a serving unit to be converted, a common serving unit,
and
a constant to be multiplied for conversion. When conversion is to be done, you find the value in the HashMap with an
input serving unit as a key. Then, you multiply the amount of ingredient with the constant and replace the current
unit with a
common unit. This process is wrapped in a method called convertToCommonUnit()
in ingredient models which contains
amount field.
Alternative Implementation of serving units dictionary
In the current implementation, a serving unit to be converted exists both as a key and in a value of the HashMap. This duplication can be removed by transforming the form of the value in the HashMap from a definition object to an array containing the other two fields of the object. However, creating a separate class to wrap three fields is more desired for abstraction. In the current version of the application, definition object is only used for conversion to a common serving unit. But in later version, conversion can be done the other way around for the purpose of display. Also, in a more complete version of the dictionary, definition should be expanded to cover information related to validity of combination between specific serving unit and ingredient, and its conversion value. Also, using HashMap brings huge convenience in further implementation of functions which include searching of value in the dictionary, cancelling out the cost of duplication.
View recipes according to ingredients, and check shop amount
This command works on separate context called cross, because the result of command manipulates list of recipes, not ingredients. The command filters(include) and sorts(prioritize) recipes based on ingredients given in the command, and makes use of information stored in Ingredient Manager in two ways. Firstly, you can provide all ingredients in Ingredient Manager as parameter for filtering or sorting. This might be useful when a user wants to find recipe that maximizes the use of existing ingredients. Secondly, for the recipes that are on the list as a result of filtering and sorting, additional amount of ingredients that need to be prepared for a recipe is calculated. Because ingredients in Ingredient Manager are considered as stock that the user currently have, their amounts are subtracted from the desired amount, calculated considering the number of servings. After cooking, she can go back to Ingredient Manager and edit amount of ingredients or delete ingredients used for cooking.
Current implementation of cross recipe model
Although it looks similar, models used for recipe context and cross context are different. crossRecipe
class extends
Recipe class with one more additional field, a Map named neededIngredients. This has IngredientDefinition
object as a
key,
and IngredientPortion
object as a value. It is to store information of needed amount of an ingredient to amount field of IngredientPortion object after calculation is done.
Current implementation of ingredient models
There are three ingredient related models, namely IngredientDefinition
, IngredientPortion
, and
Ingredient
.
IngredientDefinition is a wrapper class for ingredient name. IngredientPortion inherits IngredientDefinition and
additionally includes amount
field. Ingredient again inherits IngredientPortion, and it is the most complete version of ingredient with date
information, used by Ingredient Manager.
Reason for hierarchical implementation is that there exists different needs for ingredient related fields
across features or functions. For example, ingredient in recipe uses IngredientPortion, and ingredient in Ingredient
Manager uses Ingredient. IngredientDefinition is used as a key of a HashMap in implementing 'view recipes
according to ingredients' function. It can be used to construct ingredient dictionary or to expand unit dictionary in
the future version of the application.