简体   繁体   中英

How do I sum given data in written file in python

My code runs almost correctly. The program needs to take in a country name, software/hardware/accessory sales, and then give the average for each category per country, total sales for each category, and overall total sales. If the users opt to enter a second, third, etc country, the averages and total must all be added together to find each calculation. My code currently calculates all of those things, but it does it for each country separately and it doesn't correctly count the number of countries added. I don't know why or how to fix it, please help!

def request_countryname():
    country_name = input('Please enter the country\'s name: ')
    while len(country_name) < 2:
        print('Name must be at least two chracters')
        country_name = input('Please enter the country\'s name: ')
    return country_name    


def request_sales(product_type, country_name):
    sales = float(input('Please enter the total sales for ' + product_type + ' in ' + country_name + ": "))
    while sales == type(str) or sales < 0:
        print('Sales must be a non-negative numeric input')
        sales = float(input('Please enter the total sales for', product_type, 'in', country_name))
    return sales
   

def request_data(sales_data):
    sales_data = open('sales_data.txt', 'w')
    records = 0
    add_country = True
    while True:
        records += 1
        country_name = request_countryname()
        soft_sales = request_sales('software', country_name)
        hard_sales = request_sales('hardware', country_name)
        acc_sales = request_sales('accessories', country_name)
    
        sales_data.write(f'{country_name}\n{soft_sales}\n{hard_sales}\n{acc_sales}\n')
        add_country = input('Do you want to add another country? (Enter y/Y for Yes, any other key to stop): ')
        if add_country == 'y' or add_country == 'Y':
            records += 1
            request_data("sales_data.txt")
            analyze_data("sales_data.txt")
        else:
            print(records, 'record(s) successfully added to the file.')
            print('----------------------------------------------\n')
            sales_data.close()
        return sales_data
        
    
def analyze_data(sales_data):
    sales_data = open ('sales_data.txt', 'r')
    software_sales = []
    hardware_sales = []
    accessory_sales = []
    
    read_file = sales_data.readline()
    
    
    while read_file != '':
        soft_sales = sales_data.readline()
        hard_sales = sales_data.readline()
        acc_sales = sales_data.readline()
        
        software_sales.append(float(soft_sales))
        hardware_sales.append(float(hard_sales))
        accessory_sales.append(float(acc_sales))
        read_file = sales_data.readline().rstrip('\n')
        
    soft_average= sum(software_sales)/len(software_sales)
    hard_average = sum(hardware_sales)/len(hardware_sales)
    acc_average = sum(accessory_sales)/len(accessory_sales)
    total_soft = sum(software_sales)
    total_hard = sum(hardware_sales)
    total_acc = sum(accessory_sales)
    
    total_sales = float(total_soft + total_hard + total_acc)
    print('Average software sales per country: $' + format(soft_average, ',.2f'))
    print('Average hardware sales per country: $' + format(hard_average, ',.2f'))
    print('Average accessory sales per country: $' + format(acc_average, ',.2f'))
    print('')
    print('Total software sales: $' + format(soft_average, ',.2f'))
    print('Total hardware sales: $' + format(hard_average, ',.2f'))
    print('Total accessory sales: $' + format(acc_average, ',.2f'))
    print('')
    print('Total sales: $' + format(total_sales, ',.2f'))
    
    sales_data.close

def main():
    request_data("sales_data.txt")
    analyze_data("sales_data.txt")
    
main()   

Edit: my professor said the problem was in the request_data function, specifically the "while True" part because I need to specify what is true, I just don't know what.

I'm going to try to answer your question, but also give you some refactoring pointers that may be helpful:

def request_country_name():
    country_name = ""
    while len(country_name) < 2:
        print('Name must be at least two characters')
        country_name = input('Please enter the country\'s name: ')
    return country_name    


def request_sales(product_type, country_name):
    sales = ""
    while sales == type(str) or sales < 0:
        print('Sales must be a non-negative numeric input')
        try:
            sales = float(input(f"Please enter the total sales for {product_type} in {country_name}: "))
        except:
            pass
    return sales

def read_record(record):
    header = {'country_name': str,'soft_sales': float,'hard_sales': float,'acc_sales': float}
    str_dict = dict(zip(list(header.keys()), record.replace("\n", "").split(",")))
    return {k:header[k](v) for k,v in str_dict.items()}


def request_data(sales_data_file="sales_data.csv"):
    records = 0
    add_country = True
    while True:
        records += 1
        country_name = request_country_name()
        soft_sales = request_sales('software', country_name)
        hard_sales = request_sales('hardware', country_name)
        acc_sales = request_sales('accessories', country_name)

        with open(sales_data_file, 'w') as writer:
            writer.write(f'{country_name},{soft_sales},{hard_sales},{acc_sales}\n')
        add_country = input('Do you want to add another country? (Enter y/n): ').upper()
        if add_country == 'Y':
            analyze_data(sales_data_file)
        else:
            print(F"{records} record(s) successfully added to the file.\n----------------------------------------------\n")
            break
        
    
def analyze_data(sales_data_file="sales_data.csv"):

    latest_country_records = {}
    with open(sales_data_file) as reader:
        for line in reader.readlines():
            data = read_record(line)
            latest_country_records[data['country']] = data
    
    total_soft = sum([v['soft_sales'] for v in latest_country_records.values()])
    soft_average= total_soft/len(latest_country_records)

   total_hard = sum([v['hard_sales'] for v in latest_country_records.values()])
    hard_average = total_hard/len(latest_country_records)

   total_acc = sum([v['acc_sales'] for v in latest_country_records.values()])
    acc_average = total_acc/len(latest_country_records)
    
    total_sales = total_soft + total_hard + total_acc
    print('Average software sales per country: $' + format(soft_average, ',.2f'))
    print('Average hardware sales per country: $' + format(hard_average, ',.2f'))
    print('Average accessory sales per country: $' + format(acc_average, ',.2f'))
    print('')
    print('Total software sales: $' + format(total_soft, ',.2f'))
    print('Total hardware sales: $' + format(total_hard, ',.2f'))
    print('Total accessory sales: $' + format(total_acc, ',.2f'))
    print('')
    print('Total sales: $' + format(total_sales, ',.2f'))


def main():
    request_data("sales_data.txt")
    analyze_data("sales_data.txt")
    
if __name__ == "__main__":
    main() 

Alright, so after some refactoring -- I think your biggest issue was you weren't handling the file handlers well (I replaced with context managers) which led to some odd structuring -- ie. your "request_data" function was being called recursively (by itself) in an unnecessary way.

Some other things to note, in your final print out you were printing the avg in place of the totals -- also you avg & total calculations overlapped a bit (reuse the total and calc it first).

Last note, and one worth keeping front of mind -- 9 times out of 10 there's an existing, established data structure -- lean on those. In this case, csv is your friend, in others json will be helpful.

Storing the data in different rows leads to unneeded complexity, and if possible should be avoided.

FWIW -- I haven't run/tested this code so there may be a few errors

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM