Python sorting error - python

When I try to sort my list in python I get the following error:
Traceback (most recent call last):
File "C:/Users/natep/OneDrive/Documents/I.T/Level 2/programing/Shop_list.py", line 81, in <module>
products.sort(key = lambda x:x[3], reverse=True)
Name Measurement Price Unit Price
File "C:/Users/natep/OneDrive/Documents/I.T/Level 2/programing/Shop_list.py", line 81, in <lambda>
products.sort(key = lambda x:x[3], reverse=True)
Chips Drink
IndexError: list index out of range
50 2.0
5.0 3.0
2.5 1.0
Chips Drink
50 2.0
5.0 3.0
2.5 1.0
Process finished with exit code 1
Below is the code I am using. I would like to know how I can sort my list that contains lists. Would also like to know why my data is being printed twice and how to format the printing output better so that it corresponds to the correct column. (without importing downloads)
Any help would be greatly appreciated.
unit_price = price / measurement
unit.append(unit_price)
products.append(name_sum)
products.append(mes_sum)
products.append(money_sum)
products.append(unit)
row_entry.append(products)
average = "The average product price is ${}".format(mean(money_sum))
highest = "The most expensive item is ${}".format(max(money_sum))
low = "The cheapest item is ${}".format(min(money_sum))
print()
print("Name\t\tMeasurement\t\tPrice\t\tUnit Price" )
for item in products:
print("")
for data in item:
print(data, "\t", end='')
products.sort(key = lambda x:x[3], reverse=True)
I have added all my code below:
# Shopping list
from statistics import mean
from operator import itemgetter
def limit_check(type, question, low, high):
valid = False
error = "please enter values between {} and or equal to {}".format(low,
high)
while not valid:
try:
response = type(input(question))
if low < response <= high:
valid = True
return response
else:
print(error)
except ValueError:
print(error)
products = []
mes_sum = []
money_sum = []
name_sum = []
unit = []
row_entry = []
money = float(input("please enter your budget: $"))
get_data = True
while get_data == True:
name = input("please enter product name: ")
if name.lower() == "xxx":
break
else:
name_sum.append(name)
price = limit_check(float,"How much does the item cost", 0, money)
money_sum.append(price)
measurement = limit_check(int,"Please enter unit of measurement Push 1
for kg, push 2 for g, push 3 for L, push 4 for mL",0,4)
if measurement == int("1"):
kg = limit_check(float, "Enter Kg: ", 0, 10)
mes_sum.append(kg)
elif measurement == int("2"):
grams = limit_check(int, "Enter Grams: ", 0, 999)
mes_sum.append(grams)
elif measurement == int("3"):
litres = limit_check(float, "Enter Litres: ", 0, 30)
mes_sum.append(litres)
elif measurement == int("4"):
mL = limit_check(int, "Enter mL: ", 0, 999)
mes_sum.append(mL)
unit_price = price / measurement
unit.append(unit_price)
for i in range(len(name_sum)):
products.append([name_sum[i], mes_sum[i], money_sum[i], unit[i]])
average = "The average product price is ${}".format(mean(money_sum))
highest = "The most expensive item is ${}".format(max(money_sum))
low = "The cheapest item is ${}".format(min(money_sum))
print()
print("Name\t\tMeasurement\t\tPrice\t\tUnit Price" )
for item in products:
print("")
for data in item:
print(data, "\t", end='')
products.sort(key = lambda x:x[1], reverse=True)
Currently prints like this:
Name Measurement Price Unit Price
looooool 1.0 10.0 10.0
looooool 1.0 10.0 10.0
lol 1.0 1.0 1.0
Process finished with exit code 0

Your code seems to expect that the lists in the products list each have 4 elements (for Name, Measurement, Price, and Unit Price), but in reality your data only have two elements in each list (for Chips and Drink).
Then when you try to sort products, which contains lists of length 2, you access the 4th value in the lambda function. This triggers the error: there are only two values, not 4.
It looks like you have transposed the data that you wanted to end up in products. Instead of:
products.append(name_sum)
products.append(mes_sum)
products.append(money_sum)
products.append(unit)
do:
for i in range(len(name_sum)):
products.append([name_sum[i], mes_sum[i], money_sum[i], unit[i]])
Or more compactly:
products.extend(list(map(list, zip(*[name_sum, mes_sum, money_sum, unit]))))

Related

How to get a dictionary from a file to average a users input value and then print

I have a function in my program that is supposed to allow the user to input a name and then display the average times for the name entered. This program uses csv import and to read the file and display the data. The file contains a column of names, then times for each name (marathon runner) in Boston, Chicago, and NY.
def racerAvg(times):
name = input("Please enter racers name: ")
for row in times:
if name == row['name']:
r1 = int(row['boston'])
r2 = int(row['chicago'])
r3 = int(row['NY'])
avgTime = sum(times) / len(times)
print(avgTime)
Any help with getting this to work properly would be much appreciated!
This is what I tried but I'm not sure what I need to add to get the avg times from the requested name to be calculated and printed.
def racerAvg(times):
name = input("Please enter racers name: ")
for row in times:
if name == row['name']:
r1 = int(row['boston'])
r2 = int(row['chicago'])
r3 = int(row['NY'])
avgTime = sum(times) / len(times)
print(avgTime)
A dummy times example.
Times should be in seconds but for the sake of the example let's use integers.
times = [{"name": "A", "boston": 2, "chicago": 3, "NY": 4}, {"name": "B", "boston": 5, "chicago": 6, "NY": 7}]
Updated function :
def racerAvg(times):
name = input("Please enter racers name: ")
for row in times:
if name == row['name']:
avgTime = (row["boston"] + row["chicago"] + row["NY"]) / 3
print(avgTime)
break

Change the value of a text file Python

I am doing a POS machine which save the data in a text file. After customer buy item, the total quantity of the item in the text file will minus the quantity of the customer brought, but after I trying the code can works but the stock quantity in the text file remain unchanged. So, I found some answer from this SO question Reducing quantity in text file
, it works for them but mine can't. What gone I to do for my code work.
This is the contein of my text file named razershop.txt(id, name, price, quantity):
1 , Razer Deathadder V2, 349.00 , 100
2 , Razer Viper Ultimate, 419.00 , 105
3 , Razer Basilink Ulti, 599.00 , 35
4 , Razer Viper Mini, 139.00 , 295
5 , Raazer Deathadder X, 76.90 , 592
I used all_products to open my file:
all_products = [line.strip().split(',') for line in open('razershop.txt','r').readlines()]
This is the decrement item function code:
def decrement_item(item_id, quantity):
with open('razershop.txt', 'r') as fin:
# indexes for id and quantity
index_id = 0
index_quantity = 3
# output buffer
output = []
# Add headaer to output buffer
header = fin.readline().rstrip()
output.append(header) # header without '\n' at end of line
bfound_item = False
for line in fin:
# Check each line for item_id then upadte quantity
line = line.rstrip()
if not bfound_item:
# Only process if item_id has not been found yet
# Break line into separate fields
row = line.split()
current_id = row[index_id]
if current_id == item_id:
# Found item
# Check if sufficiente quantity
current_quantity = int(row[index_quantity])
if current_quantity >= quantity:
# Decrement quantity
current_quantity -= quantity
row[index_quantity] = str(current_quantity)
line = ' '.join(row)
bfound_item = True
else:
# Insufficient quantity for update
s = f"Sorry, available quantity is only {int(row[index_quantity])}"
raise Exception(s)
# Add line to output
output.append(line) # add copy since row changes with loop
# Update inventory file
with open('razershop.txt', 'w') as fout:
for line in output:
fout.write(line + '\n')
This is my Pos machine code which generate bill and will decrease the stock after customer buy it:
while(True):
banner()
choice = int(input("Please enter your option: "))
if choice == 1:
display_all()
elif choice == 2:
display_all()
print("Press 0 for payment")
item_lst = []
price_lst = []
quantity_lst = []
total_price = 0
prod_id = 999
while prod_id != 0:
prod_id = int(input("Enter the Product ID: "))
for item in all_products:
if int(item[0]) == prod_id:
quantity = int(input("Please enter the quantity: "))
item_lst.append(item[1])
quantity_lst.append(quantity)
price_q = float(item[2]) * quantity
price_lst.append(price_q)
total_price = total_price + price_q
decrement_item(prod_id , quantity)
order_summary(item_lst , price_lst , total_price , quantity_lst)
print(" ")
conf = input("Please confirm your order(Y/N): ")
if conf == "Y":
member = input("Do you have membership(Y/N): ")
if member == "Y":
total_price = total_price * 0.9
payment = float(input("Amount received: "))
change = payment - total_price
generate_bill(item, total_price, item_lst , price_lst , quantity_lst ,change , payment)
print(" ")
print("Thanks For shopping with Us :)")
sys.exit(0)
else:
payment = float(input("Amount received: "))
change = payment - total_price
generate_bill(item, total_price, item_lst , price_lst , quantity_lst ,change , payment)
print(" ")
print("Thanks For shopping with Us :)")
sys.exit(0)
else:
print("Continue Exploring the shop")
Output:
Upper output for customer to enter the item they want
Below part of the output which generate bill
(Sorry guys the output I can't put it in image form becuase SO not allow me so they changed my image to a link)
I had tried delete the with open('razershop.txt', 'r') as fin: and header = fin.readline().rstrip() and ( row = line.split() and change all the row variable to line fromfor line in fin: # Check each line for item_id then upadte quantity line = line.rstrip()from the decrement_item function. It end up with a infinity loop and last time I forgot what I had done with the code from the decrement_ item function the whole text in the txt file gone. I just want to know what should I do to make this work?

How to find the closest number in CSV file that is the closest to a user input?

I'm still new to Python. I want to make a Car loan calculator that only runs in command prompt. The Calculator needs to take input from the users.
I managed to get the input of the users and print the list of prices in the CSV file. I need to find the closest price in the CSV file that is closest to my variable vehiclecost. Is there any code I can use to do that?
Code:
carlist = open("carlist.csv")
data = carlist.readline()
print("Vehicle cost:")
vehiclecost = float(input().strip("! .? % $"))
print("Annual interest rate:")
AnnualInterestRate = float(input().strip("! .? % $"))
print("Loan duration:")
loandur = int(input().strip("! .? % $"))
while loandur > 10:
print("Try again your loan duration is too long!")
loandur = float(input().strip("! .? % $"))
loanmonth = (loandur * 12)
carwithtax = (vehiclecost * 0.12 + vehiclecost)
InterestRate = AnnualInterestRate / (100 * 12)
monthlypayment = carwithtax * (InterestRate *
((InterestRate + 1)**loanmonth)) / ((InterestRate + 1)**loanmonth - 1)
print("Your loan amount would be: " + str(carwithtax))
print("Your monthly payment would be: {:.2f}".format(monthlypayment))
for x in range(1, loandur + 1):
for y in range(12):
monthlyinterest = (carwithtax * InterestRate)
principal = (monthlypayment - monthlyinterest)
carwithtax = float(carwithtax - principal)
print("Years:", x)
print("Bal remaining: {:.2f}".format(carwithtax))
month = x * 12
print("Total payemtns, {:.2f}".format(month * monthlypayment))
print("Car Recomendation")
for data in carlist:
price = data.split(",")
if int(price[0]) < vehiclecost:
lower = data.split(",")
print(lower)
My input file: Carlist.csv
Snippet
To find the closest value vehicle from the data set:
# get the price list from the csv
price_list = [row[0] for row in car_list]
# get the closest value vehicle
closest_value_vehicle = min(price_list, key=lambda x:abs(int(x)-vehicle_cost))
Full Code
I cleaned up the code a little and added commenting.
Tested with the supplied dataset.
import csv
with open('carlist.csv', 'r') as csv_file:
reader = csv.reader(csv_file, delimiter=',')
# skip header
next(reader, None)
# assign car list
car_list = list(reader)
while True:
try:
# vehicle cost
vehicle_cost = float(input("Please enter the vehicle cost:").strip("! .? % $"))
except ValueError:
print("Invalid input. Vehicle cost must be numeric.")
continue
else:
break
while True:
try:
# annual interest rate
annual_interest_rate = float(input("Please enter the annual interest rate:").strip("! .? % $"))
except ValueError:
print("Invalid input. Annual interest rate must be numeric.")
continue
else:
break
while True:
try:
# loan duration
loan_duration = int(input("Please enter the loan duration:").strip("! .? % $"))
except ValueError:
print("Invalid input. Loan duration must be numeric.")
continue
if loan_duration > 10:
print("Invalid input. Loan duration must be less than 10.")
continue
else:
break
# total loan months
loan_total_months = loan_duration * 12
# vehicle tax
vehicle_tax = vehicle_cost * 0.12 + vehicle_cost
# interest rate
interest_rate = annual_interest_rate / ( 100 * 12 )
# monthly repayment
monthly_repayment = vehicle_tax * ( interest_rate * ( ( interest_rate + 1 ) ** loan_total_months ) ) / ( ( interest_rate + 1 ) ** loan_total_months - 1 )
print("Your loan amount would be: $%s" % str('{:,}'.format(vehicle_tax)) )
print("Your monthly payment would be: {:.2f}".format(monthly_repayment) )
# repayments
for x in range(1, loan_duration + 1):
for y in range(12):
monthly_interest = (vehicle_tax * interest_rate)
principal = (monthly_repayment - monthly_interest)
vehicle_tax = float(vehicle_tax - principal)
print("Years:", x)
print("Balance remaining: ${:.2f}".format(vehicle_tax))
month = x * 12
print("Total payments: ${:.2f}".format(month*monthly_repayment))
# vehicles in price range
vehicles_in_price_range = []
# get the price list from the csv
price_list = [row[0] for row in car_list]
# get the closest value vehicle
closest_value_vehicle = min(price_list, key=lambda x:abs(int(x)-vehicle_cost))
print(closest_value_vehicle)
for row in car_list:
# price
price = row[0]
# check if price in range
if int(price) == int(closest_value_vehicle):
vehicles_in_price_range.append(row)
print("Vehicle Recomendations:")
# print list of vehicles in price range
for vehicle in vehicles_in_price_range:
print('%s %s %s (VIN: %s) (Millage:%s) (Location: %s, %s) - $%s' %
( vehicle[1],
vehicle[6],
vehicle[7],
vehicle[5],
vehicle[2],
vehicle[3],
vehicle[4],
str('{:,}'.format(int(vehicle[0]))) ) )

Editing a CSV file in python based on an input

I am to create a program that collects data from a csv file, in which is stored item names and stock. I would like to display to the user how much of, for example apple, is in stock.
Item # Item name Item stock Item price
12345670 Apple 20 0.70
What would you like to buy?: 12345670
How much would you like to buy?: 10
And what I'm trying to do is edit the CSV file to display the new figure of 10 since there are 20 apples and the user purchases 10. I have tried various methods but they all give me strange errors.
My expected output would be:
Item # Item name Item stock
12345670 Apple 20
What would you like to buy?: 12345670
How much would you like to buy?: 10
You have bought 10 apple(s) for a price of £7
There are 10 apples left in stock
If the user purchases too many apples:
Item # Item name Item stock
12345670 Apple 20
What would you like to buy?: 12345670
How much would you like to buy?: 30
There are not enough apple(s) in stock to buy that amount
Would you like to buy all there is?: yes
You have bought 20 apple(s) for the price of £14
This is my code
import csv
restart = 10
list1 = []
price = 0
print("Type 'end' to end")
while restart == 10:
file1 = open("CSV File TASK 2.csv", "rt")
file2 = csv.reader(file1)
print(" ")
order = input("Type the item number of your chosen number: ")
if order == 'end':
break
for row in file2:
for field in row:
if order in field:
amount = int(input("How much of that item?: "))
row3 = int(row[3])
if amount > row3:
print("There is not enough of that item in stock")
print("Please try again")
continue
row2 = float(row[2])
row1 = str(row[1])
price = amount * row2 + price
newstock = row3 - amount
print("You have bought {} {}(s) for the price of £{:.2f}".format(amount, row1, price))
print("Your subtotal is currently at {:.2f}".format(price))
receipt = ("{} {} {} {} {}".format(row[0]+" ", row[1], str(amount), "{:10.2f}".format(float(row[2])), "{:10.2f}".format(amount * float(row[2]))))
list1.append(receipt)
print('\n'.join('{}: {}'.format(*k) for k in enumerate(list1)))
Python 3.5.2. Please and thanks in advance.
You could use this:
import csv
f = open('test.csv', 'r') # Here your csv file
r = csv.reader(f)
lines = [l for l in r]
ItemX = 0
Item = input("What would you like to buy? ")
Amount = input("How much would you like to buy? ")
for x in range(len(lines)):
if lines[x][0] == Item:
ItemX = x
else:
continue1 = True # Does nothing
f.close()
fw = open('test.csv', 'w') # Here your csv file
lines[ItemX][2] = float(lines[ItemX][2]) - float(Amount)
writer = csv.writer(fw)
writer.writerows(lines)
fw.close()

I get an error - and i'm correct with my punctuations

## Loan problem
def mon_pay( prin, an_i, dur ) :
n = dur * 12
r = (an_i/100)/12
numerator = r*(1+r)**n
dinominator = (1+r)**n - 1
if an_i == 0 :
mon_pay = prin/n
else :
mon_pay = prin * (numerator/dinominator)
return mon_pay
def rem_pay( prin, an_i, dur, num_pay) :
n = (dur * 12)
r = (an_i/100)/12
numerator = ((1+r)**n - (1+r)**num_pay)
dinominator = ((1+r)**n - 1)
if an_i == 0 :
rem_pay = (prin * (1-num_pay/n))
else :
rem_pay = (prin * (numerator/dinominator))
return rem_pay
prin = float ( input ("Enter the Principal of loan: "))
an_i = float ( input ("Enter the annual interest rate: "))
dur = int (input ("Enter the duration of loan: "))
mon_pay = mon_pay(prin, an_i, dur)
print("LOAN AMOUNT:",prin,"INTEREST RATE(PERCENT):",an_i)
print("DURATION(YEARS):",dur,"MONTHLY PAYMENT:",int(mon_pay))
for yr in range (1, dur+1) :
total_pay = mon_pay*12*yr
_yr = yr*12
rem_pay = rem_pay(prin, an_i, dur, _yr)
print("YEAR:",yr,"BALANCE:",rem_pay//1,"TOTAL PAYMENT",total_pay//1)
i have given my code above, it's a simple problem to calculate loan details( i am just just studying python and this is an assignment). When i run it i get this:
Enter the Principal of loan: 1000
Enter the annual interest rate: 10
Enter the duration of loan: 5
LOAN AMOUNT: 1000.0 INTEREST RATE(PERCENT): 10.0
DURATION(YEARS): 5 MONTHLY PAYMENT: 21
YEAR: 1 BALANCE: 837.0 TOTAL PAYMENT 254.0
Traceback (most recent call last):
File "C:/Python34/Zsample9(loan_prob).py", line 35, in <module>
rem_pay = rem_pay(prin, an_i, dur, _yr)
TypeError: 'float' object is not callable
the function
rem_pay = rem_pay(prin, an_i, dur, _yr)
runs the first time, but the second time it gives the mentioned error
I can't see why, Anybody please help!
Don't use same name for variable and function.
In this case rem_pay is used both as function and float variable.
You are assigning a float result to the variable rem_pay the first time you run the function.
And it just happens so that rem_pay is the name of the function you are executing in order to get the float result.
So instead of assigning a float result to the function rem_pay,
you should consider replacing the name the variable
payment_remainder = rem_pay(prin, an_i, dur, _yr)
print("YEAR:",yr,"BALANCE:",payment_remainder //1,"TOTAL PAYMENT",total_pay//1)
Notice rem_pay has been changed to payment_remainder.

Categories

Resources