How to read a message using TKInterface? - python

This is the "click me" function which runs when the button on the interface is clicked.
def click_me():
file_name = file_name_entry.get()
the_file_name = str(file_name)
open(the_file_name, "r")
imp_message = file.read(the_file_name)
There is a grey line beneath the_file_name in brackets and when hovered over says: passing str instead of file - is this intentional?
password_output.delete(0.0, END)
password_output.insert(END, imp_message)
The relevant TKInter code is as follows...
file_name_entry = Entry(encrypt_frame, width=20)
file_name_entry.grid(column = 1, row = 1, sticky = W)
Button(encrypt_frame, text= "Submit", command = click_me).grid(column = 2, row = 1)
The error output is:
IOError: Errno22 invalid mode ('r/) or filename ""

Your code is close, but you're trying to read from the file name rather than the opened file object. Change your code to this:
file=open(the_file_name, "r")
imp_message = file.read()
Better yet, use a context manager which will automatically close the file when you're done:
with open(the_file_name, "r") as f:
imp_message = f.read()
The python documentation has a nice tutorial on reading and writing files:
Python 2 - Reading and writing files
Python 3 - Reading and writing files
Unrelated to the actual question, there are a couple problems with your code.
First, there's no need for this statement:
the_file_name = str(file_name)
In this case, file_name is already a string since it is coming from an Entry widget.
Second, the index 0.0 in the statement password_output.delete(0.0, END) is incorrect. Text widget indexes must be strings in the form of <line>.<column>, and lines start at 1 (one). The proper index for the first character is the string "1.0".

Related

Python: .strip() and .write() seem to produce whitespace

I wrote some code to let me type special characters without learning the commands for them so I wrote this:
file = open('test.txt', 'r+')
text = file.read()
text = text.replace('//a', 'Ä')
text = text.replace('//o', 'Ö')
text = text.replace('//u', 'Ü')
text = text.replace('/a', 'ä')
text = text.replace('/o', 'ö')
text = text.replace('/u', 'ü')
text = text.replace('/s', 'ß')
file.truncate(0) # Clears the file
file.write(text.strip()) # edit was .strip(''), made no diffence
print(text)
An example input would be 'n/achtes' which would become 'nächtes'
This sort of works but when I run the file I get a huge amount of blank space in the text file for example 'n/achtes' turns into:
' nächtes'
If I run the program a second time the output, on sublimetext 3, ends with nächtes but has 8 uncopyable copies of <0x00> in a different colour. The amount of blank spaces increases as well in the text file.
truncate(0) resizes the file to zero size, but the current position is not changed.
When writing the data, it is written at current position, so the rest of the file gets null bytes to "pad".
It is a better practice to use truncate() without parameter to truncate the file in the current position:
f.seek(0) # go to the beginning of the file
f.truncate() # truncate in current position
You could try to open the file twice, once for reading and once for writing.
filename = 'text.txt'
with open(filename, 'r') as f:
text = f.read()
print('-' * 20)
print('old text:')
print(text)
replacement_list = [
('//a', 'Ä'),
('//o', 'Ö'),
('//u', 'Ü'),
('/a', 'ä'),
('/o', 'ö'),
('/u', 'ü'),
('/s', 'ß'),
]
for s_old, s_new in replacement_list:
text = text.replace(s_old, s_new)
print('-' * 20)
print('new text:')
print(text)
with open(filename, 'w') as f:
f.write(text.strip())

Add header and footer to each line in a file. Function returns only first line

I have a problem with some of my python code. I want it to open a file, with few lines of text, and add header + footer to each line in that file.
The problem is that 'create_output()' function returns only the first line with additional content. If I switch 'return' to 'print' at the end of this function it properly displays all lines from my file. What could be the reason? I want to understand what am I doing wrong here.
file_path = '/home/user/Desktop/text.txt'
file_path_edited = '/home/user/Desktop/text_new.txt'
header = 'http://'
footer = '.com'
def open_file():
opened_file = open(file_path)
return opened_file
def edit_file():
edited_file = open(file_path_edited, 'w')
return edited_file
def create_output():
for line in open_file():
line = line.strip()
edited_line = header+line+footer
to_file = edit_file()
to_file.writelines(edited_line)
to_file.close()
return edited_line
print (create_output())
OK, I changed it to something like this, now it works fine.
Thanks your feedback, now I know what I'm doing wrong.
file_path = '/home/user/Desktop/text.txt'
file_path_edited = '/home/user/Desktop/text_new.txt'
header = 'http://'
footer = '.com'
def CreateContent():
with open(file_path) as read_file:
with open(file_path_edited, 'w') as write_file:
for line in read_file.readlines():
new_line = "{}{}{}".format(header, line.strip(), footer)
print(new_line)
write_file.write("{}\n".format(new_line))
CreateContent()
You get only one line, because you reopen the write-file all the time instead of letting it open, "w" will truncate the file on open - so last line lives, rest is useless IO. Also you never close your reader afaics.
open(filename, mode) from https://docs.python.org/2/tutorial/inputoutput.html#reading-and-writing-files:
mode can be 'r' when the file will only be read, 'w' for only writing (an existing file with the same name will be erased), and 'a' opens the file for appending; any data written to the file is automatically added to the end. 'r+' opens the file for both reading and writing. The mode argument is optional; 'r' will be assumed if it’s omitted.
Do not split the file open into extra functions, use with open(...) as bla: bla.write(...) so they get closed as soon as you leave the block or some exception happens.
Use string-formatting - either 'this {} ist repleaced with'.format("something") or the inline variant - see below.
def create_output():
modLines = []
with open('/home/user/Desktop/text.txt',"r") as reader, \
open('/home/user/Desktop/text_new.txt',"w") as writer:
for line in reader:
line = line.strip().rstrip('\n') # rstrip might be better if you only cut \n
modline = f'http://{line}.com' # 3.6 inline string formatting, for 2.7 use
modLines.append(modline) # 'http://{}.com'.format(line)
writer.write(modline+"\n") # write does not autoappend \n
return modlines # return a list of written https...
print (create_output())
Should do the trick.
Links:
Format string syntax
Reading and writing files
You could further improve your code as follows:
file_path = '/home/user/Desktop/text.txt'
file_path_edited = '/home/user/Desktop/text_new.txt'
header = 'http://'
footer = '.com'
def CreateContent():
with open(file_path) as read_file, open(file_path_edited, 'w') as write_file:
for line in read_file:
write_file.write("{}{}{}\n".format(header, line.strip(), footer))
CreateContent()

computer keeps crashing with read/writing files

I am not sure why my computer keeps crashing when using this program I tried editing it by closing the file each time I run but it still crashes.
f = open("testfile.txt", "r")
text = f.read()
text = str(text)
looper= text.count(",")
f.close()
god= open("dog.txt","w+")
god.write("Passwords")
god.close()
block=""
for count in range(looper):
first= (text.find(','))
second= (text.find(':'))
block = text[first:second]
text = text[:first] + text[second:]
god= open("dog.txt","a")
god.write(block)
god.close()
I am trying to take items from a text file and format them into a new text file.
EDITED CODE:
f = open("testfile.txt", "r")
text = f.read()
text = str(text)
looper= text.count(",")
f.close()
god= open("dog.txt","w+")
god.write("Testing")
god.close()
for count in range(looper):
block = ""
first= (text.find(':'))
second= (text.find(','))
block= text[first:second]
text = text[second:]
text = text[first:]
print (block)
god= open("dog.txt","a")
god.write(block)
god.close()
In the first section of code I didn't have the string block clearing and I didn't have the string text updating so what would happen is that each time it looped block would duplicate it self
EX:
loop1) :helloworld
loop2) :helloworld:helloworld
loop3) :helloworld:helloworld:helloworld
making those two changes fixed the problem.

