Python splitting function and storing values - python

I have a txt file that reads as follows:
math,89
history,90
history,94
I am trying to split each line so I can convert the the numbers to integers and use the numbers to find the average grade. I am having issues with splitting the string at the ' , ' and storing the 2 parts I split into 2 different variables.
Here is the main part of the code that i think is the issue:
def main():
total = 0
count = 0
myfile = open('grades.txt','r')
for line in myfile:
array = line.split(",")
course = array[0]
amount = float(array[1])
total += amount
myfile.close()
Sorry forgot to add the error I am getting: ValueError: I/O operation on closed file

Related

random integers reading and writing a file. Attempting to create multiple functions using a range 0,501

Im working on some python assignments for class and I cannot answer this question. I cannot find the error in my code. The error I receive is TypeError: 'function' object is not iterable. The question is:
a. Random Number File Writer Function
Write a function that writes a series of random numbers to a file called "random.txt". Each random number should be in the range of 1 through 500. The function should take an argument that tells it how many random numbers to write to the file.
b. Random Number File Reader Function
Write another function that reads the random numbers from the file "random.txt", displays the numbers, then displays the following data:
The total of the numbers
The number of random numbers read from the file
c. Main Function
Write a main function that asks the user about how many random number the user wants to generate. It them calls the function in a. with the number the user wants as an argument and generates random numbers to write to the file. Next, it calls the function in b.
Here is my code:
import random
def random_Write(num):
# Open a file for writing
file_w = open('random.txt', 'w')
for i in range(0,num):
rand = random.randrange(1,501)
file_w.write(str(rand) + '\n')
#closing file
file_w.close()
def random_Read():
# Reading from file
readFile = open('random.txt', 'r')
count = 0
total = 0
for lines in random_Read:
count +=1
total += float(lines)
print ('number count: ', str(count))
print ('The numbers add up to: ', str(total))
readFile.close()
def main():
num = int(input("How many numbers would you like to generate?: "))
random_Write(num)
random_Read()
main()
Quite simple actually, in random_Read(), in the for loop, instead of for lines in random_Read: put in for lines in readFile.readlines(): Why are you getting the error? because of a simple typo because you said random_Read which is the function...
Your function random_Read has some mistakes. Here is a corrected version:
def random_Read():
#Reading from file
readFile = open('random.txt', 'r')
count = 0
total = 0
#You were looping with random_Read. I changed to readFile.readlines()
#so you get a list with all of the lines of the file.
for lines in readFile.readlines():
count +=1
total += float(lines)
print ('number count: ', str(count))
print ('The numbers add up to: ', str(total))
#only call .close() once, at he end of the function
readFile.close()

Troubles averaging all the grades from a "CSV" file

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.

Editing a value from a file in python

I am having some trouble getting a part of my code to read a value from a text file which then can be converted to an integer and then modified by adding a user input value, then input the new value into the file. This is for a simple inventory program that keeps track of certain items.
Example:
User inputs 10 to be added to the number in the file. The number in the file is 231 so 10+231 = 241. 241 is the new number that is put in the file in place of the original number in the file. I have tried many different things and tried researching this topic, but no code I could come up with has worked. If it isn't apparent by now I am new to python. If anyone one can help it would be greatly appreciated!
the steps that you need to take are
Open the file in read mode: file = open("path/to/file", "r")
Read the file to a python string: file_str = file.read()
Convert the string to an integer: n = int(file_str)
Add 10 and convert num: num_str = str(n + 10)
Close the file: file.close()
Reopen the file in write mode: file = open("path/to/file", "w")
Write the num string to the file: file.write(num_str)
If your is
1 2 3 4 5 6
7 8 9 10 11 12
....
....
then,go searching line by line and find the line number and index of your number.
with open('data.txt') as f:
content = f.readlines()
for x in range(len(content)):
if '5' in content[x].split(' '):
lno = x
index = content[x].split(' ').index('5')
So,now you got the index.Add the user input to the number and save it into the file as you have the line number and index.

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