New user practicing lists and loops. My goal is create two list from my own input (range is 2 for quick testing, but want to get to 10). I have hit a wall on two problems:
I would like my lists to sit side by side ie.
First Name \t\t\t $77
Next Name \t\t\t $16
I don't know how to change my types so that int or float is not iterable error does not persists. I believe it'll help with my coded out max/min statements
My code:
list1 = []
list2 = []
count = 0
for i in range(2):
customers = input("Customers name? ")
list1.append(customers)
spent = float(input("Amount spent? "))
list2.append(spent)
count += spent
averageSpent = count / 2 # change this when changing range
print("Name\t\t\tAmount")
# won't print side by side. how to use zip()?
print((*list1 + list2), sep = "\n")
print("Total spending:\t\t $", count)
print("Average spending:\t $", averageSpent)
# keep getting 'object is not iterable'
#print("Most money spent:\t $", max(spent))
#print("Least money spent:\t $", min(spent))
My output is currently:
Customers name? work
Amount spent? 45
Customers name? please
Amount spent? 65
Name Amount
work
please
45.0
65.0
Total spending: $ 110.0
Average spending: $ 55.0
Thank you!
Regarding the first issue that you have, the best way for you to print the output side by side would be to iterate over the list and print each value in the list. In addition to that, you can use f-strings which is a feature that we added with python 3.6 and it allows you to do stuff like this:
x = 10
print(f'{x+20}')
>> 30
you can read more about f-strings here.
Regarding the second issue that you're facing. You got this error because you were calling the max() function on a single float. the max function should be called for a list.
I've made some adjustments. Here is what the final code looks like:
list1 , list2 = [] , []
max_range = 2
count = 0
for i in range(max_range):
customer_name = input("Customer name: ")
list1.append(customer_name)
spent = float(input("Amount Spent: "))
list2.append(spent)
count += spent
averageSpent = count / max_range
print("Name\t\t\tAmount")
for i in range(len(list1)):
print(f'{list1[i]} \t\t\t$ {list2[i]}')
print("Total spending:\t\t $", count)
print("Average spending:\t $", averageSpent)
print("Most money spent:\t $", max(list2))
print("Least money spent:\t $", min(list2))
Edit: using the zip function might be another option for printing the two outputs side by side using tuples. However, since you've already said that you're new to these topics I think that you should stay away from zip (for the time being) until you feel comfortable with lists.
Printing things side by side is answered here: Print 2 lists side by side
The error about a float or int not being iterable is because you are calling max(spent) instead of max(list2). The function max() expects a list or other iterable object.
bikemule is correct about the iterables. You need to call max with a list, not a single number. (What would max(101) return? It doesn't quite make sense.)
To make the two lists appear side-by-side, you can use zip combined with a for loop. It will turn the lists into sets of tuples that then will appear in an almost-tabular format when printed.
list_a = [1, 2, 3]
list_b = [4, 5, 6]
for col_a, col_b in zip(list_a, list_b):
print("A_Item: %s | B_Item: %d" %(col_a, col_b))
Returns:
A_Item: 1 | B_Item: 4
A_Item: 2 | B_Item: 5
A_Item: 3 | B_Item: 6
Related
My problem is that my code starts 1 day at 2 pennies, it should start at 1. I also would like to know how to print the total amount of pennies. Here is the code I have so far:
daysworked = int(input("Enter the amount of days you worked: "))
pay = 1
print("Day\tPay")
print("-----------------")
for daysworked in range (1, daysworked+1):
endpay = pay * 2
print(daysworked, "\t", endpay)
pay = endpay
If you want to print out the total amount of money the user has earned over the course of the days they worked, you can create a variable: total, which is the sum of all the payments earned per day.
Also, since on the first day, you don't want to double your value, we can simply print out the first value before the loop (skipping an iteration of your loop, hence the -1), or start our variable pay at 0.5.
To integrate this into your code, we can utilize the for loop you implemented and simply add up all the endpay values.
Other minor changes you could make: As #S3DEV mentioned, it is unnecessary to create a secondary variable to store updated payment, you can simply update the variable pay! We could also edit the for loop to just take in one parameter, the daysworked, instead of a starting and ending value. In Python, it is also recommended that if your variable names are multiple words long, separate them with an underscore.
With these changes included, your code could look something like this:
days_worked = int(input("Enter the amount of days you worked: "))
pay = 1
total = 1
print("Day\tPay")
print("-----------------")
print(1,pay)
for days_worked in range (days_worked - 1):
pay *= 2
total += pay
print(days_worked + 1, "\t", pay)
print("Total Payment:" , total)
Different Solution: (This solution will result in float answers since pay starts at .5, so you can cast to an int):
days_worked = int(input("Enter the amount of days you worked: "))
pay = .5
total = 0
print("Day\tPay")
print("-----------------")
for days_worked in range (days_worked):
pay *= 2
total += pay
print(days_worked, "\t", int(pay))
print("Total Payment:" , int(total))
I hope this helped with your problem! Let me know if you need any further clarification or details :)
I'm guessing you don't want to print in every iteration, and that's what you are asking. Just unindent that print line so it executes at the end of the loop. Also I removed superfluous variable.
daysworked = int(input("Enter the amount of days you worked: "))
pay = 1
print("Day\tPay")
print("-----------------")
for daysworked in range (1, daysworked+1):
pay = pay * 2
print(daysworked, "\t", pay)
daysworked = int(input("Enter the amount of days you worked: "))
pay = 1
endpay = 0
print("Day\tPay")
print("-----------------")
for dayworked in range (1, daysworked+1):
pay *= 2
print(dayworked, "\t", endpay)
endpay += pay
print(endpay)
Have a look at two things here.
First, you need to add one more variable to keep track of the sum, endpay in this case, which you have to print at the end. Although, in this case, endpay will always be the double of the last value of pay less two. ;) The last line could as well have been written print(2 * pay - 2) and get rid of the lines using 'endpay'.
Second the difference between daysworked and dayworked (you could have used i or any other variable name here as well).
I've got a tiny project I'm working on: I'm trying to make a "grading" program that lets you enter the number of exams, the scores for each exam, and then prints the results.
What I'm looking to do:
Enter the number of tests:
use that number with the string "Exam #: " to number each test.
I've gotten as far as sticking the input from "Enter the number of tests:" into a list..(looks like [0,1,2,3,4.. etc] now I'm trying to combine each of those list numbers with the above string and nothing I'm trying is working.. suggestions?
This is what I came up with, and its output:
test1 = int(input('How many tests are there? '))
test2 = []
for number in range(test1):
test2.append(number)
for number2 in test2:
print('Exam #:' + str(number2))
(inputting "5" here)
Exam #:0
Exam #:1
Exam #:2
Exam #:3
Exam #:4
exactly what I needed!
Try something link this
num_exams = int(input('Enter the number of exams: '))
exam_scores = [int(input(f'Enter score for exam #{n+1}: ')) for n in range(num_exams)]
print(f'Average score: {sum(exam_scores) / num_exams:0.2f}')
Seems like you'd want to collect inputs for the number of tests and then all the test scores. Then to print the test scores you could do something like
for test in range(numTests):
print('Exam #' + (test+1) + ': ' + testScores[test])
The (test+1) is so that you could have the same variable manage the test number as well as the index in the test array. For example, it could print
Exam #1: 82
Exam #2: 93
Exam #3: 87
Not sure if this is needed for your program, but you can iterate through all your values in a list with a for loop. This allows you you to access each value and perform some set of commands on that value. So in this example, we will access each value and then print it. Print can take multiple arguments. It will print out each argument with a space in between.
for examNumber in myList:
print ('Exam', examNumber)
I'm very new to Python and programming in general, so excuse me if the code is terrible and the problem rather easy to solve.
I have written code to allow a user to have employee data printed based on 3 different inputs, which they are allowed to choose from.
The options the user has available to them are to pick employees based on their payroll number; a minimum and maximum salary range; their job title.
I made two functions for the formatting. The first one turns the lines of the text file into lists, then the second function grabs those individual lists and formats them.
Then the code requests the user to input the file name. If the file cannot be found, they get to try again. If it is correct, the file is loaded and then runs through the functions to print out a neat table.
Then the user is asked what method they want to choose from to select specific employees. They are given 4 options, 3 are mentioned at the start and the fourth is to just end the program.
I managed to successfully get the first option to print out the employees without hassle, as is the same for the fourth option to end the program. I almost have the third one completed, I just need to find a way to print the name without a comma. My problem resides within the second option: how do I print the employees and their details if they fall between the minimum and maximum salary ranges entered by the user if the range isn't an integer since it has to include a '£' sign?
Here's the code. It's the biggest chunk in the program because I just have no clue how to make it work properly -
def detailsPrint(field) : #takes tuple and prints
print("{:30}" "{:6}" "{:15}" "{:7}".format(field[3] + ", " + field[4], field[0], field[2], "£" + field[1]))
if display == 2 :
maxSalary = "£1000000"
minpay = input("Enter the minimum pay : ")
maxpay = input("Enter the maximum pay : ")
if len(minpay) and len(maxpay) < maxSalary :
for s in employeeList :
if s[1] >= minpay :
detailsPrint(s)
The outcome should be something like (example) Simpson, Bart 12345 Consultant £55000 if the minpay were to be £50000 and maxpay £60000
edit: Managed to get it working. Here's the code
if display == 2 :
x = False
maxSalary = 1000000
minpay = int(input("Enter the minimum pay: "))
maxpay = int(input("Enter the maximum pay: "))
if int(minpay) > int(maxSalary) or int(maxpay) > int(maxSalary) :
x = False
print("No employees earn over £1000000. Try again.")
if int(minpay) or int(maxpay) < int(maxSalary) :
for s in employeeList :
if int(s[1]) >= minpay and int(s[1]) <= maxpay :
detailsPrint(s)
x = True
if x == False :
print("No employees could be found within that range. Try again")
print("\n")
Simplest solution: don't ask for the £ char ;-)
A solution that work with your requirement is to change the line
if len(minpay) or len(maxpay) > maxSalary :
with something like
if int(minpay[1:]) > int(maxSalary[1:]) or int(maxpay[1:]) > int(maxSalary[1:]) :
which check the numeric value of the strings (your condition seems wrong anyway to me)
You could replace all "£" signs to "" in a string.
YourString.replace("£", "")
if n == 0:
print('And your products are: ')
for i in inputs:
with open('items.txt') as f:
for line in f:
if i in line:
desc1 = line[9:17]
price1 = line[21:25]
print(str(desc1) + ' ' +str(price1) + ' ' + str(quantities))
There is no error when running the code. When run, it outputs:
Our available products are:
15372185 ChocBisc
13281038 AppJuice
26419633 TomaSoup
74283187 SprRolls
Enter the product code: 74283187
SprRolls
Price = 0.90
Available Quantity = 86
Is this what you want? (Y/N) y
How much would you like? 34
Would you like to continue? (Y/N) y
Continuing!
Enter the product code: 15372185
ChocBisc
Price = 1.20
Available Quantity = 50
Is this what you want? (Y/N) y
How much would you like? 45
Would you like to continue? (Y/N) n
System Closing!
And your products are:
SprRolls 0.90 [34, 45]
ChocBisc 1.20 [34, 45]
As you can see, right at the bottom, it prints both quantities entered. I knew it was going to do this but i dont know how to rectify it. What i need it to do is to print only the quantity entered for that product code. Any help as always would be greatly appreciated. Thank you!!
Also i removed most of the script under while n == 1 since this is my coursework, and i would rather it didn't get copied or anything like that. Hopefully this still shows the relevant section of the code to the question.
I would re-write the latter part of your code to iterate through the range of values in inputs, rather than the values themselves. Then, you can call the index of the element you want to print from quantities.
As a caveat, this works in your case because the user send inputs to inputs one at a time (so, the indices of inputs correspond with the indices of quantities). You might consider a different data structure to use within this code, like a dictionary, which could store product codes and quantities as key/value pairs. Then, you can simply refer to the key of the dictionary when printing.
Here is how I would suggest changing your code:
if n == 0:
print('And your products are: ')
for i in range(len(inputs)):
with open('items.txt') as f:
for line in f:
if inputs[i] in line:
desc1 = line[9:17]
price1 = line[21:25]
print(str(desc1) + ' ' +str(price1) + ' ' + str(quantities[i]))
You're creating a new list for the quantities so at the end where you print out this list you can append it to print out only the product code of that item. Understand? I'll post the code in a little bit if I can.
You can use enumerate. For example:
for index, i in enumerate(inputs):
print(index, i)
That should print out
0, 74283187
1, 15372185
Getting the quantities is trivial: quantities[index]
I have 2 lists ("IDS" and "Pay"). The len of IDS is 50000 and the len of Pay is 650000
The IDS is a list of IDS, like [1,2,3,4,5,6 ... ] and the PAY list is a list of lists with all payment that the IDS did, like [ [1,50], [1,100], [1,60], [2,50], [2,80], [2,50], ...]
To know how much each ID payed in total, I'm doing a for loop inside another for loop like this one:
for x in IDS:
total = 0
for i in xrange(0,len(Pay)):
if x == Pay[i][0]:
total += Pay[i][1]
print x + str(total)
But it is taking ages to process this!
I've tried to split Pay in 10 pieces, but still taking too long.
Anyone have some idea on how can I improve this operation?
Thank you!
You can use collections.Counter:
>>> from collections import Counter
>>> pay = [ [1,50], [1,100], [1,60], [2,50], [2,80], [2,50]]
>>> c = Counter()
>>> for idx, amt in pay:
c[idx] += amt
...
>>> c
Counter({1: 210, 2: 180})
OK, the fact is you have 2 very long list. Instead of discuss on what library to use, what about a better algorithm?
IDs should naturally contains unique integers (my guess), while Pay is tuples of (id, payment).
Now think about where your list is coming from. There are two possibilities:
Read from file
From some database, like MySQL
If it is option 1, you should do the following instead:
from collections import defaultdict
totals = defaultdict(someObj_factory)
[totals[int(line.split[0])].accumulate(someObj_factory(line.split()[1]))
for line in paymentFile]
First, you don't need the ids as an independent list, because you have them in Pay.
Second, it saves the reading time.
Third, for scripting language, list comprehension saves interpreting time.
Fourth, this is robust, as you can add any object you want, like date or tuples.
If it is option 2, do the counting in your database-.-
Another option is insert these into database, and do the counting there. MySQL etc. are designed for this kind of task. You will be surprise how efficient it is. More info: http://mysql-python.sourceforge.net/
If collections.Counter doesn't work for you - say if you are on a different Python version, - converting your pay list to a dictionary will have the same effect.
totals = {}
for id, amount in pay:
totals[id] = totals.setdefault(id, 0) + amount
Like the date of payment [1,50,2013-09-01] and I have to sum the
values only of dates greater than '2013-01-01'?
Then do this:
import datetime
base_date = datetime.datetime.strptime('2013-01-01', '%Y-%m-%d').date()
totals = {}
for idx, amount, pay_date in pay:
if datetime.datetime.strptime(pay_date, '%Y-%m-%d').date() > base_date:
totals[idx] = totals.setdefault(id, 0) + amount
You only need to iterate over Pay once (rather than 50000 times!). You can drastically speed up your computation by hashing:
totals = dict(map(lambda id: (id,0), IDS))
for L in Pay:
if L[0] in totals:
totals[L[0]] = totals[L[0]] + L[1]
for (id, total) in totals.iteritems():
print "id: %s, total: %d"%(id, total)