How should I replace parts from a text file through Python?

Okay, so here's the deal, folks:
I've been experimenting with Python(3.3), trying to create a python program capable of generating random names for weapons in a game and replacing their old names, which are located inside a text file. Here's my function:
def ModifyFile(shareddottxt):
global name
a = open(str(shareddottxt) , 'r')
b = a.read()
namefix1 = '''SWEP.PrintName = "'''
namefix2 = '''" //sgaardname'''
name1 = b.find(namefix1) + len(namefix1)
name2 = b.find(namefix2, name1)
name = name + b[name1:name2] ## We got our weapon's name! Let's add the suffix.
c = open((shareddottxt + ".lua"), 'r+')
for line in b:
c.write(line.replace(name, (name + namesuffix)))
c.close()
a.close
As you can see, I first open my text file to find the weapon's name. After that, I try to create a new file and copy the contents from the old one, while replacing the weapon's name for (name + namesuffix). However, after calling the function, I get nothing. No file whatsoever. And even if I DO add the file to the folder manually, it does not change. At all.
Namesuffix is generated through another function early on. It is saved as a global var.
Also, my text file is huge, but the bit I'm trying to edit is:
SWEP.PrintName = "KI Stinger 9mm" //sgaardname
The expected result:
SWEP.PrintName = "KI Stinger 9mm NAMESUFFIX" //sgaardname
Where did I mess up, guys?
Something like this is more pythonic.
def replace_in_file(filename, oldtext, newtext):
with open(filename, 'r+') as file:
lines = file.read()
new_lines = lines.replace(oldtext, newtext)
file.seek(0)
file.write(new_lines)
If you don't want to replace that file
def replace_in_file(filename, oldtext, newtext):
with open(filename, 'r') as file, open(filename + ".temp", 'w') as temp:
lines = file.read()
new_lines = lines.replace(oldtext, newtext)
temp.write(new_lines)

