Using for loop to strip white space and resetting the pointer prior to reading a file - python-3.x

I'm using Pycharm and have been very happy so far. However, today I ran into a issue that I can't figure out or explain. The code will prompt the user for an input file. The file is a .txt file that contains lines of words. After the user provides the filename, the program will open it, remove white spaces at the end of the lines and print the contents of the file. (lots_of_words.txt = example)
INPUT
print(lots_of_words.txt)
OUTPUT
Programming is fun and will save the world from errors! ....
Here is the part of the code that is causing the confusion:
user_input = input('Enter the file name: ')
open_file = open(user_input)
for line in open_file:
line = line.rstrip()
read_file = open_file.read()
print(read_file)
OUTPUT
Process finished with exit code 0
Now by just removing the for loop with string.rstrip(), the text file prints fine:
INPUT
user_input = input('Enter the file name: ')
open_file = open(user_input)
# Removed for loop
read_file = open_file.read()
print(read_file)
OUTPUT
Programming is fun and will save the world from errors! ....
I'm using python 3.4 with Pycharm IDE. I realize that the script completed fine without errors, but why won't it print the final variable? I'm sure this is a simple answer, but I can't figure it out.
Running the same code in Python 2.7, prints fine even with string.rstrip().

It has nothing to do with PyCharm.
Your for moves the pointer to the end of the file. To use open_file again, use seek(0), before printing.
open_file = open(user_input)
for line in open_file:
line = line.rstrip()
open_file.seek(0)
read_file = open_file.read()
print(read_file)
Not the most efficient solution though (if efficiency matters in given situation), since you read all the lines twice. You can either store each line after reading it (as suggested in the other answer), or print each line after striping it.
Also, rstrip() will remove whitespaces at the end of the string, but not '\n'.
Irrelevant: You should use with open() as.. : instead of open() since it closes the file automatically.

Iterating over your file object in the for loop will consume it, so there will be nothing left to read, you're simply discarding all lines.
If you want to strip all whitespace from all lines, you could use:
user_input = input('Enter the file name: ')
open_file = open(user_input)
lines = []
for line in open_file:
lines.append(line.rstrip())
print(''.join(lines))
or even shorter:
print(''.join(line.rstrip() for line in open_file))

Related

Python: Reading line with 'readline()' function and appending to a list

My code:
In my file i have these numbers in a list
charge_account = ['4654145', '9658115', '5658845', '5658045', '6181531', '2134874', '5964554']
I am reading the file with a function, appending it to a list and then returning the list:
import os
os.system('cls')
def fileReader():
contentList = []
with open('charge_accounts.txt','r') as f:
line = f.readline().rstrip('\n')
while line !="":
line = f.readline().rstrip(' \n')
contentList.append(line)
# print(contentList)
# print(len(contentList))
#contentList = contentList[:-1]
print(contentList)
return contentList
Now my question is, when i read all the file content and append them to my list, i am getting an extra blank string at the end of the list.
output:
['4654145', '9658115', '5658845', '5658045', '6181531', '2134874', '5964554', '']
Now i have solved it by using slicing (as i commented them out) but i still have not figured out why i am getting the ' ' in the end of the list. i tried filtering it out but noting happens. i have checked if it there is an extra line in the end of the file but what am i doing wrong ?
There are a couple of things. You are reading the file line by line in the while loop. This means that after the last line is read, the while condition is still true so you read an extra line (which is empty) but still added to your list.
But you don't need a while loop: use lines = f.readlines(). It will read the whole file in a list, and you almost have the list you are aiming for. Almost, because you need to strip each element:
def fileReader():
with open('charge_accounts.txt','r') as f:
lines = f.readlines()
return [line.strip() for line in lines]
print(fileReader())
while line !="":
contentList.append(line)
line = f.readline().rstrip(' \n')
print(contentList)
I realized i had to append the while loop primer into the list which i read before the loop started. content.append(line) had to be the first statement in the while loop. This solves the blank entry in the end of list, which in hindsight i realize means that i skipped the first readline value.

file reading in python usnig different methods

# open file in read mode
f=open(text_file,'r')
# iterate over the file object
for line in f.read():
print(line)
# close the file
f.close()
the content of file is "Congratulations you have successfully opened the file"! when i try to run this code the output comes in following form:
c (newline) o (newline) n (newline) g.................
...... that is each character is printed individually on a new line because i used read()! but with readline it gives the answer in a single line! why is it so?
r.read() returns one string will all characters (the full file content).
Iterating a string iterates it character wise.
Use
for line in f: # no read()
instead to iterate line wise.
f.read() returns the whole file in a string. for i in iterates something. For a string, it iterates over its characters.
For readline(), it should not print the line. It would read the first line of the file, then print it character by character, like read. Is it possible that you used readlines(), which returns the lines as a list.
One more thing: there is with which takes a "closable" object and auto-closes it at the end of scope. And you can iterate over a file object. So, your code can be improved like this:
with open(text_file, 'r') as f:
for i in f:
print(i)

Python - Spyder 3 - Open a list of .csv files and remove all double quotes in every file

