For this function I am supposed to read a file with 12 random numbers. Then I am supposed to output the numbers 1 per line and finally the program is supposed to separate the even numbers and the odds then add them up and display their totals. The problem here is that even though I am getting printing of the numbers fine, the total function in the end is messing up and giving incorrect totals.
def main():
infile = open('numbers.txt','r')
line1 = infile.readline()
line2 = infile.readline()
line3 = infile.readline()
line4 = infile.readline()
line5 = infile.readline()
line6 = infile.readline()
line7 = infile.readline()
line8 = infile.readline()
line9 = infile.readline()
line10 = infile.readline()
line1 = line1.rstrip('\n')
line2 = line2.rstrip('\n')
line3 = line3.rstrip('\n')
line4 = line4.rstrip('\n')
line5 = line5.rstrip('\n')
line6 = line6.rstrip('\n')
line7 = line7.rstrip('\n')
line8 = line8.rstrip('\n')
line9 = line9.rstrip('\n')
line10 = line10.rstrip('\n')
print(line1)
print(line2)
print(line3)
print(line4)
print(line5)
print(line6)
print(line7)
print(line8)
print(line9)
print(line10)
line = infile.readline()
total = 0
evenTotal = 0
oddTotal = 0
while line != '':
total += int(line)
if int(line) % 2 == 0:
evenTotal += int(line)
else:
oddTotal += int(line)
line = infile.readline()
print("=======================================")
print('The total for the even numbers is', evenTotal)
print("=======================================")
print('The total for the odd numbers is', oddTotal)
infile.close()
main()
Here's are the contents from the file
47
64
67
40
91
98
82
2
42
84
48
96
I am only getting 0 for both the totals somehow.
Can someone help with this?
The file object returned by open maintains a pointer to where you are currently in a file. Each time you call infile.readline() it is advancing that pointer to the next line.
Because in the process of testing your code you're reading each line (and printing it) in advance, when you get to the later code that counts the values of the lines your file has already reached the end and will not magically go back to the beginning of the file.
You can either reopen the file, or more simply use infile.seek(0) to return the file pointer to the beginning of the file.
You have two errors in your code,
first you read your file line by line, reaching the end of file, and later you try to read further... that's impossible, you have to rewind your file, as explained in Iguananaut's answer.
your approach is, well, unusual... in general files are not read so explicitly, line1, line2, etc --- you want to be more generic so that your solution of a programming problem results more general.
Of course there are a number of things you don't know about the manner Python deals with files, as the only thing you appear to know is the .readline method, that you abused a little. One really important thing about files is that file objects (what is returned by a open) are iterables, that is you can use them in a for loop (e.g., line 5 below), and the object that you have to deal with in every iteration is a line of text. That said, you can organize your code as follows
# initialize your accumulators
odds = 0 ; evens = 0
# read lines from your file simply iterating on the file object!
for line in open('numbers.txt'):
# the int function ignores the white space, no need to strip
n = int(line)
% now you can print n
print(n)
# with an if...else... we update the accumulators
if n%2: # n is odd
odds += n
else:
evens += n
# we have read a line, converted in an integer, printed it,
# we updated the sums, we have done everything, hence
# we dedent the code, meaning that we are out of the loop
total = evens+odds
print("The sum of all even numbers is", evens)
...
You should learn to use list comprehensions or loops instead...
infile = open('numbers.txt','r')
numbers = [int(line) for line in infile]
evens = [num for num in numbers if num % 2 == 0]
odds = [num for num in numbers if num %2 == 1]
You should be able to do the rest with the code you have, however note that sum([1,2,3,4,5]) returns 15!
#Iguananaut provided you with an answer to your issue. Here's a solution to the problem stated in the question, to show how it can be done.
For this function I am supposed to read a file with 12 random numbers. Then I am supposed to output the numbers 1 per line and finally the program is supposed to separate the even numbers and the odds then add them up and display their totals.
total = [0, 0] # even, odd
with open('numbers.txt') as file:
for n in map(int, file): # read integers from the file, 1 per line
print(n) # "output the numbers 1 per line"
total[n & 1] += n # "separate the even .. and the odds then add them"
print("Even total: {}, odd total: {}".format(*total)) # "display their totals"
Related
I am trying to achieve:
User input word, and it outputs how many lines contain that word also sees it up to the first ten such lines. If no lines has the words, then your program must output Not found.
My code so far:
sentences = []
with open("txt.txt") as file:
for line in file:
words = line.split()
words_count += len(words)
if len(words) > len(maxlines.split()):
maxlines = line
sentences.append(line)
word = input("Enter word: ")
count = 0
for line in sentences:
if word in line:
print(line)
count += 1
print(count, "lines contain", word)
if count == 0:
print("Not found.")
How would I only print first 10 line regardless the amount of lines
Thank you!
If you want to iterate 10 times (old style, not pythonic at all)
index = 0
for line in file:
if index >= 10:
break
# do stuff 10 times
index += 1
Without using break, just put the stuff inside the condition. Notice that the loop will continue iterating, so this is not really a smart solution.
index = 0
for line in file:
if index < 10:
# do stuff 10 times
index += 1
However this is not pythonic at all. the way you should do it in python is using range.
for _ in range(10):
# do stuff 10 times
_ means you don't care about the index and just want to repeat 10 times.
If you want to iterate over file and keeping the index (line number) you can use enumerate
for lineNumber, line in enumerate(file):
if lineNumber >= 10:
break
# do stuff 10 times
Finally as#jrd1 suggested, you can actually read all the file and then only slice the part that you want, in your case
sentences[:10] # will give you the 10 first sentences (lines)
just change your code like this, it should help:
for line in sentences:
if word in line:
if count < 10: print(line) # <--------
count += 1
The basic outline of this problem is to read the file, look for integers using the re.findall(), looking for regular expression of [0-9]+ and then converting the extracted strings to integers and summing up the integers. I'm having different outcome it supposed to end with (209). Also, how can I simplify my code? Thanks (here is the txt file http://py4e-data.dr-chuck.net/regex_sum_167791.txt)
import re
hand = open("regex_sum_167791.txt")
total = 0
count = 0
for line in hand:
count = count+1
line = line.rstrip()
x = re.findall("[0-9]+", line)
if len(x)!= 1 : continue
num = int(x[0])
total = num + total
print(total)
Assuming that you need to sum all the numbers in your txt:
total = 0
with open("regex_sum_167791.txt") as f:
for line in f:
total += sum(map(int, re.findall("\d+", line)))
print(total)
# 417209
Logics
To start with, try using with when you do open so that once any job is done, open is closed.
Following lines are removed as they seemed redundant:
count = count+1: Not used.
line = line.rstrip(): re.findall takes care of extraction, so you don't have to worry about stripping lines.
if len(x)!= 1 : continue: Seems like you wanted to skip the line with no digits. But since sum(map(int, re.findall("\d+", line))) returns zero in such case, this is also unnecessary.
num = int(x[0]): Finally, this effectively grabs only one digit from the line. In case of two or more digits found in a single line, this won't serve the original purpose. And since int cannot be directly applied to iterables, I used map(int, ...).
You were almost there:
import re
hand = open("regex_sum_167791.txt")
total = 0
for line in hand:
count = count+1
line = line.rstrip()
x = re.findall("[0-9]+", line)
for i in x:
total += int(i)
print(total)
Answer: 417209
The program should output all of the integers, one per line, with no blank lines between each line. This program should also output the largest random number that was on file.
myfile = open('mynumbers.txt', 'r')
lines = myfile.readline()
print(lines)
I have gotten that far and I'm stuck. I have literally been sitting here for 6 hours and I don't know what the deal is!
I need help using a loop to read and process the mynumbers.txt file and then it also has to display the largest number that was in the group.
myfile = open('mynumbers.txt', 'w')
import random
num = random.randint(6, 12)
print(num)
for num in range(num):
myfile.write(str(random.randrange(10, 20)))
I also keep getting this error after I try everything.
ValueError: invalid literal for int() with base 10: '16 19 11 18 14 11 15 18 18 16 20 16'
Sorry everyone i'm new to the site!
.readline() only read one line.
You should use .readlines() if you want to get all the lines of your file.
Moreover, it is better to open your file using with.
with open('filename.txt') as fp:
lines = fp.readlines()
# Do something with the lines
See the documentation for more information.
use myfile.readlines() instead of myfile.readline()
max = lines[0]
for line in lines:
print line
print "MAX : ", max([int(line) for line in lines])
First of all, in your write code, you should be using
myfile.write(str(random.randrange(10, 20)) + '\n')
The reason you are getting an error message is because all of your numbers are being written to the same line.
If you want to keep your write code then use the following.
with open('mynumbers.txt', 'r') as myfile:
line = myfile.readline()
nums = line.split(' ')
# Set first number as the max
max = int(nums[0])
# Converting to int will remove trailing newline
print(max)
# Go through the rest of the numbers
for i in range(1, len(nums)):
x = int(nums[i])
print(x)
# Check max
if x > max:
max = x
print("Max = " + str(max))
else use this after changing the write code.
with open('mynumbers.txt', 'r') as myfile:
# Put each line into an array
lines = myfile.readlines()
# Set first number as the max
max = int(lines[0])
# Converting to int will remove trailing newline
print(max)
# Go through the rest of the numbers
for i in range(1, len(lines)):
x = int(lines[i])
print(x)
# Check max
if x > max:
max = x
print("Max = " + str(max))
I would recommend
max([int(l) for l in myfile.readlines()])
edit:
according to your file format, something like this will probably work
max([int(l) for l in myfile.readline().split()])
Your sample file creation script will cause all of your numbers to be created as one long line. You would need to add a newline after each write.
myfile = open('mynumbers.txt', 'w')
import random
num = random.randint(6, 12)
print(num)
for num in range(num):
myfile.write("%s\n" % random.randrange(10, 20))
The following will produce the answer you want. Contrary to other suggestions, I would recommend also learning about processing such files a line at a time as this would scale better. Say in the future your test file was huge, then attempting to read the whole file in could result in you running out of memory to process it. By loading the file a line at a time, it would be able to cope with any size.
max_value = None
with open('mynumbers.txt', 'r') as myfile:
for line in myfile:
num = int(line)
if max_value:
max_value = max(max_value, num)
else:
# Use the first value as the initial max value
max_value = num
if max_value:
print("Max value: %u" % max_value)
else:
print("No numbers found")
Python2 If this is what you have in your text file:16 19 11 18 14 11 15 18 18 16 20 16
You can find the largest number like this:
fname = 'mynumbers.txt'
fhand = open(fname)
for line in fhand:
line = line.rstrip()
num =[int(s) for s in line.split(' ')]
print max(num)
Output:
20
To print all the numbers:
for i in num:
print i
Output:
16
19
11
18
14
11
15
18
18
16
20
16
Hello everyone i have an issue with this problem, the problem is i need to reset the count after every line in the file, i put a comment so you can see where i want to reset the count.
The program is suppose to cut each line after every specified lineLength.
def insert_newlines(string, afterEvery_char):
lines = []
for i in range(0, len(string), afterEvery_char):
lines.append(string[i:i+afterEvery_char])
string[:afterEvery_char] #i want to reset here to the beginning of every line to start count over
print('\n'.join(lines))
def main():
filename = input("Please enter the name of the file to be used: ")
openFile = open(filename, 'r')
file = openFile.read()
lineLength = int(input("enter a number between 10 & 20: "))
while (lineLength < 10) or (lineLength > 20) :
print("Invalid input, please try again...")
lineLength = int(input("enter a number between 10 & 20: "))
print("\nYour file contains the following text: \n" + file + "\n\n") # Prints original File to screen
print("Here is your output formated to a max of", lineLength, "characters per line: ")
insert_newlines(file, lineLength)
main()
Ex. If a file has 3 lines like this with each line having 20 chars
andhsytghfydhtbcndhg
andhsytghfydhtbcndhg
andhsytghfydhtbcndhg
after the lines are cut it should look like this
andhsytghfydhtb
cndhg
andhsytghfydhtb
cndhg
andhsytghfydhtb
cndhg
i want to RESET the count after every line in the file.
I'm not sure I understand your problem, but from your comments it appears you simply want to cut the input string (file) to lines lineLength long. That is already done in your insert_newlines(), no need for the line with comment there.
However, if you want to output lines meaning strings ending with newline char that should be no more than lineLength long, then you could simply read the file like this:
lines = []
while True:
line = openFile.readline(lineLength)
if not line:
break
if line[-1] != '\n':
line += '\n'
lines.append(line)
print(''.join(lines))
or alternatively:
lines = []
while True:
line = openFile.readline(lineLength)
if not line:
break
lines.append(line.rstrip('\n'))
print('\n'.join(lines))
I don't understand the issue here, the code seems to work just fine:
def insert_newlines(string, afterEvery_char):
lines = []
# if len(string) is 100 and afterEvery_char is 10
# then i will be equal to 0, 10, 20, ... 90
# in lines we'll have [string[0:10], ..., string[90:100]] (ie the entire string)
for i in range(0, len(string), afterEvery_char):
lines.append(string[i:i+afterEvery_char])
# resetting i here won't have any effect whatsoever
print('\n'.join(lines))
>>> insert_newlines('Beautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\n..', 10)
Beautiful
is better
than ugly.
Explicit
is better
than impli
cit.
Simpl
e is bette
r than com
plex.
..
isn't that what you want?
Well, I have a problem in a Python script, I need to do is that the index of the split function, increases automatically with every iteration of the loop. I do this:
tag = "\'"
while loop<=302:
for line in f1.readlines():
if tag in line:
word = line.split(tag)[num] #num is the index I need to increase
text = "Word: "+word+"."
f.write(text)
num = num + 1
loop = loop + 1
But...the "num" variable on index doesn't change...it simply stays the same. The num index indicates the word I need to take. So this is why "num = num + 1" would have to increase...
What is the problem in the loop?
Thanks!
Your question is confusing. But I think you want to move num = num + 1 into the for loop and if statement.
tag = "\'"
while loop<=302:
for line in f1.readlines():
if tag in line:
word = line.split(tag)[num] #num is the index I need to increase
num = num + 1
text = "Word: "+word+"."
f.write(text)
loop = loop + 1
Based on Benyi's comment in the question - do you just want this for the individual sentences? You might not need to index.
>>> mystring = 'hello i am a string'
>>> for word in mystring.split():
print 'Word: ',word
Word: hello
Word: i
Word: am
Word: a
Word: string
There seems to be a lot of things wrong with this.
First
while loop <= 302:
for line in f1.readlines():
f1.readlines() is going be [] for every iteration past the first
Second
for line in f1.readline():
word = line.split(tag)[num]
...
text = "Word: "+word+"."
Even if you made the for loop work, text will always be using the last iteration of the word. Maybe this is desired behavior, but it seems strange.
Third
while loop<=302:
...
loop = loop += 1
Seems like it would be better written as
for _ in xrange(302):
Since loop isn't used at all inside that scope. This is assuming loop starts at 0, if it doesn't then you just adjust 302 to however many iterations you wanted.
Lastly
num = num + 1
This is outside your inner loop, so num will always be the same for the first iteration, then won't matter latter because of the empty f1.readlines() as stated before.
I have a different approach to your problem as mentioned by you in the comment. Consider input.txt has the following entry:
this is a an input file.
then the Following code will give you the desired output
lines = []
with open (r'C:\temp\input.txt' , 'r') as fh:
lines = fh.read()
with open (r'C:\temp\outputfile.txt' , 'w') as fh1:
for words in lines.split():
fh1.write("Words:"+ words+ "\n" )