0

i have a question about python because i am new in this language: I have a task in which several lists (shopping lists) are to be read and finally evaluated with a price list. Unfortunately I have a problem to put this shopping list in a reasonable format so that I can calculate the purchase value for each individual person. For the exercise, the individual steps should be written in functions (reading the price list, reading the shopping lists, ...).

The shopping list (customerName.txt, there are about 50 lists as textfile) looks like this:

potato X 8
orange X 7
rice X 13
bread X 13

My function currently looks like this:

def readShopping():
    for file in glob.glob('./shoppinglists/**'):
        with open(file,'r') as customerList:
            customerList_contents = customerList.read()

For the calculation i use this pricelist, which i get out of a textfile too in a json format:

{"rice": 2.10,
"potato":4.21
"orange":3.31,
"eggs":1.92,
"cheese":8.10,
"chicken":5.22}

The question is: How can I put the shopping list in a reasonable format so that I can calculate the price of the content for each person? The Price should be calculated and return the value and customername.

ziBBer
  • 5
  • 2

2 Answers2

0
shopping_list = {
  'potato' : 8,
  # etc
}

Use a Dict object to storage it.

xiaoyu2006
  • 507
  • 7
  • 20
  • Read it like `shopping_list[name]`. (Does this answer your question?) – xiaoyu2006 Dec 29 '19 at 14:28
  • But how i can orginize that each of the 50 lists are sorted in the dictionary? How i can add each list to the specific customername? Because i need to return in the next step each list with the value and customername. – ziBBer Dec 29 '19 at 15:11
  • Use `sorted`. https://stackoverflow.com/questions/613183/how-do-i-sort-a-dictionary-by-value – xiaoyu2006 Dec 29 '19 at 15:14
0

You can pass the customerList (as string) directly to the function that calculates the prices as follows.

The routine converts the string to a list of sublist of the form (for your data):

[['potato', 'X', '8'], ['orange', 'X', '7'], ['rice', 'X', '13'], ['bread', 'X', '13']]

Function to calculate Value:

def calc_purchase_value(customerList_contents, price_list):
    " Compute purchase value "

    # convert customerList_contents to a list of list
    purchase_list = [x.split() for x in customerList_contents.split('\n') if x.strip()]

    # Iterate through the purchase_list looking up items in the price list
    # Each sublist will be of the form [item, 'X', cnt]
    return sum([price_list.get(item, 0) * int(cnt) for item, x, cnt in purchase_list])

Example of Usage

Using your customerList_contents (different strings will be read from file)

customerList_contents = """
potato X 8
orange X 7
rice X 13
bread X 13
"""

price_list = {"rice": 2.10,
"potato":4.21,
"orange":3.31,
"eggs":1.92,
"cheese":8.10,
"chicken":5.22}

print(calc_purchase_value(purchase_list, price_list))
#>> 84.15

Complete Solution

import glob
import os
import json

def readShopping():
    " Reads each customer shopping list, returning result as a geneerator "
    for file in glob.glob('./shoppinglists/*.txt'):
        with open(file,'r') as customerList:
            contents = customerList.read()
            # return file path and contents
            yield file, contents

def calc_purchase_value(customerList_contents, price_list):
    " Compute purchase value "

    # convert customerList_contents to a list of list
    purchase_list = [x.split() for x in customerList_contents.split('\n') if x.strip()]

    # Iterate through the purchase_list looking up items in the price list
    # Each sublist will be of the form [item, 'X', cnt]
    return sum([price_list.get(item, 0) * int(cnt) for item, x, cnt in purchase_list])

def get_prices():
    " Reads prices from JSON file "
    with open('./shoppinglists/pricelist.json') as json_file:
        return json.load(json_file)

# - Get prices from JSON file
price_list = get_prices()

for file, contents in readShopping():
    # file - path to customer file
    # contents - contents of customer file

    # Extract customer name from file path
    basename = os.path.basename(file)
    customer_name = os.path.splitext(basename)[0]

    # Total price: based upon shopping list and price list
    total_price = calc_purchase_value(contents, price_list)

    # Show results
    print('Customer {} total is: {:.2f}'.format(customer_name, total_price))

In the above, I have 2 text files in folder shoppinglists "Mary.txt" and "James.txt" (you will have say 50 or more).

Prices list is stored in pricelist.json

Contents of Mary.txt

orange X 3
rice X 2
potato X 3
eggs X 2

Contents of James.txt

potato X 8
orange X 7
rice X 13
bread X 13

Output

Customer james total is: 84.15
Customer mary total is: 30.60
DarrylG
  • 16,732
  • 2
  • 17
  • 23
  • This is a very good start for the calculation. I will try it. But how i can create a list/dict with all 50 lists and work in the next step with the calculation? The list must contain the name (from filename) and the items in the shoppinglist(see 1st Post) – ziBBer Dec 29 '19 at 15:47
  • @ziBBer--I'll update my answer with a more complete solution. – DarrylG Dec 29 '19 at 15:53
  • @ziBBer--added a complete solution. Hope this clarifies. – DarrylG Dec 29 '19 at 16:20
  • @ziBBer--updated answer to read pricelist from JSON file (previously it was hardcoded in a dictionary). – DarrylG Dec 29 '19 at 18:27
  • @DarryIG— Thank you very much. Your complete Solution works fine. And the pricelist as json was alteady done but thank you for your helpful work. Now i will try to find out a way how i can check the shoppinglist with the pricelist and print out the missing items. Thank you! – ziBBer Dec 29 '19 at 21:37
  • @ziBBer--do you mean: missing_items = [item[0] for item in purchase_list if not item[0] in price_list] – DarrylG Dec 29 '19 at 21:56