Troubles averaging all the grades from a "CSV" file - python

So I am new to python and I am having a hard time figuring this code. I am trying to use "CSV File" called exam_grades.csv and then write a function that reads in all my values in the file but using the string class split() method to split this long string into a list of strings. Each string represents a grade. Then my function should return the average of all the grades.
So far this is what I have; I can open the .csv file just fine but I'm having troubles averaging all the grades. I have some commented out because I am sure where to go from what I have been doing :(
def fileSearch():
'Problem 4'
readfile = open('exam_grades.csv', "r")
for line in readfile:
l = line.split(str(","))
#num_grades = len(l)
#averageAllGrades = l * 500
#return num_grades
print(l)
fileSearch()
Any advice?
Thanks!

Most CSV files have a header at the top, you'll want to skip that but for simplicity sake, let's say we ignore that.
Here's some code that works:
def fileSearch():
'Problem 4'
readfile = open('exam_grades.csv', "r")
grade_sum = 0
grade_count = 0
for line in readfile:
l = line.split(str(","))
for grade in l:
grade_sum += int(grade)
grade_count += 1
print(grade_sum/grade_count)
fileSearch()
This assumes you have multiple lines with grades and multiple grades per line.
We're keeping track of two variables here, the sum of all grades and the number of all grades we've added to the list (we're also casting to integers, since you're going to be reading strings).
When you add all the grades up and divide by the number of grades, you get an average.
Hope this helped.

Related

How to write numbers to a text file (line by line) and add all of them?

I'm making a stock game's python version. There are stock prices and users can buy them. I need to make a thing that shows the average price of purchases made by the user when buying more than 0 stocks. Stock prices are connected to a randomizer. That's the story. But I think I can make a smaller code and then place that code into that game's code. Here's that small code:
numA=int(input("Number 1: "))
numB=int(input("Number 2: "))
with open('average.txt','a') as avg:
avg.write(str(numA))
avg.write("\n")
avg.write(str(numB))
avg.write("\n")
How can I make a code that reads the text file and sums numA and numB without doing something like total=numA+numB. I want the program to import it from the text file because as I said, I'm making a bigger program that includes loops and I will use the text file as memory.
you can try this one :
import numpy as np
with open('average.txt','r') as avg:
lines = avg.readlines()
Sum = np.sum([int(line.rstrip()) for line in lines], axis = 0)
Do you want something like this?
with open("New Text Document.txt", "r") as file:
text = file.read()
nums = text.replace("\n", " ").split(" ")
nums = (int(i) for i in nums if i.isdigit())
total = sum(nums)
I basically read the file in read mode and stored it inside of the text variable. Then I replaced all the newlines with spaces and then split the string by spaces. Then I used a generator comprehension to check if the element I is a number and if it is, I added it to the nums generator. And finally I used sum to get the sum of the numbers inside of the nums generator.
Or you could do something like this:
with open("file", "r") as file:
try:
total = sum(map(int, file))
except ValueError:
print("File has to contain only numbers.")

How to count number of replacements made in string

