Some items not formatted right but the rest are - python

I do not know why some items are not formatted right, the short names seem to be fine but the longer ones throw themselfs off
https://pastebin.com/pkGL0Nwy
prices = {}
groceries = []
file = open("grocery_store_price_list.txt", "r")
for strx in file:
strs = list(filter(None, strx.strip().split(" ")))
prices[strs[0]] = [strs[1]], [strs[2]]
file.close()
file = open("my_personal_gro_list.txt", "r")
for strx in file :
strs = list(filter(None, strx.strip().split(" ")))
groceries.append([strs[1], strs[0]])
headings = "{:6s} {:9s} {:6s} {:7s} {:6s}".format("item", "qty", "unit", "cost", "total")
print(headings)
finalCost = 0
for strs in groceries:
item = strs[0]
qty = int(strs[1])
unit = prices[strs[0]][1]
cost = float(prices[strs[0]][0][0])
total = qty*cost
finalCost += total
print(item, qty, unit, cost, total,)

print("{item}\t{qty}\t{unit}\t{cost}\t{total}".format(item=item, qty=qty, unit=unit, cost=cost, total=total))

Related

Syntax error calculating the average of student marks while reading from a text file

f = open('studMarks.txt', 'r')
marks = 0
# Sort out names, split the words then sort which order
for line in f:
words = line.split()
fname = words[0]
lname = words[1]
print(f"{lname},{fname}")
f.close()
f = open('studMarks.txt', 'r')
sum = 0
count = 0
for line in f:
count += 1
sum += float(line.split()[2])
n = []
average = sum/count
print(f"{average}")
When using the for loop it seems to display a value of 64.3, which I believe is for the total of the whole student list and average for all marks.
I need to produce the an output which displays the student names and average on the same line. I can do for the names but I cannot do it for the average as I keep getting errors. I don't know what to input in.
Below is the full solution. The with open line is a context manager and ensures that the file will get closed as soon as you exit the block. You should get used to using this style as it's the safe way to do I/O. The rest is just bog standard Python.
marks=dict()
with open('studMarks.txt', 'r') as f:
for line in f:
words = line.split()
fname = words[0]
lname = words[1]
score = int(words[2])
key = f'{fname} {lname}'
count_key = f'{fname} {lname}_count'
latest_score = score + (marks.get(key)[0] if marks.get(key) else 0)
latest_count = 1 + (marks.get(key)[1] if marks.get(key) else 0)
marks[key] = (latest_score, latest_count )
for name, value in marks.items():
print(f'{name} : {value[0]/value[1]}')
This is an interesting problem.
From what I understand you have a text file that looks like this:
Johnny Ly 90 100 Adam Best 80 30 Tim Smith 10 20 in a file called studentMarks2.txt
and want output like this:
Johnny_Ly 95.0 Adam_Best 55.0 Tim_Smith 15.0
if that is true then it can be done using code like this without pandas or csv
though those would make this a lot easier.
fileContents = []
with open('studMarks2.txt','r') as f:
fileContents = f.read().split()
students = dict()
names = []
for content in fileContents:
if content.isnumeric():
studentKey = '_'.join(names)
currentScore = students.get(studentKey,[])
newScore = currentScore + [float(content)]
students.update({studentKey:newScore})
else:
if len(names) == 2:
names.clear()
names.append(content)
else:
names.append(content)
for student,scores in students.items():
avg = sum(scores)/len(scores)
print(student,avg,end=' ')
Broken down
This part reads the contents and splits on white space
fileContents = []
with open('studMarks2.txt','r') as f:
fileContents = f.read().split()
this part then iterates through the contents
storing the names as keys in a dictionary and putting the scores in a list
students = dict()
names = []
for content in fileContents:
if content.isnumeric():
studentKey = '_'.join(names)
currentScore = students.get(studentKey,[])
newScore = currentScore + [float(content)]
students.update({studentKey:newScore})
else:
if len(names) == 2:
names.clear()
names.append(content)
else:
names.append(content)
Lastly it iterates over the dictionary and output the avg on one line
for student,scores in students.items():
avg = sum(scores)/len(scores)
print(student,avg,end=' ')

How do I remove string '' from python dictionary list values?

The loadInventory function with a string filename as parameter reads the contents from inventory.txt
def loadInventory(filename):
inventory = {}
inventoryFile = open(filename)
for line in inventoryFile:
itemID,itemStock = line.split(":")
inventory[itemID] = itemStock
inventory = {itemID: itemStock for itemID, itemStock in inventory.items()}
inventory[itemID] = [itemStock.replace('\n', '')]
# print(f"{inventory}")
return inventory
def main():
print(loadInventory('Inventory.txt'))
main()
Inventory.txt:
C05:10,10,5,4
C01:0,20,10,5
C11:10,20,10,1
C03:0,0,10,0
C10:1,1,1,1
Output:
{'C05': ['10,10,5,4'], 'C01': ['0,20,10,5'], 'C11': ['10,20,10,1'], 'C03': ['0,0,10,0'], 'C10': ['1,1,1,1']}
Intended Output:
{'C05':[10,10,5,4], 'C01':[0,20,10,5], 'C11':[10,20,10,1],
'C03':[0,0,10,0]}
Try replacing this line:
inventory[itemID] = [itemStock.replace('\n', '')]
To:
inventory[itemID] = [int(i) for i in itemStock.replace('\n', '').split(',')]
Or:
inventory[itemID] = list(map(int, itemStock.replace('\n', '').split(',')]))

transform for in loop to while loop

i have this assignment in a basic programming course where i need to transform this code using while loop instead of for loop, but i dont know how to doit
this is my code so far
def read_txt(file_txt):
file = open(file_txt, "r")
lines = file.readlines()
file.close()
return lines
file_txt = input("file: ")
lines = read_txt(file_txt)
for l in lines:
asd = l.split(",")
length = len(asd)
score = 0
for i in range(1, length):
score += int(asd[i])
average = score / (length-1)
print(asd[0], average)
file text is like this
edward,4,3,1,2
sara,5,4,1,0
def read_txt(file_txt):
file = open(file_txt, "r")
lines = file.readlines()
file.close()
return lines
file_txt = input("file: ")
lines = read_txt(file_txt)
lines.reverse()
while lines:
l = lines.pop()
asd = l.split(",")
length = len(asd)
score = 0
i = 1
while i < length:
score += int(asd[i])
i += 1
average = score / (length-1)
print(asd[0], average)
Now in this while loop, it will iterate through lines until lines is empty. it will pop out items one by one.
For loops are more suitable for iterating over lines in files than while loops. Few improvements here are, (1) use the builtin sum instead of manually adding up scores, and (2) don't read all lines in file at once if the files are too big.
file_txt = input("file: ")
with open(file_txt) as f:
while True:
line = f.readline()
if not line:
break
name, scores = line.split(',', maxsplit=1)
scores = scores.split(',')
avg = sum(int(s) for s in scores) / len(scores)
print(f'{name} {avg}')
As you see above the check for if not line to determine if we have reached the end of file in a while loop, this is not needed in for loop as that implements the __iter__ protocol.
Python 3.8 walrus operator makes that slightly easier with::
file_txt = input("file: ")
with open(file_txt) as f:
while line := f.readline():
name, scores = line.split(',', maxsplit=1)
scores = scores.split(',')
avg = sum(int(s) for s in scores) / len(scores)
print(f'{name} {avg}')
The following gives the exact same output without using any for loop.
filename = input("file: ")
with open(filename) as f:
f = f.readlines()
n = []
while f:
v = f.pop()
if v[-1] == '\n':
n.append(v.strip('\n'))
else:
n.append(v)
d = {}
while n:
v = n.pop()
v = v.split(',')
d[v[0]] = v[1:]
d_k = list(d.keys())
d_k.sort(reverse=True)
while d_k:
v = d_k.pop()
p = d[v]
n = []
while p:
a = p.pop()
a = int(a)
n.append(a)
print(str(v), str(sum(n)/len(n)))
Output:
edward 2.5
sara 2.5