Python: How do you read a chunk of text from a file without knowing how long the file actually is?

What I'd like to do is basically I have this file with data in separate lines, except the last piece which is a biography and may stretch across many lines. The biography may be any number of lines long, and all I know is that it starts on the 5th line. Now what I need is a way to retrieve the biography from the fifth line to the end of the file, but I don't know how to do this. Thanks in advance.
Here's what I tried:
from tkinter import *
import os
class App:
charprefix = "character_"
charsuffix = ".iacharacter"
chardir = "data/characters/"
def __init__(self, master):
self.master = master
frame = Frame(master)
frame.pack()
# character box
Label(frame, text = "Characters Editor").grid(row = 0, column = 0, rowspan = 1, columnspan = 2)
self.charbox = Listbox(frame)
for chars in []:
self.charbox.insert(END, chars)
self.charbox.grid(row = 1, column = 0, rowspan = 5)
charadd = Button(frame, text = " Add ", command = self.addchar).grid(row = 1, column = 1)
charremove = Button(frame, text = "Remove", command = self.removechar).grid(row = 2, column = 1)
charedit = Button(frame, text = " Edit ", command = self.editchar).grid(row = 3, column = 1)
for index in self.charbox.curselection():
charfilelocale = self.charbox.get(int(index))
charfile = open(app.chardir + app.charprefix + app.charfilelocale, 'r+')
charinfo = str.splitlines(0)
Another way to phrase your question would be "how do I discard the first four lines of a file I read?" Taking the answer to that a step at a time:
filename = "/a/text/file"
input_file = open(filename)
where the default mode for open() is 'r' so you don't have to specify it.
contents = input_file.readlines()
input_file.close()
where readlines() returns a list of all the lines contained in the input file in one gulp. You were going to have to read it all anyway, so let's do it with one method call. And, of course close() because you are a tidy coder. Now you can use list slicing to get the part that you want:
biography = contents[4:]
which didn't actually throw away the first four lines, it just assigned all but the first four to biography. To make this a little more idiomatic gives:
with open(filename) as input_file:
biography = input_file.readlines()[4:]
The with context manager is useful to know but look it up when you are ready. Here it saved you the close() but it is a little more powerful than just that.
added in response to comment:
Something like
with open(filename) as input_file:
contents = input_file.readlines()
person = contents[0]
birth_year = contents[1]
...
biography = contents[4:]
but I think you figured that bit out while I was typing it.
If you just want to put the entire biography in a string, you can do this:
with open('biography.txt') as f:
for i in range(4): # Read the first four lines
f.readline()
s = ''
for line in f:
s += line
"for line in f" iterates over f. iter(f) returns a generator function that yields f.readline() until the end of the file is reached.
f = open('workfile', 'w')
for line in f:
print line,
This is the first line of the file.
Second line of the file
Python does not require you to know in advance how big a file is or how many lines it contains. It uses an iterator and gets the lines from the file and returns lines lazily.
find some excellent documentation here: http://docs.python.org/2/tutorial/inputoutput.html

Categories