I am currently working on a beginner problem
(https://www.reddit.com/r/beginnerprojects/comments/1i6sax/challenge_count_and_fix_green_eggs_and_ham/).
The challenge is to read through a file, replacing lower case 'i' with 'I' and writing a new corrected file.
I am at a point where the program reads the input file, replaces the relevant lower case characters, and writes a new corrected file. However, I need to also count the number of corrections.
I have looked through the .replace() documentation and I cannot see that it is possible to find out the number of replacements made. Is it possible to count corrections using the replace method?
def capitalize_i(file):
file = file.replace('i ', 'I ')
file = file.replace('-i-', '-I-')
return file
with open("green_eggs.txt", "r") as f_open:
file_1 = f_open.read()
file_2 = open("result.txt", "w")
file_2.write(capitalize_i(file_1))
You can just use the count function:
i_count = file.count('i ')
file = file.replace('i ', 'I ')
i_count += file.count('-i-')
file = file.replace('-i-', '-I-')
i_count will have the total amount of replacements made. You can also separate them by creating new variables if you want.

Same value in list keeps getting repeated when writing to text file

I'm a total noob to Python and need some help with my code.
The code is meant to take Input.txt [http://pastebin.com/bMdjrqFE], split it into seperate Pokemon (in a list), and then split that into seperate values which I use to reformat the data and write it to Output.txt.
However, when I run the program, only the last Pokemon gets outputted, 386 times. [http://pastebin.com/wkHzvvgE]
Here's my code:
f = open("Input.txt", "r")#opens the file (input.txt)
nf = open("Output.txt", "w")#opens the file (output.txt)
pokeData = []
for line in f:
#print "%r" % line
pokeData.append(line)
num = 0
tab = """ """
newl = """NEWL
"""
slash = "/"
while num != 386:
current = pokeData
current.append(line)
print current[num]
for tab in current:
words = tab.split()
print words
for newl in words:
nf.write('%s:{num:%s,species:"%s",types:["%s","%s"],baseStats:{hp:%s,atk:%s,def:%s,spa:%s,spd:%s,spe:%s},abilities:{0:"%s"},{1:"%s"},heightm:%s,weightkg:%s,color:"Who cares",eggGroups:["%s"],["%s"]},\n' % (str(words[2]).lower(),str(words[1]),str(words[2]),str(words[3]),str(words[4]),str(words[5]),str(words[6]),str(words[7]),str(words[8]),str(words[9]),str(words[10]),str(words[12]).replace("_"," "),str(words[12]),str(words[14]),str(words[15]),str(words[16]),str(words[16])))
num = num + 1
nf.close()
f.close()
There are quite a few problems with your program starting with the file reading.
To read the lines of a file to an array you can use file.readlines().
So instead of
f = open("Input.txt", "r")#opens the file (input.txt)
pokeData = []
for line in f:
#print "%r" % line
pokeData.append(line)
You can just do this
pokeData = open("Input.txt", "r").readlines() # This will return each line within an array.
Next you are misunderstanding the uses of for and while.
A for loop in python is designed to iterate through an array or list as shown below. I don't know what you were trying to do by for newl in words, a for loop will create a new variable and then iterate through an array setting the value of this new variable. Refer below.
array = ["one", "two", "three"]
for i in array: # i is created
print (i)
The output will be:
one
two
three
So to fix alot of this code you can replace the whole while loop with something like this.
(The code below is assuming your input file has been formatted such that all the words are split by tabs)
for line in pokeData:
words = line.split (tab) # Split the line by tabs
nf.write ('your very long and complicated string')
Other helpers
The formatted string that you write to the output file looks very similar to the JSON format. There is a builtin python module called json that can convert a native python dict type to a json string. This will probably make things alot easier for you but either way works.
Hope this helps

I can't properly define a function in Python. Can anyone tell me where I am going wrong?

The directions are to:
Write a function called calc_average that takes a string representing a filename of the following format, for example:
Smith 82
Jones 75
Washington 91
The function should calculate and return the class average from the data in the file.
So far I have:
def calc_average():
infile = open("filename.txt", "r")
readlines = infile.readlines()
for line in readlines:
parts = line.split()
name = parts[0]
clsavg = parts[1]
average = 0
I have tried to work past this part, but I can't find the right way to do the average. Any suggestions? I only need the function and the file is only an example.
def calc_average():
infile = open("filename.txt", "r")
readlines = infile.readlines()
for line in readlines:
parts = line.split()
name = parts[0]
clsavg = parts[1]
average = 0
After all that, you're just literally sending something into the function, but not asking for anything to come out.
Using return will help get something out of the function.
return [variable] is a way to use it.
Here:
Add this line
return [variable] to the end of your code, such that it looks like this:
def calc_average():
infile = open("filename.txt", "r")
readlines = infile.readlines()
for line in readlines:
parts = line.split()
name = parts[0]
clsavg = parts[1]
average = 0
return variable #where you replace variable with
#the thing you want to get out of your function
To call this function (or should i say "run" it) just write the name of it, but dedented.
def calc_average():
infile = open("filename.txt", "r")
readlines = infile.readlines()
for line in readlines:
parts = line.split()
name = parts[0]
clsavg = parts[1]
average = 0
return variable
calc_average() #<- this calls the function
You might also want to read up on parameters:
parametere are values passed into a function and are used.
Example:
def test1(number):
number = number + 1 #this can be written as number += 1 as well
return number
x = test1(5)
First I define the function with a number parameter. This would mean that number will be used in this function. Notice how the lines below def test1(number) also use the variable number. whatever is passed into the function as number will be considered number in the function.
Then, I call the function and use 5 as a parameter.
When it's called, the function takes 5 (since that was the input parameter) and stores the variable number as 5.(from def test1(number)) Thus, It's like writing number = 5 in the function itself.
Afterwards, return number will take the number (which in this case is added to become 6, number = 6) and give it back to the outside code. Thus, it's like saying return 6.
Now back to the bottom few lines. x = test1(5) will make x = 6, since the function returned 6.
Hope I helped you understand functions more.
The function needs an argument. It also needs to return the average, so there should be a return statement at the end.
def calc_average(file_name):
...
return <something>
def calc_average():
infile = open("filename.txt", "r")
readlines = infile.readlines()
clsavg = 0
counter = 0
for line in readlines:
parts = line.split()
clsavg = clsavg+ float(parts[1])
counter = counter + 1
print clsavg/counter
To continue using mostly your own code and your example, you could do:
def calc_average(filename):
infile = open(filename, "r")
readlines = infile.readlines()
average = 0 # use this to sum all grades
index = 0 # keep track of how many records or lines in our txt
for line in readlines:
parts = line.split()
name = parts[0] # basically useless
# for each line in txt we sum all grades
average = average + float(parts[1]) # need to convert this string to a float
index = index + 1
# divide by the number of entries in your txt file to get the class average
return average / index
then:
calc_average('grades.txt')
prints:
82.66666666666667
Alright, let's look at this, part by part:
Write a function called calc_average
def calc_average():
that takes a string representing a filename
let's make this a meaningful variable name:
def calc_average(filename):
Now that we have the basics down, let's talk about how to actually solve your problem:
Each line in your file contains a name and a grade. You want to keep track of the grades so that you can compute the average out of them. So, you need to be able to:
read a file one line at a time
split a line and take the relevant part
compute the average of the relevant parts
So, it seems that holding the relevant parts in a list would be helpful. We would then need a function that computes the average of a list of numbers. So let's write that
def average(L):
sum = 0
for num in L:
sum += num
return sum/len(L)
Of course, there's an easier way to write this:
def average(L):
return sum(L)/len(L) # python has a built-in sum function to compute the sum of a list
Now that we have a function to compute the average, let's read the file and create a list of numbers whose average we want to compute:
def read_from_file(filename):
answer = [] # a list of all the numbers in the file
with open(filename) as infile: # open the file to read
for line in infile:
parts = line.split()
grade = int(parts[-1]) # the integer value of the last entity in that line
answer.append(grade)
return answer
Now that we have a function that returns the relevant information from a file, and a function that computes averages, we just have to use the two together:
def calc_average(filename):
numbers = read_from_file(filename)
answer = average(numbers)
return answer
Now, you might notice that you don't need to keep track of each number, as you just sum them up and divide by the number of numbers. So, this can be done more concisely as follows:
def calc_average(filename):
nums = 0
total = 0
with open(filename) as infile:
for line in infile:
total += int(line.split()[-1])
nums += 1
return total/nums
You didnt calculated the average.Also didnt return anything from the function calc_average.So try this
def calc_average():
with open('filename.txt') as text:
nums = [int(i.split()[1]) for i in text]
avg = float(sum(nums)) / float(len(nums))
return avg
>>>print(calc_average())
82.6666666667
First thing you're doing wrong is not marking the source code in your post, as source code. Put it on separate lines to the rest of your post, and use the {} link at the top of the editor to mark it as source code. Then it should come out like this:
def calc_average():
infile = open("filename.txt", "r")
readlines = infile.readlines()
for line in readlines:
parts = line.split()
name = parts[0]
clsavg = parts[1]
average = 0
You should do the same with the file contents: I am assuming that you have one name and one number per line.
If you want to put a snippet of code inline with your text, e.g. "the foo() function", put a backtick each side of the code. The backtick is like an accent grave, and is sometimes very wrongly used as an opening quote char in text files.
Next, you were to write a function that takes a string containing a filename. But you have
def calc_average():
infile = open("filename.txt", "r")
That doesn't take anything. How about
def calc_average(filename):
infile = open(filename, "r")
Now, what your function is doing is, reading the lines ok, splitting them into a name and a number -- but both are still strings, and the string containing the number is put in the variable clsavg, and then just setting the variable average to 0 every time a line is read.
But what do you want to do? I think when you say "class average", these are all people in a class, the numbers are their scores, and you want to calculate the average of the numbers? So that means adding up all the numbers, and dividing by the number of rows in the file.
So you need to set a variable to 0 ONCE, before the loop starts, then on each time you read a line, increment it by the number value. I would imagine the clsavg variable would be the one to use. So you need to convert parts[1] to an integer. You can use int() for that. Then you need to increment it, with += or with a statement like x = x + y. Ask google if you want more details. That way you build up a total value of all the numbers. Finally, after the loop is finished (meaning on a line that is only indented as far as the for), you need to divide the total by the number of rows. That would be the number of elements in readlines. You should google the len() function. Division uses the / operator. You can use x /= y to set x to the value of x/y.
That's making lots of assumptions: that you want an integer average, that every line in the file has the name and number (no blank lines or comments etc.) By the way, you can use float() instead of int() if you want more precision.

making lists from data in a file in python

I'm really new at python and needed help in making a list from data in a file. The list contains numbers on separate lines (by use of "\n" and this is something I don't want to change to CSV). The amount of numbers saved can be changed at any time because the way the data is saved to the file is as follows:
Program 1:
# creates a new file for writing
numbersFile = open('numbers.txt', 'w')
# determines how many times the loop will iterate
totalNumbers = input("How many numbers would you like to save in the file? ")
# loop to get numbers
count = 0
while count < totalNumbers:
number = input("Enter a number: ")
# writes number to file
numbersFile.write(str(number) + "\n")
count = count + 1
This is the second program that uses that data. This is the part that is messy and that I'm unsure of:
Program 2:
maxNumbers = input("How many numbers are in the file? ")
numFile = open('numbers.txt', 'r')
total = 0
count = 0
while count < maxNumbers:
total = total + numbers[count]
count = count + 1
I want to use the data gathered from program 1 to get a total in program 2. I wanted to put it in a list because the amount of numbers can vary. This is for an introduction to computer programming class, so I need a SIMPLE fix. Thank you to all who help.
Your first program is fine, although you should use raw_input() instead of input() (which also makes it unnecessary to call str() on the result).
Your second program has a small problem: You're not actually reading anything from the file. Fortunately, that's easy in Python. You can iterate over the lines in a file using
for line in numFile:
# line now contains the current line, including a trailing \n, if present
so you don't need to ask for the total of numbers in your file at all.
If you want to add the numbers, don't forget to convert the string line to an int first:
total += int(line) # shorthand for total = total + int(line)
There remains one problem (thanks #tobias_k!): The last line of the file will be empty, and int("") raises an error, so you could check that first:
for line in numFile:
if line:
total += int(line)

Categories