Error in code wont allow me to progress

I get an error when i run this code
cost = float(prices[strs[0]][0])
TypeError: float() argument must be a string or a number, not 'list'
i dont know how to fix the error
prices = {}
groceries = []
file = open("grocery_store_price_list.txt", "r")
for strx in file:
strs = list(filter(None, strx.strip().split(" ")))
prices[strs[0]] = [strs[1]], [strs[2]]
file.close()
file = open("my_personal_gro_list.txt", "r")
for strx in file :
strs = list(filter(None, strx.strip().split(" ")))
groceries.append([strs[1], strs[0]])
headings = "{:15s} {:3s} {:10s} {:5s} {:6s}".format("item", "qty", "unit",
"cost", "total")
print(headings)
finalCost = 0
for strs in groceries
item = strs[0]
qty = int(strs[1])
unit = prices[strs[0]][1]
cost = float(prices[strs[0]][0])
prices[strs[0]][0] is a list that contains two prices. So you'll want to cast both values separately or using cost = [float(v) for v in prices[strs[0]][0]].
prices = {}
groceries = []
file = open("grocery_store_price_list.txt", "r")
for strx in file:
strs = list(filter(None, strx.strip().split(" ")))
prices[strs[0]] = [strs[1]], [strs[2]] # List of two prices, why you get the error.
file.close()
file = open("my_personal_gro_list.txt", "r")
for strx in file :
strs = list(filter(None, strx.strip().split(" ")))
groceries.append([strs[1], strs[0]])
headings = "{:15s} {:3s} {:10s} {:5s} {:6s}".format("item", "qty", "unit",
"cost", "total")
print(headings)
finalCost = 0
for strs in groceries
item = strs[0]
qty = int(strs[1])
unit = prices[strs[0]][1]
cost = [float(v) for v in prices[strs[0]][0]]
# OR cost = [float(prices[strs[0]][0][0]), float(prices[strs[0]][0][1])]
>>> prices = {}
>>> prices['a'] = [1], [2]
>>> prices
{'a': ([1], [2])}
Taking above as an example, your prices contains a tuple and each is a list that contains 1 element
prices[strs[0]] = [strs[1]], [strs[2]]
You either apply float() on one of the values or modify your prices let each key has one value

Python: Average Prie per Year

Would anyone be able to help me with the below? I'm trying to create a program that can open the "notepad.txt" file and calculate the average price for the month of October.
notepad.txt
10-15-2012:3.886
10-22-2012:3.756
10-29-2012:3.638
infile = open('notepad.txt', 'r')
def clean_data():
line1 = infile.readline()
split1 = line1.rstrip('\n')
items = split1[0].split('-')
del items[0]
del items[0]
master = []
master = master + split1 + items
master = list(map(float, master))
print(master)
print(total)
line1 = infile.readline()
clean_data()
this prints and returns the average
def clean_data(infile):
lines = infile.readlines()
total = 0.0
num = 0
for line in lines:
spl = line.strip().split(":")
total += float(spl[len(spl)-1])
num += 1
average = total/num
print(average)
return average
def sum_data():
n,c = 0,0
with open('notepad.txt', 'r') as infile:
x = infile.readline()
# for october 10
if x[:3]=='10-' and x[6:10]=='2010';
n += float(x[12:])
c += 1
print(n/c)
If you want to use Pandas:
from io import StringIO
import pandas as pd
notepadtxt = StringIO("""10-15-2012:3.886
10-22-2012:3.756
10-29-2012:3.638""")
df = pd.read_csv(notepadtxt, sep='\:',header=None, engine='python')
df[0] = pd.to_datetime(df[0])
df=df.set_index(0)
df.resample('M').mean().values[0][0]
Output:
3.7600000000000002
The following vanilla Python code should suffice:
infile = open('notepad.txt', 'r')
def clean_data():
data = []
for line in infile:
data.append(line.strip().split(':'))
values = []
for value in data:
values.append(float(value[1]))
avg_price = sum(values)/len(values)
print(avg_price)
clean_data()
infile.close()

Categories