Struggling to get a simple function running from command line - python

I'm trying to get the below function running from the command line by simply using
python filename.py
However, it isn't doing what I want.
Could someone please help me out with this? I'm sure I'm missing something very simple...
inFile = ""
inFile = raw_input("Enter the File Name: ")
x = open(inFile, 'w')
def summation(x):
sum = 0
for i in x:
sum = sum + i
return sum
if __name__ == "__main__":
print(summation(x))
Hopefully it's fairly self explanatory what I'm trying to achieve, but in case it's not...
I'm asking for a raw_input; this will be a text file full of numbers (each on it's own line). The file should be fed into the variable x which is then used in the summation function. Finally, with a for loop each value is summed and the sum is returned (and printed in terminal).

There are two problems:
You're opening the file in write mode. This deletes all the contents of the file. Drop the "w" parameter.
You can't add strings (as read from the file) to an integer. You need to convert them to integers first: sum += int(i)
Also, you should close the file after you've read its contents. And the line infile = "" is unnecessary.

A more pythonic version...
def line_to_int(line):
line = line.strip()
if not line:
# handles the case of empty lines
return 0
return int(line)
def sumfile(f):
return sum(line_to_int(line) for line in f)
if __name__ == "__main__":
fname = raw_input("Enter the File Name: ").strip()
with open(fname) as f:
print(sumfile(f))
or even more simple as long as you don't plan on adding error handling around the call to int(line) (thanks Jon Clements):
if __name__ == "__main__":
fname = raw_input("Enter the File Name: ").strip()
with open(fname) as f:
print(sum(int(line.strip() or 0) for line in f))

Related

Why does python delete every line except the first one?

I have a text file with some data in it, and i've written a code that is supposed to delete a specific line when te if statement is true. Why does python delete every line except the first one? And how do i fix it?
def give_back():
number_input = input('What is ur number?')
code_input = input('Enter the code corresponding to your number.')
b = [f'{number_input};{code_input}']
with open('fa_kluizen.txt', 'r') as f:
x = f.readlines()
with open('fa_kluizen.txt', 'w') as f:
for line in x:
if line.strip('\n').strip() != b:
f.write(line)
return True
else:
return False
You have two basic issues. The first is the way you handle your loop:
def give_back():
...
return True # leaves the function `give_back`
Even though you have a for line in x between these two statements, it will only ever run the first loop because you use the keyword return. This leaves the function. If you expect more work to be done, you need to avoid doing this.
Secondly, you are using the read-write flags awkwardly. When you open a file with open('somefile.txt', 'w') it opens for writing, truncating (deleting the contents of) the file first. If you plan to write every line back, that is fine, but since your loop only occurs once, the first line will be all that is in the file when you're done.
You don't say what you want the actual end result to look like with a given input, so it's impossible to say what the correct way to fix this is, but I'd start by getting rid of your return statements and see whether that matches what you're looking for.
You probably meant something like this:
def give_back():
number_input = input('What is ur number?')
code_input = input('Enter the code corresponding to your number.')
b = [f'{number_input};{code_input}']
with open('fa_kluizen.txt', 'r') as f:
x = f.readlines()
with open('fa_kluizen.txt', 'w') as f:
for line in x:
if line.strip('\n').strip() != b:
f.write(line)
The problem is that if u return the function exits

How to Read Numeric Data From Text file and save it to a variable using python

I am working on a project that gets data from a text file and that value needs to be stored in a variable. but the following code does not work properly. sometimes it works while other times it returns
ValueError: invalid literal for int() with base 10: ''
the following is the code used:
def main():
# Txt read
global id
input = open('data.txt', 'r')
lines = input.readlines()
i = 0
for line in lines:
i += 1
id = int(line)
main()
print id
Data would be in single int followed by new line in text file.
Any Help would be appreciated.
Few things first
Don't use input as a variable, since it's a built-in function in python. It is not considered a good practice.
Also, id also happens to be a built-in function, so avoid that as well
Also, I would suggest to read the whole file as string and the split based on \n. This will help you to strip the extra newlines at end (and start if you wish)
You can use something like this:
def main():
# Txt read
input1 = open('text.txt', 'r').read().strip()
l = input1.split("\n")
#convert to int
ll = [int(s) for s in l]
print(ll)
main()
In your code you will get only last value in file for getting all values use list and store them in list and there is no need of i and increment of i if want to calculate total number of values use len(id)
Try Below code
def main():
# Txt read
global id
id=[]
input = open('data.txt', 'r')
lines = input.readlines()
for line in lines:
if line.strip(): #Checking Non-Empty Line
id.append(int(line.strip()))
main()
print id
print "Total Valuse: "+str(len(id))
The newline character "\n" is casing the error.
def main():
# Txt read
global id
data = open('data.txt', 'r').read()
data = data+'0'
data = data.replace('\n','+0+')
id = eval(data)
main()
print(id)

How to print a specific line from a file

I am trying to print a specific line from the file "Scores", which is option B. This is my code:
print("Option A: Show all scores\nOption B: Show a record\nOption Q: Quit")
decision = input("Enter A, B, C or Q: ")
myFile = open("Scores.txt", "rt")
if decision == "A":
record = myFile.read()
print(record)
myFile.close()
elif decision == "B" or decision == "b":
playerName = input("Enter a player name to view their scores: ")
record = myFile.read()
answer = record.find(playerName)
for line in answer:
print(line)
elif decision == "Q" or decision == "q":
exit
I went for Option B, then I entered a player name that holds the score of the player, but it throws this error message:
line 12, in <module>
for line in answer():
TypeError: 'int' object is not callable
A few cents from my side :
file = open("file")
lines = file.readlines()
for line in lines:
if playername in line:
print line
file.close()
Hope it works!
find() method returns a positive index if it succeeds, -1 otherwise
You should loop on your content line by line, as follows:
for line in myFile:
if line.find(playerName):
print(line)
A safer way to read the file and find data, so that you will not have OutOfMemory issues when storing the whole file in memory.
playerName = input("Enter a player name to view their scores: ")
with open("Scores.txt", 'r') as f:
for row in f:
if playerName in row:
print row
This way you will be using with that will close the file by itself either when the program ends or Garbage Collection kicks in. This way python will read the file line by line and store only 1 line in memory. So you can use huge files and do not worry about memory issues.
Hope it helps :)
Working with str methods will take more acrobatics. Try the following,
import re
p = re.compile(r"\b{}\b".format(playername)) # keep it ready
# inside option B
for line in myfile: # no need to `.read()` it
match = p.search(line)
if match:
print(line)
break # if there is only one record for playername
See if it works for you.
similar thing here:
Reading specific lines only (Python)
fp = open("file")
for i, line in enumerate(fp):
if line == playername:
print line
fp.close()
I also notice you don't close your file for each decision, should make that happen.
Few python idioms and small optimization
Here are many answer, my sample brings in few python idioms and optimize it a bit:
fname = "Scores.txt"
player_name = "Quido"
with open(fname) as f:
for line in f:
if player_name in line:
print line
break
print "Going on doing following tasks."
The with block will close the open file on exiting the inner block. No need to f.close(), safe
in case of problems to read the file.
for line in f: shows, that iterating over file open in text mode we get one line per iteration.
break after we print the line with the player will effectively stop iterating over lines assuming,
there is only one such line or that we are happy with the very first one. If this is not the case,
removing the break allows printing all lines containing the player name.
As lines returned from text file iterator contain new line, you may prefer to get rid of them. Use
print line.strip() in such case what will remove all blank characters from start and end of the line.
Final print is proving, the program continues after it processes all the lines.
It may happen, that you get no output for name, which appears to be present in the file. In such a
case, you might need to clarify letter case. For example, if your text file contains all the names
in exact casing, you have to enter the name properly.
Other option is to lower-case the player_name and compare it against lower cased line:
fname = "Scores.txt"
player_name = "Quido"
normalized_player_name = player_name.lower()
with open(fname) as f:
for line in f:
if normalized_player_name in line.lower():
print line.strip()
break # comment out to print all lines with the player
print "Going on doing following tasks."
Note, that we normalize the player_name outside from the loop to be a bit faster. Lower-casing inside the
loop would work, but would do the same task repeatedly.
The line is printed using exact letter cases as in the file.

Python compare bombs if files not sorted

