I have the very simple task of creating a text file with 8 random integers from 1-100, reading the file, displaying the numbers on the same line, calculating the even integers and the odd integers, and then displaying them.
The problem I am having is getting the string to display on the same line. I have browsed multiple articles about similar problems to no avail. I have attempted to use .join, however, it seems to break the code when I include it.
# Imports random and time
import random
import time
# Defines the main function
def main():
# Opens file "mynumbers" and creates it if not existent
myfile = open('mynumbers.txt', 'w')
# Statement to write intergers to text file in the correct format
for count in range(8):
number = random.randint(1, 100)
myfile.write(str(number) + '\n')
# Defines read function
def read():
# Opens the "mynumbers" file created in the main function
myfile= open('mynumbers.txt', 'r')
# Sets the content variable to the content of the file that was opened
content = myfile.read()
# Prints the content variable and strips the \n from the string
stripit = content.rstrip('\n')
print(stripit)
# Calls for the functions, prints created, and sleep calls
main()
print('File Created!')
time.sleep(1)
read()
time.sleep(5)
Any help that can be provided would be greatly appreciated.
Your read function is reading the whole file contents into a single string. Your rstrip call on that string removes the last newline from it, but not any of the internal newlines. You can't effectively use str.join, since you only have the one string.
I think there are two reasonable solutions. The first is to stay with just a single string, but replace all the internal newlines with spaces:
def read():
myfile = open('mynumbers.txt', 'r')
content = myfile.read()
stripit = content.rstrip('\n')
nonewlines = stripit.replace('\n', ' ')
print(nonewlines)
The other approach is to split the single string up into a list of separate strings, one for each number. This is more useful if we need to do different things with them later. Of course, all we're going to do is use join to combine them back together:
def read():
myfile = open('mynumbers.txt', 'r')
content = myfile.read()
content_list = content.split() # by default, splits on any kind of whitespace
rejoined_content = " ".join(content_list)
print(rejoined_content)
Don't add a newline char when you write the file. Just use a space instead (or comma, whatever)
import random
import time
#Defines the main function
def main():
#Opens file "mynumbers" and creates it if not existent
myfile = open('mynumbers.txt', 'w')
#Statement to write intergers to text file in the correct format
for count in range(8):
number = random.randint(1,100)
myfile.write(str(number) +' ')
#Defines read function
def read():
#Opens the "mynumbers" file created in the main function
myfile= open('mynumbers.txt', 'r')
#Sets the content variable to the content of the file that was opened
content=myfile.read()
#Prints the content variable and strips the \n from the string
print(content)
#Calls for the functions, prints created, and sleep calls
main()
print('File Created!')
time.sleep(1)
read()
time.sleep(5)
the code looks great but do this instead on your read() function.
def read():
my_numbers = []
with open('mynumbers.txt', 'r') as infile:
for line in infile:
line = line.strip()
my_numbers.append(line)
print (' '.join(line))
I would do it like this, especially because you mentioned the even and odd part that you'll need to do next. At the end of the first loop, you'll have a list of ints (rather than strs) that you can work with and determine whether they are even or odd.
def read():
my_nums = []
with open('mynumbers.txt', 'r') as f:
for line in f:
num_on_line = int(line.strip())
my_nums += [num_on_line]
print num_on_line, #don't forget that comma
for num in my_nums:
#display the even and odds
You could print the numbers in a single line in this way
with open('mynumbers.txt', 'r') as numbers_file:
for line in numbers_file:
print(line.strip(), end=" ")
The line.strip() is for eliminate the \n character.
Related
My code pretty much asks user input and a pre made text which it prints to the .txt file. I want to add the character calculator to print into the file, not as a print. Is it possible?
input = input(str("Type something: "))
file = open("harjoitus.txt", "w")
file.write(str("This code is here automatically.\n"))
file.write(str(input))
file.write(str("\n",))
file.close()
with open("harjoitus.txt", 'r') as file:
text = file.read().strip().split()
len_chars = sum(len(word) for word in text)
print(len_chars)
This pretty much prints the amount of characters as print not to the text file how I want it. Is it possible to edit this somehow that it prints the character amount straight to the file and not as a print?
First before you go into this appending, take a look at how many places you are calling str() its unnecessary most of these values are already stings and ready to be written. Also avoid variable names like input that have preassigned purposes in python. But to add this count to the end, collections.Counter is an option, you should open the file as a append. Then you can add this number to the end of your file.
from collections import Counter
user = input("Type something: ")
with open('harjoitus.txt', 'w') as f:
f.write("This code is here automatically.\n")
f.write(user)
f.write("\n")
with open('harjoitus.txt', 'r') as f:
content = f.read()
c = Counter(content)
tot = sum(c.values())
with open('harjoitus.txt', 'a') as f:
f.write(str(tot))
chrx#chrx:~/python/stackoverflow/10.11$ python3.7 stack.py
Type something: vash
chrx#chrx:~/python/stackoverflow/10.11$ cat harjoitus.txt
This code is here automatically.
vash
38
I want to append or write multiple lines to a file. I believe the following code appends one line:
with open(file_path,'a') as file:
file.write('1')
My first question is that if I do this:
with open(file_path,'a') as file:
file.write('1')
file.write('2')
file.write('3')
Will it create a file with the following content?
1
2
3
Second question—if I later do:
with open(file_path,'r') as file:
first = file.read()
second = file.read()
third = file.read()
Will that read the content to the variables so that first will be 1, second will be 2 etc? If not, how do I do it?
Question 1: No.
file.write simple writes whatever you pass to it to the position of the pointer in the file. file.write("Hello "); file.write("World!") will produce a file with contents "Hello World!"
You can write a whole line either by appending a newline character ("\n") to each string to be written, or by using the print function's file keyword argument (which I find to be a bit cleaner)
with open(file_path, 'a') as f:
print('1', file=f)
print('2', file=f)
print('3', file=f)
N.B. print to file doesn't always add a newline, but print itself does by default! print('1', file=f, end='') is identical to f.write('1')
Question 2: No.
file.read() reads the whole file, not one line at a time. In this case you'll get
first == "1\n2\n3"
second == ""
third == ""
This is because after the first call to file.read(), the pointer is set to the end of the file. Subsequent calls try to read from the pointer to the end of the file. Since they're in the same spot, you get an empty string. A better way to do this would be:
with open(file_path, 'r') as f: # `file` is a bad variable name since it shadows the class
lines = f.readlines()
first = lines[0]
second = lines[1]
third = lines[2]
Or:
with open(file_path, 'r') as f:
first, second, third = f.readlines() # fails if there aren't exactly 3 lines
The answer to the first question is no. You're writing individual characters. You would have to read them out individually.
Also, note that file.read() returns the full contents of the file.
If you wrote individual characters and you want to read individual characters, process the result of file.read() as a string.
text = open(file_path).read()
first = text[0]
second = text[1]
third = text[2]
As for the second question, you should write newline characters, '\n', to terminate each line that you write to the file.
with open(file_path, 'w') as out_file:
out_file.write('1\n')
out_file.write('2\n')
out_file.write('3\n')
To read the lines, you can use file.readlines().
lines = open(file_path).readlines()
first = lines[0] # -> '1\n'
second = lines[1] # -> '2\n'
third = lines[2] # -> '3\n'
If you want to get rid of the newline character at the end of each line, use strip(), which discards all whitespace before and after a string. For example:
first = lines[0].strip() # -> '1'
Better yet, you can use map to apply strip() to every line.
lines = list(map(str.strip, open(file_path).readlines()))
first = lines[0] # -> '1'
second = lines[1] # -> '2'
third = lines[2] # -> '3'
Writing multiple lines to a file
This will depend on how the data is stored. For writing individual values, your current example is:
with open(file_path,'a') as file:
file.write('1')
file.write('2')
file.write('3')
The file will contain the following:
123
It will also contain whatever contents it had previously since it was opened to append. To write newlines, you must explicitly add these or use writelines(), which expects an iterable.
Also, I don't recommend using file as an object name since it is a keyword, so I will use f from here on out.
For instance, here is an example where you have a list of values that you write using write() and explicit newline characters:
my_values = ['1', '2', '3']
with open(file_path,'a') as f:
for value in my_values:
f.write(value + '\n')
But a better way would be to use writelines(). To add newlines, you could join them with a list comprehension:
my_values = ['1', '2', '3']
with open(file_path,'a') as f:
f.writelines([value + '\n' for value in my_values])
If you are looking for printing a range of numbers, you could use a for loop with range (or xrange if using Python 2.x and printing a lot of numbers).
Reading individual lines from a file
To read individual lines from a file, you can also use a for loop:
my_list = []
with open(file_path,'r') as f:
for line in f:
my_list.append(line.strip()) # strip out newline characters
This way you can iterate through the lines of the file returned with a for loop (or just process them as you read them, particularly if it's a large file).
I am trying to write a function that opens a filename, reads the contents of the file, and then prints the contents 3 letters at a time.
Here is what I have tried:
def trigram_printer(filename):
open_file = open(filename)
copy = open_file
three_letters = copy.read(4)
for contents in copy:
print(three_letters)
open_file.close
There are several things I’d change about this code:
You never update the three_letters variable, which is why it prints the same thing repeatedly. You need to update the value of three_letters (by reading three more characters from the file) after you print it.
You copy the open_file object, when I’d just use it directly.
By doing .read(4), you print the contents 4 letters at a time, not 3.
You’re using the f = open(filename); ...; f.close() construction, rather than the more conventional with open(filename) as f; ....
With those thoughts in mind, here’s how I’d write your trigram printer:
def trigram_printer(filename):
"""Prints the contents of <filename>, three characters at a time."""
with open(filename, 'r') as f:
three_letters = f.read(3)
while three_letters:
print(three_letters)
three_letters = f.read(3)
The key part is that every time three_letters gets printed, this function reads the next three characters from the file. When it runs out of characters, three_letters will be an empty string and the while loop will stop.
copy simply points to open_file and your printing the letters for the number of lines in copy:
with open('test.txt') as open_file:
data = open_file.read(3)
while data != '':
print(data) # print 3-gram
data = open_file.read(3)
Just use a continuous loop to test if the file buffer is empty and print the data during the iteration.
I have a text file named number.txt. It contains the following:
0
1
2
3
My code:
def main():
inFile = open("number.txt", "r")
text = inFile.read()
inFile.close()
print(len(text))
main()
I have tried to use the above code to print out how many characters are in the file. It prints out 8, but there are only 4 characters.
I know that when python reads in the file it adds a newline after each line, and this could be extra characters. How do I get rid of this?
The file contains a newline between each line. To filter it out, you can either recreate the string without those newlines with replace, split, or similar, or count the newlines and subtract them from the length (which is faster/more efficient).
with open("number.txt", "r") as file:
text = file.read()
length_without_newlines = len(text) - text.count('\n')
Edit: As #lvc says, Python converts all line endings to '\n' (0x0A), including windows newlines ('\r\n' or [0x0D, 0x0A]), so one need only search for '\n' when finding new line characters.
As Antonio said in the comment the newline characters are in the file.
if you want, you can remove them:
def main():
inFile = open("number.txt", "r")
text = inFile.read()
inFile.close()
text = text.replace('\n', '') # Replace new lines with nothing (empty string).
print(len(text))
main()
The answer of your script is correct: in fact new line are character too (they only are invisible!)
To omit the new line characters (referred in strings with \n or \r\n) then you have to substitute them with an empty string.
See this code:
def main():
inFile = open("number.txt", "r")
text = inFile.read()
text = text.replace("\r\n","") #in windows, new lines are usually these two
text = text.replace("\n","")
caracters.
inFile.close()
print(len(text))
main()
for more information about what \r\n and \n are, try: http://en.wikipedia.org/wiki/Newline
Try this:
if __name__ == '__main__':
with open('number.txt', 'rb') as in_file:
print abs(len(in_file.readlines()) - in_file.tell())
Use string.rstrip('\n'). This will remove newlines from the right side of the string, and nothing else. Note that python should convert all newline chars to \n, regardless of platform. I would also recommend iterating over the lines of the file, rather than dumping it all to memory, in case you have a large file.
Example code:
if __name__ == '__main__':
count = 0
with open("number.txt", "r") as fin):
for line in fin:
text = line.rstrip('\n')
count += len(text)
print(count)
Do it in the print line, like this:
print(len(text.replace("\n", "")))
I am having the following issues in my code below,please provide inputs on where it is going wrong?
change_ignore_base.txt and change_ignore_file.txt are not getting created,where is it going wrong?
I see chagne_ignore has "\r" and "\n" appended,what is the smart way to strip off them and put them in a variable which can later be used to search.
change_ids.txt
206061
150362
147117
147441
143446
200912
change_ignore.txt
150362
147117
147441
143446
200914
Code
import os
import subprocess
from subprocess import check_call
def sync (base_change):
# open a file
with open('change_ignore.txt') as f:
change_ignore = f.readlines()
print "change_ignore"
print change_ignore
with open('change_ids.txt') as f:
lines = f.readlines()
for line in lines:
line=line.strip()
print line
if line <= base_change:
print "IN line<=base_change"
print line
with open("change_ignore_base.txt", "a") as myfile:
myfile.write(line)
if line in change_ignore:
print "IN change_ignore"
print line
with open("change_ignore_file.txt", "a") as myfile:
myfile.write("line")
if line > base_change and line not in change_ignore:
pass
def main ():
base_change=200913
sync(base_change)
if __name__ == '__main__':
main()
Here is a mild adjustment to your program that I believe accomplishes what you want. Key points (as pointed out in the comments) are that you want to compare integers with integers, and that you should avoid opening/closing files multiple times (as was happening with the file appends inside the loop).
import os
import subprocess
from subprocess import check_call
def sync(base_change):
# Generate a list of integers based on your change_ignore file
with open('change_ignore.txt', 'rb') as f:
# Here we make a list of integers based on the file
change_ignore = [int(line.strip()) for line in f]
# Store your hits/misses in lists; that way you do not
# need to continuously open/close files while appending
change_ignore_base = []
change_ignore_file = []
# Now open the file of the IDs
with open('change_ids.txt', 'rb') as f:
# Iterate over the file itself
for line in f:
# Convert the line to an integer (note that this
# implicitly removes the newline characters)
# However we are going to write 'line' to our list,
# which will keep the newline (more on that later)
num = int(line)
print num
# Now we are comparing ints with ints
# I'm assuming the print statements are for debugging,
# so we offset them with some space, making it so that
# any relevant hits are indented under a number
if num <= base_change:
print " IN line<=base_change"
change_ignore_base.append(line)
if num in change_ignore:
print " IN change_ignore"
change_ignore_file.append(line)
if num > base_change and num not in change_ignore:
pass
# Now that you have lists containing the data for your new files,
# write them (they already have newlines appended so writelines works)
# You can use 'with' with two files in this way in Python 2.7+,
# but it goes over 80 characters here so I'm not a huge fan :)
with open('change_ignore_base', 'wb') as b, open('change_ignore_file', 'wb') as f:
b.writelines(change_ignore_base)
f.writelines(change_ignore_file)
def main ():
base_change=200913
sync(base_change)
main()
This should create your files and print the following:
206061
150362
IN line<=base_change
IN change_ignore
147117
IN line<=base_change
IN change_ignore
147441
IN line<=base_change
IN change_ignore
143446
IN line<=base_change
IN change_ignore
200912
IN line<=base_change