Skip to content

Commit

Permalink
Committing all project files
Browse files Browse the repository at this point in the history
  • Loading branch information
lizziel committed May 13, 2014
0 parents commit c30e169
Show file tree
Hide file tree
Showing 35 changed files with 1,961 additions and 0 deletions.
Binary file added MakeMenu
Binary file not shown.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add:
g++ MakeMenu.cpp fooddatabase.cpp foodgroup.cpp ingredient.cpp menuplanner.cpp menu.cpp meal.cpp alacarte.cpp pairmeal.cpp halfmeal.cpp salad.cpp bruschetta.cpp burger.cpp soup.cpp sandwich.cpp -o MakeMenu
60 changes: 60 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
C++/Object-Oriented Programming Final Project
Lizzie Lundgren
May 12, 2011

This directory contains all files needed for a menu planner program called MakeMenu.

Overview

The program plans a menu of up to 7 dinners and 7 lunches while optimizing using foods that the user has indicated she already has in file have.txt. All possible ingredients in the meals are stored in another text file: foods.txt.

The user is asked how many lunches and how many dinners she would like planned. The algorithm is based on what I use to plan out the meals for my girlfriend and I at the start of the week. To minimize cooking, the portion size of as many meals as needed are doubled to use leftovers. A cooking session may result in a dinner and a lunch but not two dinners or two lunches (unless the user ultimately decides to spread them out this way). A cooking session never results in more than 2 meals so maximum frequency per meal is 2.

Each meal represents two portion sizes. A meal with a frequency of 1 means it can be a lunch or dinner for two. A meal with a frequency of 2 means it is meant to be used as both a dinner for two and a lunch for two.

Internally the main is in MakeMenu.cpp and that is where the highest level of the program is executed.

The Food Database

First, a Fooddatabase object is created from the foods.txt file. As administrator of the program I have customized the food database to only foods that my girlfriend and I like to eat. It also includes estimated price per ingredient per meal (2 servings).

The Fooddatabase object stores the different types of food in vectors of Foodgroup object pointers. Foods are categorized by foodgroup type (e.g. vegetable) in the fooddatabase file. Each foodgroup object contains a vector of Ingredient objects, each of which has the name and cost that is in the food database. Several of the foodgroups are customized for certain types of meals that we like to eat. For example, "salad toppings" is a foodgroup. New foodgroups are easily added by simply following the format in the foodatabase.txt file.

The Menu Planner

Next, a MenuPlanner object is created. The menuplanner is where the menu actually gets created. In its constructor it builds the have list that contains what foods the user has and in what quantities. Quantities are the same as for meals: 1 indicates two servings, 2 indicates four servings, etc.

The menuplanner starts out with am empty used list which stores what foods are used in the menu and in what quantities. It also starts out with a have left list equal to the have list and which stores what ingredients and in what quantities have not been used yet. These, along with the have list, are actually vectors of pairs where the first in the pair is ingredient name and the second is amount.

When the MenuPlanner object is constructed it creates a Menu object. The Menu object contains a vector of Meal pointers and the vector is initialized as empty. It also contains the number of lunches and dinners that need to be created, accepting the user input when it is initialized. It uses these numbers to calculate how many meals and with what frequency per meal will need to be created.

Making the Menu

Once the Menuplanner object has been created and the Menu object has been constructed it is time to make the menu. The Menuplanner object calls its makeMenu() method to do this. It builds all meals with frequency equal to 2 first, followed by all meals with frequency of 1.

There are currently two types of meals: alacarte and pairmeal. Each is a class that inherits from the Meal abstract base class. Alacarte consists of four ingredients, each of a different Foodgroup, and basically is four items separately cooked and put on the same plate. The user has the option to combine them in any way they please of course.

The other type of meal is Pairmeal which contains two halfmeals. There are currently five types of halfmeals, each of which is a class that inherits from the Halfmeal abstract base class. The five types are Salad, Soup, Bruschetta, Sandwich, and Burger. All of these are items we eat but always with something else. For this program that something else is another halfmeal.

The meals for the menu are created in a loop. The type of meal that is created is based on statistics. A random number generator makes it such that on average 1 in 4 meals is a pairmeal, while the rest are alacarte.

Creating an alacarte meal is pretty simple. Query the database for the four ingredients from the specific desired foodgroup. The have left list, used list, and frequency of the meal are all used to optimize using ingredients that the user has left or not used.

Creating a pairmeal is more complicated. Two halfmeals must be created. Each of the halfmeals is similar to the alacarte meal: they consist of one or more ingredients from very specific foodgroups. When a pairmeal is created it uses some rules on what halfmeals are created. The quick summary is if the user has "baguette" or "burger" either Bruschetta or Burger are created. Else, a halfmeal type is randomly picked. Once one halfmeal has been found, the other one chosen cannot be the same one. In addition, if the first halfmeal is bread-based (burger, bruschetta, or sandwich), only a soup or salad can be chosen to accompany it.

After one meal is created, the used and have left lists in the menuplanner are updated. These are used during the making of the next meal to optimize using ingredients the user has and also not repeating ingredients used more than necessary.

Then What?

After the menu has been planned a number of things are displayed to the user.
These include:
Each meal, with ID number, frequency, type of meal, and ingredients.
Whether any of the foods in the have.txt file were not contained in the fooddatabase.
What foods and in what amounts are left over that the user has.
What foods and in what amounts are used in the menu.

The user is asked if the menu is acceptable. They can either say yes and quit, or say no and make a new menu. This is done by making a new menuplanner.

Whether any of the foods in the have.txt file were not contained in the food database is shown to the user to give them a chance to potentially update either the food database or the have list. Having a food not in the database does not disrupt making a menu but it does get ignored with no chance of making its way into the menu. The user can therefore see if this is happening and then quit and do something about it if it is.

If the user accepts the meal, a shopping list is printed that contains the name of each ingredient that needs to be acquired along with the amount. The estimated worth of the menu is also printed.
49 changes: 49 additions & 0 deletions alacarte.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// alacarte.cpp

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include "meal.h"
#include "alacarte.h"
#include "ingredient.h"
#include "fooddatabase.h"
using std::string;
using std::vector;
using std::pair;
using std::cout;
using std::endl;

typedef vector< pair< string,size_t> >::const_iterator vpiter;
typedef vector<string>::const_iterator vsiter;

Alacarte::Alacarte( const FoodDatabase& fdb, const vector< pair< string, size_t > >& used, const vector< pair< string, size_t > >& haveLeft, size_t ID, size_t freq) : Meal( ID, freq )
{

m_veg = getIngred("vegetable", fdb, used, haveLeft);
m_foodInMeal.push_back(m_veg.getName());

m_protein = getIngred("protein", fdb, used, haveLeft);
m_foodInMeal.push_back(m_protein.getName());

m_starch = getIngred("starch", fdb, used, haveLeft);
m_foodInMeal.push_back(m_starch.getName());

m_savory = getIngred("savory", fdb, used, haveLeft);
m_foodInMeal.push_back(m_savory.getName());

}

void Alacarte::printMeal() const
{
cout << "Meal " << m_ID << endl;
cout << "\tFrequency: " << m_freq << endl;
cout << "\tA La Carte: " << m_veg.getName() << ", " << m_starch.getName();
cout << ", " << m_protein.getName() << ", " << m_savory.getName() << endl << endl;
}

double Alacarte::getMealCost() const
{
double cost = m_veg.getCost() + m_protein.getCost() + m_starch.getCost() + m_savory.getCost();
return cost;
}
29 changes: 29 additions & 0 deletions alacarte.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// alacarte.h

#ifndef _ALACARTE_H
#define _ALACARTE_H

#include <string>
#include <vector>
#include "meal.h"
#include "ingredient.h"

class FoodDatabase;

class Alacarte : public Meal
{
public:
Alacarte(const FoodDatabase& fdb, const std::vector< std::pair<std::string, size_t> >& used, const std::vector< std::pair<std::string, size_t> >& haveleft, size_t ID, size_t freq);
virtual ~Alacarte() {}
virtual void printMeal() const;
virtual double getMealCost() const;

private:
Ingredient m_veg;
Ingredient m_protein;
Ingredient m_starch;
Ingredient m_savory;

};

#endif
45 changes: 45 additions & 0 deletions bruschetta.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// bruschetta.cpp

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include "halfmeal.h"
#include "bruschetta.h"
#include "ingredient.h"
#include "fooddatabase.h"
using std::string;
using std::vector;
using std::pair;
using std::cout;
using std::endl;

Bruschetta::Bruschetta( const FoodDatabase& fdb, const vector< pair< string, size_t > >& used, const vector< pair< string, size_t > >& haveLeft, size_t freq) : Halfmeal( freq )
{
m_bread = fdb.getSpecificIngred( "bruschetta bread", "baguette" );
m_foodNames.push_back(m_bread.getName());

m_topping1 = getIngred("bruschetta topping", fdb, used, haveLeft);
m_foodNames.push_back(m_topping1.getName());

m_topping2 = getIngred("bruschetta topping", fdb, used, haveLeft);
m_foodNames.push_back(m_topping2.getName());

m_topping3 = getIngred("bruschetta topping", fdb, used, haveLeft);
m_foodNames.push_back(m_topping3.getName());
}

void Bruschetta::printHalfmeal() const
{
cout << "Bruschetta: " << m_bread.getName() << ", " << m_topping1;
cout << ", " << m_topping2 << ", " << m_topping3;
cout << endl;
}

double Bruschetta::getCost() const
{
double cost = 0;
cost += m_bread.getCost();
cost += m_topping1.getCost() + m_topping2.getCost() + m_topping3.getCost();
return cost;
}
27 changes: 27 additions & 0 deletions bruschetta.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// bruschetta.h

#ifndef _BRUSCHETTA_H
#define _BRUSCHETTA_H

#include <string>
#include <vector>
#include "halfmeal.h"
#include "ingredient.h"

class FoodDatabase;

class Bruschetta : public Halfmeal
{
public:
Bruschetta(const FoodDatabase& fdb, const std::vector< std::pair<std::string, size_t> >& used,const std::vector< std::pair<std::string, size_t> >& haveleft, size_t freq);
virtual void printHalfmeal() const;
virtual double getCost() const;

private:
Ingredient m_bread;
Ingredient m_topping1;
Ingredient m_topping2;
Ingredient m_topping3;
};

#endif
48 changes: 48 additions & 0 deletions burger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// burger.cpp

#include <string>
#include <vector>
#include <iostream>
#include <algorithm>
#include "halfmeal.h"
#include "burger.h"
#include "ingredient.h"
#include "fooddatabase.h"
using std::string;
using std::vector;
using std::pair;
using std::cout;
using std::endl;

Burger::Burger( const FoodDatabase& fdb, const vector< pair< string, size_t > >& used, const vector< pair< string, size_t > >& haveLeft, size_t freq) : Halfmeal( freq )
{
m_burger = getIngred( "burger filling", fdb, used, haveLeft );
m_foodNames.push_back(m_burger.getName());

m_bun = fdb.getSpecificIngred("burger bread", "hamburger bun");
m_foodNames.push_back(m_bun.getName());

m_topping1 = getIngred("burger topping", fdb, used, haveLeft);
m_foodNames.push_back(m_topping1.getName());

m_topping2 = getIngred("burger topping", fdb, used, haveLeft);
m_foodNames.push_back(m_topping2.getName());
}

void Burger::printHalfmeal() const
{
cout << "Burger: " << m_burger << ", " << m_bun;
cout << ", " << m_topping1 << ", " << m_topping2;
cout << endl;
}

double Burger::getCost() const
{
double cost = 0;
cost += m_burger.getCost();
cost += m_bun.getCost();
cost += m_topping1.getCost() + m_topping2.getCost();
return cost;
}


27 changes: 27 additions & 0 deletions burger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// burger.h

#ifndef _BURGER_H
#define _BURGER_H

#include <string>
#include <vector>
#include "halfmeal.h"
#include "ingredient.h"

class FoodDatabase;

class Burger : public Halfmeal
{
public:
Burger(const FoodDatabase& fdb, const std::vector< std::pair<std::string, size_t> >& used,const std::vector< std::pair<std::string, size_t> >& haveleft, size_t freq);
virtual void printHalfmeal() const;
virtual double getCost() const;

private:
Ingredient m_burger;
Ingredient m_bun;
Ingredient m_topping1;
Ingredient m_topping2;
};

#endif
Loading

0 comments on commit c30e169

Please sign in to comment.