I have written some code to compare two files via a search string.
The file = master data file
The checkfile = list of states & regions
When I have more than 1 state in the file that is not in sorted order it bombs out.
How can i get this to work without having to sort my "file"
The Error message: Traceback (most recent call last):
File "./gangnamstyle.py", line 27, in
csvLineList_2 = csv2[lineCount].split(",")
IndexError: list index out of range
My code:
#!/usr/bin/python
import csv
file = raw_input("Please enter the file name to search: ") #File name
checkfile = raw_input("Please enter the file with the search data: ") #datafile
save_file = raw_input("Please enter the file name to save: ") #Save Name
search_string = raw_input("Please type string to search for: ") #search string
#row = raw_input("Please enter column text is in: ") #column number - starts at 0
#ID_INDEX = row
#ID_INDEX = int(ID_INDEX)
f = open(file)
f1 = open(save_file, 'a')
csv1 = open(file, "r").readlines()
csv2 = open(checkfile, "r").readlines()
#what looks for the string in the file
copyline=False
for line in f.readlines():
if search_string in line:
copyline=True
if copyline:
f1.write(line)
for lineCount in range( len( csv1) ):
csvLineList_1 = csv1[lineCount].split(",")
csvLineList_2 = csv2[lineCount].split(",")
if search_string == csvLineList_2[0]:
f1.write(csvLineList_2[2])
f1.close() #close saved file
f.close() #close source file
#csv1.close()
#csv2.close()
OK, so that error message is an IndexError: list index out of range in the line csvLineList_2 = csv2[lineCount].split(","). There's only one indexing happening there, so apparently lineCount is too big for csv2.
lineCount is one of the values of range(len(csv1)). That makes it automatically in range for csv1. Apparently csv1 and csv2 are not the same length, causing the IndexError.
Now that's quite possible, because they contain lines from different files. Apparently the files don't have equal number of lines.
To be honest I have no clue why you are reading the lines into csv1 at all. You loop over those lines and split them (into the variable csvLineList_1), but you never use that variable.
I think your loop should just be:
for line in csv2:
parts = line.strip().split(",") # line.strip() removes whitespace and the newline
# at the end of the line
if search_string == parts[0]:
f1.write(parts[2] + "\n") # Add a newline, you probably want it
I hope this helps.
The error you're getting is probably due to the file lengths not being equal.
It's not exactly clear from what you've written, what you're hoping to do. It looks to me like (maybe) you want to find a search term in "master file", and if you find it, write the line you find to the "save file". It also looks to me like you want to find that same search term in the very first field of the "check file", and if you find it, write the contents of the third field into the "save file". If that's wrong, it's because your code has bugs.
Either way, there's a bunch of issues in the code you've posted, and you're probably going to get at least some mileage out of using the csv module to do what you're trying to do.
Maybe post a fuller problem description.
Edit:
import csv
import sys
def build_state_lookup(fn):
with open(fn) as infile:
reader = csv.reader(infile)
# throw away first line
reader.next()
# now build a dictionary mapping state to region
lookup = {state: region for (state, _, region) in reader}
return lookup
def process_big_file(in_fn, checkfile, out_fn):
lookup = build_state_lookup()
with open(in_fn) as infile:
with open(out_fn, 'w') as outfile:
reader = csv.reader(infile)
writer = csv.writer(outfile)
# output the header row
writer.writerow(reader.next() + ['Region'])
for row in reader:
state = row[0]
region = lookup.get(state, "No Region Found")
row.append(region)
writer.writerow(row)
def main():
process_big_file(*sys.argv[1:])
if __name__ == '__main__':
main()

Taking numbers from a file, and find the average where the amount of lines changes?

I am trying to make a program which grabs a list of numbers from a file (which could change in lines and size), and then print out the total of all the numbers and the average. I had no problems doing this when I had a set number of linereads, but am confused on the 'proper' way when the lineread changes every run.
This is my work-in-progress code. I read around a bit and found the correct (?) way of looping through the file to find the length, but not sure how to implement it since it throws some type of IO error currently. Thanks for the help!
def main():
filename = input("Enter file name (name.txt):")
try:
file = open(filename, "r")
except IOError:
print("Error opening file!")
totalLines = totalLineGet(filename)
results = []
for x in range(totalLines):
results.append(getLineNumber(x+1, file))
print("Total = ", numTotal)
print("Average = ", numAvg)
def totalLineGet(_filename):
count = 0
_file = open(_filename, "r")
for x in open(_file):
count+= 1
return count
def getLineNumber(linetoget, _file):
try:
intNumber = int(number = _file.readline())
except ValueError:
print("Error in file data!")
return intNumber
main()
I'm not sure what you want to do... but you should be able to get the answer in one pass.
You can use enumerate() to number an iterable object, in this case a file, if you need to know the item/line number count.
Assuming a single int() per line:
with open(filename, "r") as in_f:
numbers = []
for line in in_f:
line = line.strip() # remove whitespace
if line: # make sure there is something there
number_on_line = int(line)
numbers.append(number_on_line)
sum_of_numbers = sum(numbers)
avg_of_numbers = sum(numbers)/len(numbers)
if this is CSV data you should look into using the csv module, it will split the line into rows/columns for you.
import csv
filename = "somefile"
with open(filename, "rb") as in_f: # <-- notice "rb" is used
reader = csv.reader(in_f)
for row in reader:
for col in row:
# do stuff
...
A simple solution, doing what you want...
filename = 'tmp.txt'
f = open(filename)
s, totnum = 0, 0
for line_number, line in enumerate(f):
nums = map(int, line.split())
s += sum(nums)
totnum += len(nums)
print "numbers:", totnum, "average:", 1.0*s/totnum
This assumes your file only has numbers on each line and not characters, otherwise you'll get a TypeError.
list_of_numbers = []
with open('somefile.txt') as f:
for line in f:
if line.strip(): # this skips blank lines
list_of_numbers.append(int(line.strip()))
print 'Total ',len(list_of_numbers)
print 'Average ',1.0*sum(list_of_numbers)/len(list_of_numbers)
There are some good answers regarding how to do what you want. As for the IO error, the input() built-in attempts to evaluate the user's input which is both dangerous and not what you want.
Try using the raw_input() built-in. That returns the user's input as a string. For fun, try running your script and giving it __name__ as the filename and see what happens.

Categories

Resources