transform for in loop to while loop - python

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

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 to calculate moving average for temperature?

This is the output I need:
Temperature anomaly filename:SacramentoTemps.csv
Enter window size:60
1940,-0.2331
1941,-0.2169
1942,-0.2150
1943,-0.2228
1944,-0.2107
1945,-0.1796
1946,-0.1667
1947,-0.1582
1948,-0.1585
1949,-0.1492
1950,-0.1711
1951,-0.1688
1952,-0.1490
1953,-0.1556
1954,-0.1548
1955,-0.1580
1956,-0.1420
1957,-0.1101
1958,-0.1017
This is my code:
filename = input("Temperature anomaly filename:")
infile = open(filename, "r")
k = int(input("Enter window size:"))
infile.readline()
temp_list = []
for line in infile:
line = line.strip()
year,temp = line.split(",")
temp = float(temp)
temp_list.append(temp)
index = k
for index in range(index,len(temp_list)-1-index):
year = 1880 + index
ave = sum(temp_list[index:index+k]) / (2*index+1)
print(str(year)+","+"{:.4f}".format(ave))
infile.close()
My code currently prints out up until the year 1957 and it prints out the wrong averages for each year. What do I need to fix?
filename = "SacramentoTemps.csv"
infile = open(filename, "r")
k = int(input("Enter window size:"))
temp_list = []
for line in infile:
line = line.strip()
year, temp = line.split(",")
temp = float(temp)
temp_list.append(temp)
infile.close()
moving_average = []
for i, temp in enumerate(temp_list):
average = temp
if len(temp_list) - i < k:
break
for j in range(k):
average += temp_list[i+j]
moving_average.append(average/k)
print(str(year) + "," + "{:.4f}".format(average))
I coded in the direction of modifying your code as little as possible.
One thing to note is your file need to be longer than window size.
Using pandas would be most sane way to go:
import pandas as pd
filename = "SacramentoTemps.csv"
window = 2
data = pd.read_csv(filename)
data.temperature.rolling(window = window).mean().fillna(data.temperature)

Am trying to get the average of a list from a text file

