On 22/03/17 12:30, Rafael Knuth wrote:

> I wrote a function that does exactly what I want, and that is:
> Create a shopping list and then let the user decide which items (food)
> are supposed to be instantly consumed and which ones stored.

That's a good start, because it means you understand your requirements.

> def ManageFood():
>     create_shopping_list = []
>     prompt = ("Which foods would you like to purchase?\nEnter 'quit' to exit. 
> ")
>     food = input(prompt)
> 
>     while food != "quit":
>         create_shopping_list.append(food)
>         food = input(prompt)
> 
>     print("These are your foods on your shopping list: %s." % ", "
> .join(create_shopping_list))
>     eat_food = []
>     store_food = []
>     for food in create_shopping_list:
>         print("You bought this item: %s. " % (food))
>         prompt = input("What would you like to do with it?\nEnter
> 'eat' or 'store'. ")
>         if prompt == "eat":
>             eat_food.append(food)
>         elif prompt == "store":
>             store_food.append(food)
>     print("Food you want to eat now: %s." % ", " .join(eat_food))
>     print("Food you want to store: %s." % ", " .join(store_food))
> 
> ManageFood()
> 
> PS: Please let me know if you have any suggestions how to write my
> code above in a shorter, more elegant fashion

The first thing to say is that shorter does not mean more
elegant, often more elegant code is shorter, but sometimes
its longer. Elegance is more about structuring the code
into clearly defined pieces, avoiding redundancy and
repetition and encouraging reuse. And it should be easy
to read and understand  too!

If converting from a function to classes its very common
for the classes to have a lot more code than the original
function. But you trade that for more reusable code.
Which begs the question of whether you need classes? - are
you likely to reuse the class? If not it may not be worth
the effort. (Although it might still be worth doing if it
clarifies the code and makes it easier to maintain - will
it be maintained? Or is it throw-away code?)

But let's assume this is just a training exercise and you
want to convert to OOP just for the experience.

> ... not sure if a pro would write it same way I did).

The answer is no, for several reasons, but probably not
the ones you expect!

> Besides that, I want to take it a step further and rewrite the
> function above as a class, and I don't know how exactly how to do
> this.

OK, I'll discuss one approach to this below, but there
are many OOP "methodologies", this is just one that I
personally find works for small/medium projects.


> (coding newbie pains ... I just learned the basics about classes in
> Python, but nowhere could I find examples of how to properly
> initialize classes, given that it operates solely with user input -
> same goes with with calling that class properly). 

There is a very important programming principle (not just
for classes) that says you should separate out the data
processing from the user interaction. So your initial design
concept is flawed - the first reason a pro would not write
your code the way you did.

So maybe you need a separate class (or just a function) to
represent the UI? That class can then interact5 with your
data models.

And talking about your data models...

Classes represent objects, things. Things that can do stuff.
So you should not normally have classes that *manage* other
things, the things should manage themselves. The exception
is when you have a container like your shopping list. The
list is a single thing (a class) that should manage itself.
It should control what goes in and out of the list but it
should not be manipulating its contents, it should be
providing access to its contents for the user of the list
to manipulate.

So it looks like we have maybe 3 kinds of object here.
1) The UI - could just be a function
2) The list - almost certainly a class
3) the items in the list - probably a class but we need
   to know more

To decide what these classes look like its often useful to
imagine that they already exist and think about how you
want to use them. (The formal way to do this is to
create a CRC card - Google it if interested)

Lets assume the UI is a function and that it is using
the other 2 classes.

The structure of our code is roughly:

# create and populate a FoodList
lst = FoodList()
while True:
    item = input('What is the item? (quit to exit) ')
    if item == 'quit': break
    food = Food(item)
    lst.add(food)

print(lst.contents())

# Separate thev list into eats and stores
eats = FoodList()
store = FoodList()
for food in lst.contents():
    action = input('What action do you want for %s?' % food.name)
    if action == 'eat':
       eats.add(food)
    if action == 'store':
       store.add(food)

print('Items to eat now: %s' % eats.contents())
print('Items to store: %s' % store.contents())


Looking at that code we see that we have 3 lists of food.
We also see that a FoodList should be able to add items
and return its contents.

We also see that the Food objects don't do much except
store their name, so probably we can just use strings
and not bother with a class. So the final program consists
of a GUI function (that looks a lot like the pseudo
code above) and a single class:

class FoodList:
   def __init__(self):
      self.data = []
   def add(self, item):
      self.data.append(item)
   def contents():
      return self.data[:]  # return a copy

Of course that's not doing anything that a normal
list couldn't do, so we don't really need a class
at all in this case, but hopefully, as a learning
exercise, it shows the kind of thought process you
might use.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to