lets say i have a folder which contains the following files:
f1.py
f2.py
f3.py
in f1.py i got this code:
#O = "Random string"
print("ABCD")
#P = "Random string"
but in f2.py and f3.py i have this code:
#M = "Random string"
print("EFGH")
#Z = "Random string"
And i want to change the strings in the 'print' function in f2.py and f3.py to the string i have in print in f1.py, and run all the files in the folder after changing the strings, using f1.py
It would be best to have more context why you want to do this.
This is possible, but in 99% of the cases it's not a god idea to write self modifying code, though it can be a lot of fun.
In fact you do not really write self modifying code, but more one piece of code modifying other files. But this is also rarely to be recommended.
What's more usual is, that one script analyzes / parses f1.py, extracts the data writes some data into a file (e.g. a json file)
and f2.py and f3.py read the data from that file and do then print this data.
Is there a particular reason you want to have code, that is modifying other python files.
If you really want to have f2.py and f3.py modified, then there is another solution, which is called templating (you can for example use Jinji).
In this case you have two template files f2.py.template and f3.py.template.
you write a file parsing f1.py, extracting the data and creates f2.py from f2.py.template and the extracted data. (Same for f3.py.template and f3.py)
If you're really 100% sure, that you really want what you ask for.
Yes it is possible:
you write a script, tht opens and reads f1.py line by line, looks for the line "#O = ", then memorizes the next line.
Then it reads f2.py line by line and writes it to another file (e.g. next_version_of_f2.py). it reads in a line and writes it out until it encounters the line #M = "Random string in f2.py In this case the line will be written out, the desired print will be written out, the print line from f2.py will be read and ignored and then you read and write all the other lines.
Then you close f2.py and next_version_of_f2.py, rename f2.py into f2.py.old and rename next_version_of_f2.py to f2.py
This is certainly possible but probably inadvisable.
Editing code should typically be a separate action from executing it (even when we use a single tool that can do both, like a lot of modern IDEs).
It suggests a poor workflow. If you want f2.py to print("ABCD"), then it should be written that way.
It's confusing. In order to understand what f2.py does, you have to mentally model the entirety of f1.py and f2.py, and there's no indication of this in f2.py.
It invites all kinds of difficult-to-debug situations. What happens if f1.py is run twice at the same time? What if two different versions of f1.py are run at the same time? Or if I happen to be reading f2.py when you run f1.py? Or if I'm editing f2.py and save my changes while you're running f1.py?
It's a security problem. For f1.py to edit f2.py, the user (shell, web-server, or other surface) calling f1.py has to have edit permissions on f2.py. That means that if they can get f1.py to do something besides what you intended (specifically, if they can get their own text in place of "ABCD"), then they can get arbitrary code execution in everyone else's runtime!
Note that it's perfectly fine to have code that generates or edits other code. The problem is when a program (possibly spanning multiple files) edits its own source.
gelonida discusses some options, which are fine and appropriate for certain contexts such as managing user-specific configuration or building documents. That said, if you're familiar with functions, variables, imports, and other basics of computer science, then you may not even need a config.json file or a template engine.
Reconsider the end result you're trying to accomplish. Do some more research/reading, and if you're still stuck start a new question about the bigger-picture task.
complaints about XYZ problems are old hat, so here's how to do what you want, even though it's awful and you really shouldn't.
f1.py
import os
import re
import sys
#O = "Random string"
print("ABCD")
#P = "Random string"
selector = re.compile(
r'#([A-Z]) = \"Random string\"\nprint\(\"([A-Z]{4})\"\)\n#([A-Z]) = \"Random string\"')
template = '''#{} = "Random string"
print("{}")
#{} = "Random string"'''
own_file_name = os.path.abspath(__file__)
own_directory = os.path.dirname(own_file_name)
def read_file(name: str) -> str:
with open(name, 'r') as f:
return f.read()
find_replacement = selector.match(read_file(own_file_name))
replacement = find_replacement.group(1) if find_replacement else False
if not replacement:
sys.exit(-1)
def make_replacement(reg_match) -> str:
return template.format(reg_match.group(1), replacement, reg_match.group(3))
for dir_entry in os.listdir(own_directory):
if dir_entry.is_file():
original = read_file(dir_entry.path)
with open(dir_entry.path, 'w') as out_file:
out_file.write(selector.sub(make_replacement, original))
# this will cause an infinite loop, but you technically asked for it :)
for dir_entry in os.listdir(own_directory):
if dir_entry.is_file():
exec(read_file(dir_entry.path))
I want to be clear that the above is a joke. I haven't tested it, and I desperately hope it won't actually solve any problems for you.
Related
I'm new to python, trying to learn and code at the same time, to test what i can do, I learned java, javascript, php, html, css, on my course, so I still remeber the basics.
I reached this problem and after hours i haven't found a solution that I can understand and like.
So this is my structure:
my structure
I want to read the test_input.txt inside the test_input.py, i want that because there are some strings for the user, and i want those strings to change based on the language. I though to write the .txt along side the .py file, but then everytime a function would generate string I would need to make all the language folders again, also if needed to add another language, I also would make various folders on every string occurency.
If possible, i want a solution that read the project inside itself to get the .txt file, because i want this project to be an .exe desktop program. Also, is pyhton good to make simple desktop apps? I'm lookin foward to learn the future languages, like I learned android in java, but I want to use kotlyn because is "better", so I cold make this project in java as a learned and did some in the past, but I want the "what will be most used on the future".
Please correct me in anything if I'm wrong, all this is more about see what I can do, and how, thanks for the help!!!
If I understand you correctly, you want to load and read the txt file in py. If this is the case, like i understood, then perhaps you want to follow this tutorial here:
https://www.pythontutorial.net/python-basics/python-read-text-file/
Also, did you try to open/load it already? If so, did you get an error? Most of the time, it is a path problem for beginners so make sure the path is setup already.
Cheers
I got this script from geeksforgeeks, it got multiple form of how to read a .txt, I am leaving you as well the documentation.
# Program to show various ways to read and
# write data in a file.
file1 = open("myfile.txt","w")
L = ["This is Delhi \n","This is Paris \n","This is London \n"]
# \n is placed to indicate EOL (End of Line)
file1.write("Hello \n")
file1.writelines(L)
file1.close() #to change file access modes
file1 = open("myfile.txt","r+")
print("Output of Read function is ")
print(file1.read())
print()
# seek(n) takes the file handle to the nth
# bite from the beginning.
file1.seek(0)
print( "Output of Readline function is ")
print(file1.readline())
print()
file1.seek(0)
# To show difference between read and readline
print("Output of Read(9) function is ")
print(file1.read(9))
print()
file1.seek(0)
print("Output of Readline(9) function is ")
print(file1.readline(9))
file1.seek(0)
# readlines function
print("Output of Readlines function is ")
print(file1.readlines())
print()
file1.close()
https://www.geeksforgeeks.org/reading-writing-text-files-python/
I'm making a troubleshooting program in which I need to take a python program which is stored in a text file, but I can't use the 'import' module. To clarify this, there would be a python program stored as a '.txt' file, and in the main program I would take this text file and be able to use it as a subprogram. I've tried doing this, but I have had no clue of how to go about it, especially since I do not have much experience of Python.
Below is roughly the program. I don't know how to format it either, but here goes:
phonechoice = input("What type of phone do you have?")
if 'iphone' in phonechoice:
#here I would load a text file which contains the program for the iphone
#which asks them what problem they have with their phone and gives a solution
I'm wondering how I can do this. I thought how I could do this and maybe I could 'copy and paste' the program, line by line, into a definition, which I could then use. Would this work, and if it doesn't then in what other way could I do it?
Rename the text file to a python file, i.e. change the extension to ".py". This does not change the fact that it is a text file, just like renaming a picture.jpg file to picture.txt does not change the fact that it's an image file.
If you have some wacky requirement to import a module saved in file with a .txt extension, you can not use an import statement. But it is still possible to import like this:
import imp
my_module = imp.load_source('my_module', 'example.txt')
I am a bit reluctant to answer a "homework" type question, but I will give you some pointers on what you need to do. If I have a text file with this in it:
def main():
print("Hello")
main()
I could execute the code with the exec function like this:
with open("filename.txt") as file: #filename should be the name of the file
data = file.read()
exec(data) #this executes the code
The output would be as expected:
Hello
Hopefully this will shed some light on your problem!
I want to keep a piece of code in a txt file and execute it from my Python script.
For example in the txt file there is
print("ok")
I want my programme to print ok and not print print("ok "). How can I do this?
Doing what you want usually is a security risk, but not necessarily so.
You'll definitely have to notify the user about potential risk.
There is more than one program using execfile() or compile() and exec statement to provide plug-ins system.
There is nothing so ugly about it, you just have to know what are you doing, when and where.
Both execfile(), eval() and exec statement allow you to specify a scope in which will your code be executed/evaluated.
myscope = {}
execfile("myfile.txt", myscope)
This will prevent the new code being mixed with the old one. All variables classes, functions and modules from myfile.txt will be contained in myscope dictionary.
This, however, does not prevent malicious code to delete all files it can from your disk or something similar.
Python 2 has a nice module called rexec, but from Python 2.2 it doesn't work any more.
It implements execfile() exec statement and eval() in restricted environment.
Though it doesn't work it is there, and you can dig through the code to see how it is done.
So, you see, it is possible to allow only secure code to execute (well, as secure as it can be) from external source.
There is another way too.
You can load the file, compile the code from it and then inspect it to see what it does. Then say, yes I'll execute it or no, I won't. This is, however, a little bit more work and a lot of complications.
But, I don't think that it'll be necessary to go through all that stuff. Please elaborate some more on your problem. What exactly do you mean by level editor?
I don't think external code is a solution for that.
You are looking for eval function
eval is a function that takes arbitrary python code represented as a string and execute it at run time.
Example
>>> x = 1
>>> y = eval('x+1')
>>> print(y)
2
It works in both Python 2.x and 3.x
Check the documentation : https://docs.python.org/2.7/library/functions.html#eval
So I wanted to do the same thing. I came across this: GeeksforGeeks.
With this we could make a text file. Let's say it's called myfile.txt and in the first line we will add print("ok") in the second add A += 1.
Now let's move over to the script editor.
# open txt file
f = open("myfile.txt", "r")
# add the data in the file the a var
data = f.readlines()
# remove unwanted \n for new lines and '' left over by the code above
# readlines() returns a list so we need to convert data to str
# in data[] add the line you wish to read from
info = str(data[0]).strip("\n").strip("'")
# run the code
exec(info)
# running the A += 1 in the txt file
# run this
A = 0
info = str(data[1]).strip("\n").strip("'")
while A == 0:
print(A)
exec(info)
print(A)
# if you wanted too you can even define a variable with this
alist = ["B = 0", "B += 1", "print(B)"]
runner = [0, 1, 2, 1, 2, 0, 2]
for i in range(len(runner)):
exec(alist[int(runner[i])])
I have a python program that just needs to save one line of text (a path to a specific folder on the computer).
I've got it working to store it in a text file and read from it; however, I'd much prefer a solution where the python file is the only one.
And so, I ask: is there any way to save text in a python program even after its closed, without any new files being created?
EDIT: I'm using py2exe to make the program an .exe file afterwards: maybe the file could be stored in there, and so it's as though there is no text file?
You can save the file name in the Python script and modify it in the script itself, if you like. For example:
import re,sys
savefile = "widget.txt"
x = input("Save file name?:")
lines = list(open(sys.argv[0]))
out = open(sys.argv[0],"w")
for line in lines:
if re.match("^savefile",line):
line = 'savefile = "' + x + '"\n'
out.write(line)
This script reads itself into a list then opens itself again for writing and amends the line in which savefile is set. Each time the script is run, the change to the value of savefile will be persistent.
I wouldn't necessarily recommend this sort of self-modifying code as good practice, but I think this may be what you're looking for.
Seems like what you want to do would better be solved using the Windows Registry - I am assuming that since you mentioned you'll be creating an exe from your script.
This following snippet tries to read a string from the registry and if it doesn't find it (such as when the program is started for the first time) it will create this string. No files, no mess... except that there will be a registry entry lying around. If you remove the software from the computer, you should also remove the key from the registry. Also be sure to change the MyCompany and MyProgram and My String designators to something more meaningful.
See the Python _winreg API for details.
import _winreg as wr
key_location = r'Software\MyCompany\MyProgram'
try:
key = wr.OpenKey(wr.HKEY_CURRENT_USER, key_location, 0, wr.KEY_ALL_ACCESS)
value = wr.QueryValueEx(key, 'My String')
print('Found value:', value)
except:
print('Creating value.')
key = wr.CreateKey(wr.HKEY_CURRENT_USER, key_location)
wr.SetValueEx(key, 'My String', 0, wr.REG_SZ, 'This is what I want to save!')
wr.CloseKey(key)
Note that the _winreg module is called winreg in Python 3.
Why don't you just put it at the beginning of the code. E.g. start your code:
import ... #import statements should always go first
path = 'what you want to save'
And now you have path saved as a string
I've done a fair amount of lurking on SO and a fair amount of searching and reading, but I must also confess to being a relative noob at programming in general. I am trying to learn as I go, and so I have been playing with Python's NLTK. In the script below, I can get everything to work, except it only writes what would be the first screen of a multi-screen output, at least that's how I am thinking about it.
Here's the script:
#! /usr/bin/env python
import nltk
# First we have to open and read the file:
thefile = open('all_no_id.txt')
raw = thefile.read()
# Second we have to process it with nltk functions to do what we want
tokens = nltk.wordpunct_tokenize(raw)
text = nltk.Text(tokens)
# Now we can actually do stuff with it:
concord = text.concordance("cultural")
# Now to save this to a file
fileconcord = open('ccord-cultural.txt', 'w')
fileconcord.writelines(concord)
fileconcord.close()
And here's the beginning of the output file:
Building index...
Displaying 25 of 530 matches:
y . The Baobab Tree : Stories of Cultural Continuity The continuity evident
regardless of ethnicity , and the cultural legacy of Africa as well . This Af
What am I missing here to get the entire 530 matches written to the file?
text.concordance(self, word, width=79, lines=25) seem to have other parameters as per manual.
I see no way to extract the size of concordance index, however, the concordance printing code seem to have this part: lines = min(lines, len(offsets)), therefore you can simply pass sys.maxint as a last argument:
concord = text.concordance("cultural", 75, sys.maxint)
Added:
Looking at you original code now, I can't see a way it could work before. text.concordance does not return anything, but outputs everything to stdout using print. Therefore, the easy option would be redirection stdout to you file, like this:
import sys
....
# Open the file
fileconcord = open('ccord-cultural.txt', 'w')
# Save old stdout stream
tmpout = sys.stdout
# Redirect all "print" calls to that file
sys.stdout = fileconcord
# Init the method
text.concordance("cultural", 200, sys.maxint)
# Close file
fileconcord.close()
# Reset stdout in case you need something else to print
sys.stdout = tmpout
Another option would be to use the respective classes directly and omit the Text wrapper. Just copy bits from here and combine them with bits from here and you are done.
Update:
I found this write text.concordance output to a file Options
from the ntlk usergroup. It's from 2010, and states:
Documentation for the Text class says: "is intended to support
initial exploration of texts (via the interactive console). ... If you
wish to write a program which makes use of these analyses, then you
should bypass the Text class, and use the appropriate analysis
function or class directly instead."
If nothing has changed in the package since then, this may be the source of your problem.
--- previously ---
I don't see a problem with writing to the file using writelines():
file.writelines(sequence)
Write a sequence of strings to the file. The sequence can be any
iterable object producing strings, typically a list of strings. There
is no return value. (The name is intended to match readlines();
writelines() does not add line separators.)
Note the italicized part, did you examine the output file in different editors? Perhaps the data is there, but not being rendered correctly due to missing end of line seperators?
Are you sure this part is generating the data you want to output?
concord = text.concordance("cultural")
I'm not familiar with nltk, so I'm just asking as part of eliminating possible sources for the problem.