Can't get python to read my .txt file on OS X - osx-snow-leopard

I'm trying to get IDLE to read my .txt file but for some reason it won't. I tried this same thing at school and it worked fine using a Windows computer with Notepad, but now using my Mac with IDLE won't read (or find) my .txt file.
I made sure they were in the same folder/directory and that the file was formatted in plain text, still I get errors. Here's the code I was using:
def loadwords(filename):
f = open(filename, "r")
print(f.read())
f.close()
return
filename = input("enter the filename: ")
loadwords(filename)
and here is the error I got after I enter the file name "test.txt" and press enter:
Traceback (most recent call last):
File "/Computer Sci/My programs/HW4.py", line 8, in <module>
loadwords(filename)
File "/Computer Sci/My programs/HW4.py", line 4, in loadwords
print(f.read())
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)

The error you see means your Python interpreter tries to load the file as ASCII chars, but the text file you're trying to read is not ASCII encoded. It's probably UTF-8 encoded (the default in recent OSX systems).
Adding the encoding to the open command should work better:
f = open(filename, "r" "utf8")
Another way to correct that, would be to go back to TextEdit with your file and then select Duplicate (or Save as shift-cmd-S) where you'll be able to save your file again, but this time choosing the ASCII encoding. Though you might need to add ASCII in the encodings option list if it is not present.
This other question and accepted answer provides some more thoughts about the way to choose the encoding of the file you're reading.

You need to open the file with the appropriate encoding. Also, you should return something from the method otherwise you won't be able to do anything with the file.
Try this version:
def loadwords(filename):
with open(filename, 'r', encoding='utf8') as f:
lines = [line for line in f if line.strip()]
return lines
filename = input('Enter the filename: ')
file_lines = loadwords(filename)
for eachline in file_lines:
print('The line is {}'.format(eachline))
This line [line for line in f if line.strip()] is a list comprehension. It is the short version of:
for line in f:
if line.strip(): # check for blank lines
lines.append(line)

textfile = "textfile.txt"
file = open(textfile, "r", encoding = "utf8")
read = file.read()
file.close()
print(read)

This encoding limitiation was limited to python version 2.*
If your MAC is running a Python version 3.* you do not have to add the extra encoding part to encode the txt file.
The below function will directly run in python 3 without any edit.
def loadwords(filename):
f = open(filename, "r")
print(f.read())
f.close()
return
filename = input("enter the filename: ")
loadwords(filename)

Related

Results in Pyhton terminal printed (i.e., using the print function) to a .txt file (ideally created with the open function)

Here's my situation: after running a Python file in VS Code I get a bunch of results in the terminal (in my case, several integers). Now, I want to export what is displayed on the terminal to a txt. file.
I have tried this:
import sys
f = open("out.text", 'w')
sys.stdout = f
print ("out.text", file=f)
f.close()
Basically, I am looking for something like this:
with open('out.txt', 'w') as f:
print('The data I see in the terminal window', file=f)
Now, how do i get this object: 'The data I see in the terminal window'?
P.S. I am very new to programming.
You can use the write method to write to a file:
with open("out.text", "w") as f:
f.write("out.text\n")
f.write("Something else\n")
You need the \n to end the line and print the "Something else" to the next line.
You can use
with open("out.text", "a") as f:
to append the following write statements to the contents of the file.
To do both, i.e., print to the terminal and write to a file, you would need two commands, one for each:
with open("out.text", "w") as f:
print("out.text")
f.write("out.text\n")
print("Something else")
f.write("Something else\n")
Alternatively, you could redirect the terminal output when calling your script
python script.py > out.text
But this will not print anything on the terminal anymore either, but redirect everything to the file.
There is at least one other question on here that deals with this.
Have a look here:
How to redirect 'print' output to a file?
And additionally search a bit more.
There are several solutions to your problem, but having it both ways is gonna be tricky.

Python - Reading from a file, any file

I want to make a function that reads from a txt file, thats given by the user on a function. I know how to open a specific file, on python, but I don't know how to make it any file on a function.
For example I want do something like this:
Read_board(irock.txt) --- irock.txt, can be any other fale, it's the argument that the function recieves. Read the line on the file and return it.
This is my final code
def le_tabuleiro(txt):
text = ((open(txt, 'r')).readline())
print text
Thanks everyone.
You need to read from the file object, not its name. Try this:
def read_board(f):
ficheiro = open(f, "r")
line = ficheiro.readline()
return line
Also note that f is a string containing the file name so pass the variable unquoted to open().
One other thing worth mentioning is that you can/should use a with statement to open the file. This will ensure that the file is properly closed once the function returns (or if there is an exception):
def read_board(f):
with open(f, "r") as ficheiro:
return ficheiro.readline()

Unicode fonts in pdf at GAE with web2py/pyfpdf

I'm writing an app, which results with pdf file with some text with unicode characters. On GAE devserver it works good, but after deploy it can't import font file (crash after add_font() (pyfpdf)).
The code is:
# -*- coding: utf-8 -*-
def fun1():
from gluon.contrib.pyfpdf import FPDF, HTMLMixin
class MyFPDF(FPDF, HTMLMixin):
pass
pdf =MyFPDF()
pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)
pdf.add_page()
pdf.set_font('DejaVu','',16)
pdf.write(10,'test-ąśł')
response.headers['Content-Type']='application/pdf'
return pdf.output(dest='S')
The font files (with a file DejaVuSansCondensed.pkl generated after first run on web2py server...) is in /gluon/contrib/fpdf/font. I didn't add anything to routers.py (I'm using Pattern-based system) also app.yaml is not changed. And I get this:
In FILE: /base/data/home/apps/s~myapp/web2py-04.369240954601780983/applications/app3/controllers/default.py
Traceback (most recent call last):
File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/gluon/restricted.py", line 212, in restricted
exec ccode in environment
File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/applications/app3/controllers/default.py", line 674, in <module>
File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/gluon/globals.py", line 194, in <lambda>
self._caller = lambda f: f()
File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/applications/app3/controllers/default.py", line 493, in fun1
pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True)
File "/base/data/home/apps/s~myapp/web2py-04.369240954601780983/gluon/contrib/fpdf/fpdf.py", line 432, in add_font
font_dict = pickle.load(fh)
File "/base/data/home/runtimes/python27p/python27_dist/lib/python2.7/pickle.py", line 1378, in load
return Unpickler(file).load()
File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
File "/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py", line 966, in load_string
raise ValueError, "insecure string pickle"
ValueError: insecure string pickle
As I said on local (both web2py/rocket and gae) it works well. After deploy only something like this works:
pdf =MyFPDF()
pdf.add_page()
pdf.set_font('Arial','',16)
pdf.write(10,'testąśł')
But without "unusual" characters...
The best solution would be to add my font files (like DejaVu), but basically I need unicode characters in any font... maybe some "half-solution" to use "generic GAE unicode" fonts... if it exist something like this...
Thanks for suggestion Tim!
I found some solution... it isn't the best one, but it works...
The problem is with using pickle on GAE. The best solution (probably) would be to overload/rewrite the add_font() function where for GAE, in such a way, that it would write to a datastore instead of a filesystem. Additionaly ValueError: insecure string pickle error can still occur, I tried b64 encoding according to this. But still I get errors. So my solution is to overload add_font() function with commented out/deleted parts:
if os.path.exists(unifilename):
fh = open(unifilename)
try:
font_dict = pickle.load(fh)
finally:
fh.close()
else:
and
try:
fh = open(unifilename, "w")
pickle.dump(font_dict, fh)
fh.close()
except IOError, e:
if not e.errno == errno.EACCES:
raise # Not a permission error.
Because of this the function every time calculates little bit more instead of just reading data from the pickle... but it works on GAE.

How to properly recognize different line endings in C?