This the link to see the image of the text file I need help with feature one, click here to see the imageFor some reason when I print out the average of the list, it only shows the number from the text file. I don't know where my mistake is. I think the issue might be when am appending the list.
f = open("votes.txt")
lines = f.read().split('\n')
issueA = {}
voteAa = {}
voteBa = {}
while(True):
for line in lines:
col = line.split(' ')
issue = col[0]
voteA = float(col[1])
voteB = float(col[2])
if voteA in voteAa:
voteAa[issue].append(voteA)
else:
voteAa[issue] = [voteA]
if voteB in voteBa:
voteBa[issue].append(voteB)
else:
voteBa[issue] = [voteB]
choice = int(input("Which choice? "))
if choice == 1:
for issue in voteAa:
sumVote = sum(voteAa[issue])
avg = sumVote / len(voteAa[issue])
print("avg is ",sumVote)
how about this
f = open("votes.txt")
lines = f.read().split('\n')
issues = []
voteAa = []
voteBa = []
for line in lines:
col = line.split(' ')
issue = col[0]
voteA = float(col[1])
voteB = float(col[2])
issues.append(issue)
voteAa.append(voteA)
voteBa.append(voteB)
avgA = voteAa.count(0)/len(issues) * 1.0
avgB = voteBa.count(0)/len(issues) * 1.0
if (avgA > avgB):
print('B higher than A'
elif (avgB > avbA):
print('A higher than B')
Since you need average by issue
remove for issue loop
and compute average in one line with special mean function like below
avg = mean(voteAa.values())
or, if you prefer keep it close to your code
sumVote = sum(voteAa.values())
avg = sumVote / len(voteAa)
also correct print line to
print("avg is ", avg)
Also you should just collect votes not need for if in the first loop.
So resulting script is
f = open("votes.txt")
lines = f.read().split('\n')
issueA = {}
voteAa = {}
voteBa = {}
for line in lines:
col = line.split()
issue = col[0]
voteA = float(col[1])
voteB = float(col[2])
voteAa[issue] = voteA
sumVote = sum(voteAa.values())
avg = sumVote / len(voteAa)
print("avg is ", avg)
I tried to keep close to your original code, and did not say replace dictionaries with arrays, it could be simplified even further if you like, say with pandas or even standard https://docs.python.org/3/library/csv.html

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()

Python programming error re: reading from files

I'm taking an online class and we were assigned the following task:
"Write a program that prompts for a file name, then opens that file and reads through the file, looking for lines of the form:
X-DSPAM-Confidence: 0.8475
Count these lines and extract the floating point values from each of the lines and compute the average of those values and produce an output as shown below.
You can download the sample data at http://www.pythonlearn.com/code/mbox-short.txt when you are testing below enter mbox-short.txt as the file name."
The desired output is: "Average spam confidence: 0.750718518519"
Here is the code I've written:
fname = raw_input("Enter file name: ")
fh = open(fname)
inp = fh.read()
for line in inp:
if not line.strip().startswith("X-DSPAM-Confidence: 0.8475") : continue
pos = line.find(':')
num = float(line[pos+1:])
total = float(num)
count = float(total + 1)
print 'Average spam confidence: ', float( total / count )
The output I get is: "Average spam confidence: nan"
What am I missing?
values = []
#fname = raw_input("Enter file name: ")
fname = "mbox-short.txt"
with open(fname, 'r') as fh:
for line in fh.read().split('\n'): #creating a list of lines
if line.startswith('X-DSPAM-Confidence:'):
values.append(line.replace('X-DSPAM-Confidence: ', '')) # I don't know whats after the float value
values = [float(i) for i in values] # need to convert the string to floats
print 'Average spam confidence: %f' % float( sum(values) / len(values))
I just tested this against the sample data it works just fine
#try the code below, it is working.
fname = raw_input("Enter file name: ")
count=0
value = 0
sum=0
fh = open(fname)
for line in fh:
if not line.startswith("X-DSPAM-Confidence:") : continue
pos = line.find(':')
num = float(line[pos+1:])
sum=sum+num
count = count+1
print "Average spam confidence:", sum/count
My guess from the question is that the actual 0.8475 is actually just an example, and you should be finding all the X-DSPAM-Confidence: lines and reading those numbers.
Also, the indenting on the code you added has all the calcuations outside the for loop, I'm hoping that is just a formatting error for the upload, otherwise that would also be a problem.
As a matter if simplification you can also skip the
inp = fh.read()
line and just do
for line in fh:
Another thing to look at is that total will always only be the last number you read.
# Use the file name mbox-short.txt as the file name
fname = raw_input("Enter file name: ")
fh = open(fname)
count = 0
total = 0
for line in fh:
if not line.startswith("X-DSPAM-Confidence:") : continue
count = count + 1
# print count
num = float(line[20:])
total +=num
# print total
average = total/count
print "Average spam confidence:", average
The way you're checking if it is the correct field is too specific. You need to look for the field title without a value (see code below). Also your counting and totaling needs to happen within the loop. Here is a simpler solution that makes use of python's built in functions. Using a list like this takes a little bit more space but makes the code easier to read in my opinion.
How about this? :D
with open(raw_input("Enter file name: ")) as f:
values = [float(line.split(":")[1]) for line in f.readlines() if line.strip().startswith("X-DSPAM-Confidence")]
print 'Average spam confidence: %f' % (sum(values)/len(values))
My output:
Average spam confidence: 0.750719
If you need more precision on that float: Convert floating point number to certain precision, then copy to String
Edit: Since you're new to python that may be a little too pythonic :P Here is the same code expanded out a little bit:
fname = raw_input("Enter file name: ")
values = []
with open(fname) as f:
for line in f.readlines():
if line.strip().startswith("X-DSPAM-Confidence"):
values.append(float(line.split(":")[1]))
print 'Average spam confidence: %f' % (sum(values)/len(values))
fname = raw_input("Enter file name: ")
fh = open(fname)
x_count = 0
total_count = 0
for line in fh:
if not line.startswith("X-DSPAM-Confidence:") : continue
line = line.strip()
x_count = x_count + 1
num = float(line[21:])
total_count = num + total_count
aver = total_count / x_count
print "average spam confidence:", aver
user_data = raw_input("Enter the file name: ")
lines_list = [line.strip("\n") for line in open(user_data, 'r')]
def find_spam_confidence(data):
confidence_sum = 0
confidence_count = 0
for line in lines_list:
if line.find("X-DSPAM-Confidence") == -1:
pass
else:
confidence_index = line.find(" ") + 1
confidence = float(line[confidence_index:])
confidence_sum += confidence
confidence_count += 1
print "Average spam confidence:", str(confidence_sum / confidence_count)
find_spam_confidence(lines_list)
fname = raw_input("Enter file name: ")
fh = open(fname)
c = 0
t = 0
for line in fh:
if line.startswith("X-DSPAM-Confidence:") :
c = c + 1
p = line.find(':')
n = float(line[p+1:])
t = t + n
print "Average spam confidence:", t/c
fname = input("Enter file name: ")
fh = open(fname)
count = 0
add = 0
for line in fh:
if line.startswith("X-DSPAM-Confidence:"):
count = count+1
pos = float(line[20:])
add = add+pos
print("Average spam confidence:", sum/count)
fname = input('Enter the file name : ') # file name is mbox-short.txt
try:
fopen = open(fname,'r') # open the file to read through it
except:
print('Wrong file name') #if user input wrong file name display 'Wrong file name'
quit()
count = 0 # variable for number of 'X-DSPAM-Confidence:' lines
total = 0 # variable for the sum of the floating numbers
for line in fopen: # start the loop to go through file line by line
if line.startswith('X-DSPAM-Confidence:'): # check whether a line starts with 'X-DSPAM-Confidence:'
count = count + 1 # counting total no of lines starts with 'X-DSPAM-Confidence:'
strip = line.strip() # remove whitespace between selected lines
nline = strip.find(':') #find out where is ':' in selected line
wstring = strip[nline+2:] # extract the string decimal value
fstring = float(wstring) # convert decimal value to float
total = total + fstring # add the whole float values and put sum in to variable named 'total'
print('Average spam confidence:',total/count) # printout the average value
total = float(num)
You forgot here to sum the num floats.
It should have been
total = total+num
fname = input("Enter file name: ")
fh = open(fname)
count=0
avg=0
cal=0
for line in fh:
if not line.startswith("X-DSPAM-Confidence:") :
continue
else:
count=count+1
pos = line.find(':')
num=float(line[pos+1:])
cal=float(cal+num)
#print cal,count
avg=float(cal/count)
print ("Average spam confidence:",avg)
IT WORKS JUST FINE !!!
Use the file name mbox-short.txt as the file name
fname = raw_input("Enter file name: ")
if len(fname) == 0:
fname = 'mbox-short.txt'
fh = open(fname)
count = 0
tot = 0
ans = 0
for line in fh:
if not line.startswith("X-DSPAM-Confidence:") : continue
count = count + 1
num = float(line[21:])
tot = num + tot
ans = tot / count
print("Average spam confidence:", ans)
# Use the file name mbox-short.txt as the file name
fname = raw_input("Enter file name: ")
fh = open(fname,'r')
count=0
avg=0.0
cal=0.00
for line in fh:
if not line.startswith("X-DSPAM-Confidence:") :
continue
else:
count=count+1
pos = line.find(':')
num=float(line[pos+1:])
cal=cal+num
#print cal,count
avg=float(cal/count)
print "Average spam confidence:",avg
fname = raw_input("Enter file name: ")
fh = open(fname)
inp = fh.read()
i = 0
total = 0
count = 0
for line in inp:
if not line.strip().startswith("X-DSPAM-Confidence: 0.8475"):
continue
pos = line.find(':')
num = float(line[pos+1:])
total += num
count += 1
print 'Average spam confidence: ', float( total / count )

Categories