I've read every thing I can find and tried about 20 examples from SO and google, and nothing seems to work.
This should be very simple, but I cannot get it to work. I just want to point to a folder, and replace every double quote in every file in the folder. That is it. (And I don't know Python well at all, hence my issues.) I have no doubt that some of the scripts I've tried to retask must work, but my lack of Python skill is getting in the way. This is as close as I've gotten, and I get errors. If I don't get errors it seems to do nothing. Thanks.
import glob
import csv
mypath = glob.glob('\\C:\\csv\\*.csv')
for fname in mypath:
with open(mypath, "r") as infile, open("output.csv", "w") as outfile:
reader = csv.reader(infile)
writer = csv.writer(outfile)
for row in reader:
writer.writerow(item.replace("""", "") for item in row)
You don't need to use csv-specific file opening and writing, I think that makes it more complex. How about this instead:
import os
mypath = r'\path\to\folder'
for file in os.listdir(mypath): # This will loop through every file in the folder
if '.csv' in file: # Check if it's a csv file
fpath = os.path.join(mypath, file)
fpath_out = fpath + '_output' # Create an output file with a similar name to the input file
with open(fpath) as infile
lines = infile.readlines() # Read all lines
with open(fpath_out, 'w') as outfile:
for line in lines: # One line at a time
outfile.write(line.replace('"', '')) # Remove each " and write the line
Let me know if this works, and respond with any error messages you may have.
I found the solution to this based on the original answer provided by u/Jeff. It was actually smart quotes (u'\u201d') to be exact, not straight quotes. That is why I could get nothing to work. That is a great way to spend like two days, now if you'll excuse me I have to go jump off the roof. But for posterity, here is what I used that worked. (And note - there is the left curving smart quote as well - that is u'\u201c'.
mypath = 'C:\\csv\\'
myoutputpath = 'C:\\csv\\output\\'
for file in os.listdir(mypath): # This will loop through every file in the folder
if '.csv' in file: # Check if it's a csv file
fpath = os.path.join(mypath, file)
fpath_out = os.path.join(myoutputpath, file) #+ '_output' # Create an output file with a similar name to the input file
with open(fpath) as infile:
lines = infile.readlines() # Read all lines
with open(fpath_out, 'w') as outfile:
for line in lines: # One line at a time
outfile.write(line.replace(u'\u201d', ''))# Remove each " and write the line
infile.close()
outfile.close()

User input after file input in Python?

First year Comp Sci student here.
I have an assignment that is asking us to make a simple game using Python, which takes an input file to create the game-world (2D grid). You're then supposed to give movement commands via user input afterwards. My program reads the input file one line at a time to create the world using:
def getFile():
try:
line = input()
except EOFError:
line = EOF
return line
...after which it creates a list to represent the line, with each member being a character in the line, and then creates a list containing each of these lists (amounting to a grid with row and column coordinates).
The thing is, I later need to take input in order to move the character, and I can't do this because it still wants to read the file input, and the last line from the file is an EOF character, causing an error. Specifically the "EOF when reading a line" error.
How can I get around this?
Sounds like you are reading the file directly from stdin -- something like:
python3 my_game.py < game_world.txt
Instead, you need to pass the file name as an argument to your program, that way stdin will still be connected to the console:
python3 my_game.py game_world.txt
and then get_file looks more like:
def getFile(file_name):
with open(file_name) as fh:
for line in fh:
return line
File interaction is python3 goes like this:
# the open keyword opens a file in read-only mode by default
f = open("path/to/file.txt")
# read all the lines in the file and return them in a list
lines = f.readlines()
#or iterate them at the same time
for line in f:
#now get each character from each line
for char_in_line in line:
#do something
#close file
f.close()
line terminator for the file is by default \n
If you want something else you pass it as a parameter to the open method (the newline parameter. Default=None='\n'):
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

python3 opening files and reading lines

Can you explain what is going on in this code? I don't seem to understand
how you can open the file and read it line by line instead of all of the sentences at the same time in a for loop. Thanks
Let's say I have these sentences in a document file:
cat:dog:mice
cat1:dog1:mice1
cat2:dog2:mice2
cat3:dog3:mice3
Here is the code:
from sys import argv
filename = input("Please enter the name of a file: ")
f = open(filename,'r')
d1ct = dict()
print("Number of times each animal visited each station:")
print("Animal Id Station 1 Station 2")
for line in f:
if '\n' == line[-1]:
line = line[:-1]
(AnimalId, Timestamp, StationId,) = line.split(':')
key = (AnimalId,StationId,)
if key not in d1ct:
d1ct[key] = 0
d1ct[key] += 1
The magic is at:
for line in f:
if '\n' == line[-1]:
line = line[:-1]
Python file objects are special in that they can be iterated over in a for loop. On each iteration, it retrieves the next line of the file. Because it includes the last character in the line, which could be a newline, it's often useful to check and remove the last character.
As Moshe wrote, open file objects can be iterated. Only, they are not of the file type in Python 3.x (as they were in Python 2.x). If the file object is opened in text mode, then the unit of iteration is one text line including the \n.
You can use line = line.rstrip() to remove the \n plus the trailing withespaces.
If you want to read the content of the file at once (into a multiline string), you can use content = f.read().
There is a minor bug in the code. The open file should always be closed. I means to use f.close() after the for loop. Or you can wrap the open to the newer with construct that will close the file for you -- I suggest to get used to the later approach.

Resources