I guess the title speaks for itself.
I am coding a C program on Windows 7, using g++ and Notepad++, which compares content of files.
Content of the file:
simple
file with lines
File has line endings in windows style CRLF.
When I count the length of file using this code:
fseek(file, 0, SEEK_END);
size = ftell(file);
fseek(file, 0, SEEK_SET);
I get 23.
When I change line endings to Unix format LF (using Notepad++) I get 22 length.
This creates kind of a problem, when comparing two files. That's why I ask, if there is a way to determine if given file has LF or CR or CRLF.
I know that I can distinguish between CR and LF, LF has ascii code 10 and CR has ascii code 13. Or LF is '\n' and CR is '\r'.
But when reading file char after char I always get LF (ascii 10), even if there is CRLF.
I hope I made it clear. Thanks.
That is the difference between reading files in text and binary mode.
In text mode (fopen with the relevant parameters fopen( file, "r") then getc etc) all line ends are read as one character. If you read in binary mode e.g. fopen(file, "rb") then you will get the actual bytes and you will see CRLF and CR as different. fseek will use the actual number of bytes and so sees the difference in line endings.
And the only way to tell is to read the files in the two different ways and see if there are CRLF pairs or the size differs, or in practice just see if there is a LF as I fdon't think any current major OS uses that as a line enfing.
In addition to Mark's answer, if you need to do this for a filehandle that has already been opened (such as stdin or stdout), you can use _setmode():
#include <fcntl.h>
#include <io.h>
...
_setmode(fileno(stdin), _O_BINARY);
This works provided no input or output has already occurred to that filehandle. Incidentally, _setmode() only exists on Windows and DOS; on Unix-like operating systems (including versions of Mac OS since OS X), files are effectively always opened in binary mode, and fopen(file, "...b") there is accepted but has no effect. On these platforms, a line ending is encoded by the single character \n.

fopen() returning a NULL pointer, but the file definitely exists

The code I have is as follows:
FILE *txt_file = fopen("data.txt", "r");
if (txt_file == NULL) {
perror("Can't open file");
}
The error message returned is:
Can't open file: No such file or directory
The file 'data.txt' definitely exists in the working directory (it exists in the directory that contains my .c and .h files), so why is fopen() is returning a NULL pointer?
Standard problem. Try
FILE *txt_file = fopen("C:\\SomeFolder\\data.txt", "r");
I.e. try opening it with the full absolute path first ; if it works then you just have to figure out what the current directory is with _getcwd() and then fix your relative path.
Is it possible that the filename is not really "data.txt"?
On Unix, filenames are really byte strings not character strings, and it is possible to create files with controls such as backspace in their names. I have seen cases in the past in which copy-pasting into terminals resulted in files with ordinary-looking names, but trying to open the filename that appears in a directory listing results in an error.
One way to tell for sure that the filenames really are what you think they are:
$ python
>>> import os
>>> os.listdir('.')
My problem was that I had a file filename.txt and I didn't realize that in reality it was filename.txt.txt due to windows not showing the extension.
Make sure that your input file is in the same directory as the executable, which may be different than the one where your source files are kept. If you're running the program in an IDE debugger, make sure that your working directory is set to the location of the input file. Also, if you're running in *nix rather than Windows, you may need to prepend a "./" to the input filename.
Invisible SPACE character in file name?
Once a year I have a similar problem:
I try to open a file with the filename in a string, obtained from a sting operation. When I print the name it seems OK, but fopen() returns a null pointer. The only help is printing the name with delimiters showing the exact beginning and end of the filename string. Of course this does not not help with unprintable chars.
I just had a similar issue like this where I knew the path was correct and the file was in the right location. Check the file permissions. It is possible that the program cannot access the file because it is getting permission denied.
I encountered the same errno to fopen on Linux from a script file corrupted by Windows.
ENOENT 2 No such file or directory
Wordpad on Windows (or some other Microsoft culprit) inserted CRLF = (0x0D, 0x0A) into my linux script files in place of newline = LF = 0x0A. When I read the file name into a buffer and called fopen if failed due to the invisible appended CR character.
In the Codelite editor on Linux Mint I was able to show EOL characters (View > Display EOL) and remove them with find and replace, using copy and paste of the CRLF from the corrupted script files and the LF from an uncorrupted file into the text fields.

Resources