Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Java functional programming exercise

NotificationsYou must be signed in to change notification settings

tercanfurkan/java-functional

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This java functional programming exercise implements a food ingredients API.

An ingredient list is a list of product-ingredient relations, with a multiplier describing how many units of each ingredient is needed for making the product. A good example for an ingredient list is a sandwich. A sandwich is made from multiple ingredients (bread, mayonnaise, eggs, various cold cuts, etc.) which may themselves be intermediate products that are made of other intermediate ingredients (such as mayonnaise) or basic ingredients that do not have further ingredients (e.g. oil, yeast).

Ingredient list is stored in a tree structure, where the top-level product (such as sandwich or fried eggs) is the root and ingredients are either intermediate items (like mayo) or leaves (such as yeast). An item can only be once in the tree. For example imaginary product SALT can not be both child of BREAD and MAYO. However, an ingredient can be used several times in different trees: it's valid to have EGG as child of fried eggs and sandwich.

All ingredient lists are supplied in a CSV file.

Interfaces

#1 Ingredients Deconstruction Interface

Given an input with the following structure:

codeingredient_codestart_dateend_datemultiplier
CLUB_SANDWICHBREAD1
BREADFLOUR1
BREADYEAST1
CLUB_SANDWICHMAYO1
MAYOEGG1
EGGEGG_WHITE1
EGGEGG_YOLK1
MAYOOIL1
MAYOMUSTARD1
MUSTARDGARLIC_POWDER1
GARLIC_POWDERGARLIC1
CLUB_SANDWICHBACON1
FRIED_EGGSEGG1
FRIED_EGGSOIL1

Methods:

It constructs a tree structure that implements the given methods:

Set<String> getNamesForProducts(String productCode)

For a given product code, anywhere in the tree, it returns the values of ancestor products in an unordered collection, like Set.

Set<String> getNamesForIngredients(String productCode)

For a given product code, anywhere in the tree, it returns the values of child products in an unordered collection, like Set.

List<Map> getIngredients(String productCode)

For a given product code, anywhere in the tree, it returns every ingredient (children) for all levels. Returned value is an ordered list of key-value pairs (Maps) containing following information: product code, depth in the current tree, multiplier.

Sample Output:

getNamesForProducts("GARLIC_POWDER") => Set("MUSTARD", "MAYO", "CLUB_SANDWICH")getNamesForIngredients("CLUB_SANDWICH") => Set("BREAD", "MAYO", "BACON", "FLOUR", "YEAST", "EGG", "EGG_WHITE", "EGG_YOLK" "OIL", "MUSTARD", "GARLIC_POWDER", "GARLIC")getIngredients("CLUB_SANDWICH") => [    {code: "BREAD", depth: 1, multiplier 1},    {code: "FLOUR", depth: 2, multiplier 1},    {code: "YEAST", depth: 2, multiplier 1},    {code: "MAYO", depth: 1, multiplier 1},    {code: "EGG", depth: 2, multiplier 1},    {code: "EGG_WHITE", depth: 3, multiplier 1},    {code: "EGG_YOLK", depth: 3, multiplier 1},    {code: "OIL", depth: 2, multiplier 1},    {code: "MUSTARD", depth: 2, multiplier 1},    {code: "GARLIC_POWDER", depth: 4, multiplier 1},    {code: "GARLIC", depth: 3, multiplier 1},    {code: "BACON", depth: 1, multiplier 1},]getIngredients("GARLIC_POWDER") => [    {code: "GARLIC", depth: 1, multiplier 1},]getIngredients("GARLIC") => []getIngredients("FRIED_EGGS") = [    {code: "EGG", depth: 2, multiplier 1},    {code: "EGG_WHITE", depth: 3, multiplier 1},    {code: "EGG_YOLK", depth: 3, multiplier 1},    {code: "OIL", depth: 2, multiplier 1}]

#2 Ingredient Availability Interface

Ingredients may have a start date and an end date defined. When an ingredient has a start and end date defined and its multiplier set to zero, it’s considered inactive for that period. If an ingredient has only start date defined it means that it's active from that date to eternity. In similar fashion having only end date defined means that the ingredient is active from beginning of time up to the given date.

It's possible to substitute an inactive ingredient with other ingredients. Thus there may be other, similar ingredients listed as active during that time. If you have a an ingredient replacing another for any time range (e.g. HYPER_YEAST replaces SUPER_YEAST on 2016-12-24) you also need to explicitly set the replaced ingredient inactive (zero multiplier) for the given period or otherwise the both ingredients would be considered active for the time range.

Active/inactive ingredients appear in the data as follows:

codeingredient_codestart_dateend_datemultiplier
CLUB_SANDWICHBREAD1
BREADFLOUR1
BREADYEAST1
BREADYEAST2016-12-102016-12-260
BREADSUPER_YEAST2016-12-102016-12-261
BREADSUPER_YEAST2016-12-242016-12-240
BREADHYPER_YEAST2016-12-242016-12-241
CLUB_SANDWICHMAYO1
MAYOEGG1
MAYOEGG2016-12-062017-01-010
MAYOEGGS_ORGANIC2016-12-062017-01-011
MAYOOIL1
MAYODIJON_MUSTARD2016-11-201
MAYOFRENCHS_MUSTARD2016-11-211
MUSTARDGARLIC_POWDER1
GARLIC_POWDERGARLIC1
CLUB_SANDWICHBACON1
CLUB_SANDWICHBACON2016-12-312016-12-310
CLUB_SANDWICHFAKE_BACON2016-12-312016-12-311
FAKE_BACONHAM1
FAKE_BACONBACON_SPICE1

Methods:

This overloads the getIngredients interface to support date-specific queries for ingredients as follows:

List<Map> getIngredients(String productCode, LocalDate date)

For a given product code and date, anywhere in the tree, it returns every ingredient (children) for all levels including or excluding ingredients that are active and inactive for the given date. As before, the returned value is an ordered list of maps.

Sample Output:

getIngredients("BREAD", "2000-01-01") => [    { code: "FLOUR", depth: 1, multiplier: 1 },    { code: "YEAST", depth: 1, multiplier: 1 }]getIngredients("BREAD", "2016-12-24") => [    { code: "FLOUR", depth: 1, multiplier: 1 },    { code: "YEAST", depth: 1, multiplier: 0 },    { code: "SUPER_YEAST", depth: 1, multiplier: 0 },    { code: "HYPER_YEAST", depth: 1, multiplier: 1 }]getIngredients("BREAD", "2016-12-25") => [    { code: "FLOUR", depth: 1, multiplier: 1 },    { code: "YEAST", depth: 1, multiplier: 0 },    { code: "SUPER_YEAST", depth: 1, multiplier: 1 }]

#3 Ingredients Forecasting Interface

Ordering basic ingredients is based on forecasts. Forecasts are supplied as a separate CSV, with a separate ingredient for each sandwich type and date. The data is provided byDataProvider.

codeingredient_codestart_dateend_datemultiplier
CLUB_SANDWICHBREAD1
BREADFLOUR2
BREADYEAST1
BREADYEAST2016-12-102016-12-260
BREADSUPER_YEAST2016-12-102016-12-261
BREADSUPER_YEAST2016-12-242016-12-240
BREADHYPER_YEAST2016-12-242016-12-240.1
CLUB_SANDWICHMAYO3
MAYOEGG2
EGGEGG_WHITE1
EGGEGG_YOLK1
MAYOOIL2.5
MAYOMUSTARD1
MUSTARDGARLIC_POWDER0
MUSTARDMUSTARD_SEEDS5
GARLIC_POWDERGARLIC1
CLUB_SANDWICHBACON4
FRIED_EGGSEGG1
FRIED_EGGSOIL1
codeforecastdate
CLUB_SANDWICH2.02017-01-01
FRIED_EGGS5.02017-01-01
CLUB_SANDWICH4.02016-12-24

Methods:

getForecastsFor()

Calculates the need for specific basic ingredients for the given date. The output is the orders sent to suppliers for restocking the inventory for the given date. In reality there can be millions of forecasts for different products in different dates so performance can be considered in the future as well.

List<Map> getForecastsFor(LocalDate date)

For the given date, it calculates the demand of basic ingredients (i.e. tree leaves) for all active products. Returned value is a list of maps containing the ingredient code (String), amount to order (double) and date (LocalDate).

Sample Output:

getForecastsFor("2017-01-01") => [    { code: "FLOUR", amount: 2.0 * 2, date: "2017-01-01" },    { code: "YEAST", amount: 2.0 * 1.0, date: "2017-01-01" },    { code: "EGG_WHITE", amount: (2.0 * 3 * 2 * 1) + (5.0 * 1), date: "2017-01-01" },    { code: "EGG_YOLK", amount: (2.0 * 3 * 2 * 1) + (5.0 * 1), date: "2017-01-01" },    { code: "OIL", amount: (2.0 * 3 * 2.5) + (5.0 * 1), date: "2017-01-01" },    { code: "MUSTARD_SEEDS", amount: 2.0 * 3 * 1 * 5, date: "2017-01-01" },    { code: "BACON", amount: 2.0 * 4, date: "2017-01-01" }]getForecastsFor("2016-12-24") => [    { code: "FLOUR", amount: 2.0 * 2, date: "2016-12-24" },    { code: "HYPER_YEAST", amount: 4.0 * 0.1, date: "2016-12-24" },    { code: "EGG_WHITE", amount: 2.0 * 3 * 2 * 1, date: "2016-12-24" },    { code: "EGG_YOLK", amount: 2.0 * 3 * 2 * 1, date: "2016-12-24" },    { code: "OIL", amount: 4.0 * 3 * 2.5, date: "2016-12-24" },    { code: "MUSTARD_SEEDS", amount: 4.0 * 3 * 1 * 5, date: "2016-12-24" },    { code: "BACON", amount: 4.0 * 4, date: "2016-12-24" }]

About

Java functional programming exercise

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp