I am working on a small program that uses classes to generate a weekly menu of daily food logs. I am still new to python and would like some help with what I view to be the next step. I want to be able to load the program and have it check if the weekly menu class for the week already exists or create a new one if there is not a created class. Right now the program generates an empty week's worth of list when the foodManagement class is created. How do I import and export a created class so I can load it from file? Also how to i get the program to check if this file exist or create a new weekly menu? Any help in my next process or with the code would really help me. Thanks.

# Food Inventory
# A program that creates a weekly menu to help manage food inventory and meals
# 2010.02.04

import datetime
from datetime import date, timedelta

convertUnits = {"Teaspoon" : .1667, "Tablespoon" : .5, "Ounces" : 1, "Cup" : 8, "Pound" : 16, "Gallon" : 128}
mealTypes = ["Breakfast", "Lunch", "Dinner", "Snack", "Workout"]

class foodManagement(object):
    def __init__(self):
        self.todaysDate = datetime.date.today()
        self.weekDate = self.getWeekStartDate()
        self.weekMenu = weeklyMenu(self.weekDate)

    def getWeekStartDate(self):
        today = self.todaysDate
        year = int(today.strftime("%Y"))
        week = int(today.strftime("%W"))
        d = date(year, 1, 1)    
        delta_days = d.isoweekday() - 1
        delta_weeks = week
        if year == d.isocalendar()[0]:
            delta_weeks -= 1
        delta = timedelta(days=-delta_days, weeks=delta_weeks)
        return d + delta

# Class Structures

class weeklyMenu(object):
    def __init__(self, startDate):
        self.startDate = startDate
        self.menuDayLog = []
        self.getWeeklyMenu(self.startDate)

    def getWeeklyMenu(self, startDate):
        weekStart = datetime.date(startDate.year, startDate.month, startDate.day)
        for number in range(7):
            difference = datetime.timedelta(days = number)
            date = weekStart + difference
            self.menuDayLog.append(dailyMenu(date))

class dailyMenu(object):
    def __init__(self, date):
        self.date = date
        self.menuLog = []
        self.getDailyMenu()

    def getDailyMenu(self):
        for meal in mealTypes:
            self.menuLog.append(Meal(meal))

class Meal(object):
    def __init__(self, mealType):
        self.mealType = mealType
        self.mealLog = []
        self.totalCals = self.getTotalCals()
        self.totalCost = self.getTotalCost()

    def getTotalCals(self):
        total = 0
        for ingredient in self.mealLog:
            total += ingredient.servCals
        return total

    def getTotalCost(self):
        total = 0
        for ingredient in self.mealLog:
            total += ingredient.servCost
        return total

I think you're taking the problem the wrong way: you're writing classes and miscelaneous functions and you're missing the most important part. I think you should forget your classes for a moment and start thinking about Mr User of your program. I suppose that the user wants to input menus, list of meals, ingredients, prices, calories, etc in your program, all these data must be saved on disk for later use. Also Mr User wants to recall data entered in previous sessions. All this is the most important part of your program.
So, start simple (just with meal names for example, no price, calories, day of the week) and write code that allows the user to enter the data, save them, recall them later, modify them). Once this runs, gradually add features to your program.

Edited 6 Years Ago by Gribouillis: n/a

Object oriented programming has some advantages in virtually all situations, even if functional programming is sometimes easier to write.

That's why I generally tend to encourage its use over functional programming, but make no mistake that a poorly conceptually designed program will be harder to write using object oriented programming - not easier.

But I agree with Gribouillis that the most important thing to do first is to ask questions about who will be using the program, what they will be using it for, and how they will be using it. This will allow you to form a clearer design - even if its just in your mind. Thinking like a person who will be using the program is a feat that will improve your programs.

So let's start out.

Who will be using your program?
What do they want to use your program to accomplish?

Thank you guys for the response.

Who will be using your program?
Anyone that wants to log their daily food consumption into this program to track what they eat.

What do they want to use your program to accomplish?
I want the user to log food in their pantry into a list of available food. I want the user to be able to enter they daily food consumption into a daily log and it subtract food from the available food list. I also want the user to be able to look at the complete log of food for a day.

So I should start with a food inventory list and have the user be able to add food to that list and then a log amounts into a daily log. This daily log should subtract amounts from the food inventory list?

Yes, I think you should start writing something interactive. It will be much easier to extend your program once we can interact with it, basically add and remove food, print reports, etc.
I'm potentially interested into using your program :). I think it's a good idea.

Also, for simple interactivity, you could have a look at the standard module Cmd.

Edited 6 Years Ago by Gribouillis: n/a

Here is how you could start an interpreter for the food program with module cmd

from cmd import Cmd
import os, sys

class FoodCmd(Cmd):
    def __init__(self):
        Cmd.__init__(self)
        self.restart = False

    def do_quit(self, line):
        """exit the interpreter. With option -r, start a new one."""
        if line.strip() == "-r":
            self.restart = True
        return True

    def do_pid(self, line):
        print("My pid is %d" % os.getpid())

    def do_showline(self, line):
        print(repr(line))

if __name__ == "__main__":
    interpreter = FoodCmd()
    interpreter.prompt = "--food-- "
    interpreter.cmdloop("""
        ----------------------------------
        |  Welcome to the food program ! |
        ----------------------------------
""")
    if interpreter.restart:
        os.execl(sys.executable, sys.executable, __file__)

Then you can add do_* methods to add interactive commands. Here I defined 3 commands: 'pid' which displays the program's process id, 'quit' which exits the interpreter, with an option 'quit -r' which exits and restarts the program (this is useful when you're editing the program), and 'showline' which shows you how llines of input are received by the interpreter.

Thank you for posting some code for me to work from. I just started looking up the module after I saw your last post. If I want to have user input put into a simple database, should I find a way of doing that when coding methods now or should I just get the user inputting the data first?

Thank you for posting some code for me to work from. I just started looking up the module after I saw your last post. If I want to have user input put into a simple database, should I find a way of doing that when coding methods now or should I just get the user inputting the data first?

First think about a few typical command lines that you would like to enter to manipulate your data. Then add do* methods in the interpreter, so that you can enter the command lines, then write the code in the command methods and start storing your data in memory, either in class instances, and may be also in lists, dicts, etc. Then think about storing data on disk and read it back.

I forgot to mention this code snippet, which could be useful. Save it as argv.py, then you can use

from argv import buildargv

....
    def do_something(self, line):
        args = buildargv(line) # this splits the line into a list of arguments
        ....

This should help you handle user input in your interpreter.

I started to add a few methods but I get an error with my attempt to print the food list. I understand it has to do with the cmd module but I am not sure how to correct it. Also is my approach with the food class correct? I missed your small code snippet before posting this.

from cmd import Cmd
import os, sys

class FoodCmd(Cmd):
    def __init__(self):
        Cmd.__init__(self)
        self.restart = False
        self.foodInventory = []

    def do_quit(self, line):
        """exit the interpreter. With option -r, start a new one."""
        if line.strip() == "-r":
            self.restart = True
        return True

    def do_pid(self, line):
        print("My pid is %d" % os.getpid())

    def do_showline(self, line):
        print(repr(line))

    def do_showlist(self):
        for food in self.foodInventory:
            print food.name

    def do_addfood(self, foodname):
        self.foodInventory.append(Food(foodname))

class Food(object):
    def __init__(self, name):
        self.name = name
        

if __name__ == "__main__":
    interpreter = FoodCmd()
    interpreter.prompt = "--food-- "
    interpreter.cmdloop("""
        ----------------------------------
        |  Welcome to the food program ! |
        ----------------------------------
""")
    if interpreter.restart:
        os.execl(sys.executable, sys.executable, __file__)

Edited 6 Years Ago by cnuzzo: Missed a post

I started to add a few methods but I get an error with my attempt to print the food list. I understand it has to do with the cmd module but I am not sure how to correct it. Also is my approach with the food class correct? I missed your small code snippet before posting this.

def do_showlist(self):
        for food in self.foodInventory:
            print food.name

Every do_* method takes 2 arguments, self and line !

This article has been dead for over six months. Start a new discussion instead.