Python: Importing class from another file and implementing function - python

I'm trying to import a class from another file and then implement the member function in my main function. I'm really just trying to understand the syntax of Python, as I am still really new to the language. My program is simple, and isn't really meant to do much. I'm more or less just trying to get a grasp on how Python goes about this. My class file is called Parser.py and here's is the code:
class Parser:
def hasMoreCommands(self):
if not c:
return false
else:
return true
and my main function is in a file called jacklex.py The main function only opens an input file and copies the text to an output file. Here's the code:
import Parser
from Parser import *
f = open('/Python27/JackLex.txt' , 'r+')
fout = open('/Python27/output.txt' , 'w')
while Parser.hasMoreCommands:
c = f.read(1)
fout.write(c)
print "All Done"
f.close()
fout.close()
My issue is that my program runs, but it seems to be getting stuck in an infinite loop. There's never any text printed to the ouput file, and "All Done" is never printed in the Python Shell. Am I missing something essential that's causing my program not to work properly?

Parser.hasMoreCommands refers to the (unbound) method, not the output. It'll always evaluate to True.
You need to create an instance of your parser and then call the method:
parser = Parser()
while parser.hasMoreCommands():
...

Related

How to read a value from another python file after file write?

I am new to Stackoverflow so I will try to ask the question as detailed as possible. I am facing an issue where I call a function to write a value to a python file, and another function to return this written value. However, the function that supposed to return this written value does not return the most updated value after the write function.
I have done multiple researches and tried multiple methods from other questions posted in Stackoverflow but it still didn't work for me.
Here is what I currently have:
In test.py
import random
import string
from test_value import *
def write():
letters = string.ascii_letters
value_to_be_passed = ''.join(random.choice(letters) for i in range(10))
f = open("test_value.py", "w")
f.write('value="' + value_to_be_passed + '"')
f.close()
def read():
print(value)
write()
read()
In test_value.py
value="MutmHDlVQj"
If you run this file, it will generate a new string and store this new string into test_value.py. But when the function read() runs, it does not print out the newly generated string. It seem as though when I run this program, python will immediately store the value in test_value.py in it's memory and does not return the new value when called.
I have tried fsync, flush, with open but it still doesn't work. It won't be ideal to read the file as a plaintext as I might be storing multiple variables in test_value.py so that my program can call the value of the respective variables.
You can run the code in your ide, upon the first run it will print MutmHDlVQj in your terminal even though the goal is supposed to print the newly generated string.
Does anyone know how this could be solved? Thank you in advance.
Workaround Solution
Thanks to tripleee that gave me the idea of this cheap solution. However, I am sure there are better methods that can be done to solve this issue. May the experts give your opinions on this!
Instead of importing at compile time, I ran the importing when I really needed it.
def read():
from test_value import *
print(value)
The import happens when your script is compiled, before it runs and writes anything to the new file. If you want to import something during runtime, you can do that with importlib; but this seems fundamentally like an XY problem. If your task is to serialize some data, use pickle or simply save the data in a standard format like JSON.
from import method you can't pass a variable so simply for a return value, you must specify in test_value.py a return function.
here's the functioning code:
import random
import string
from test_value import value
def write():
letters = string.ascii_letters
value_to_be_passed = ''.join(random.choice(letters) for I in range(10))
f = open("test_value.py", "w")
f.write('value="' + value_to_be_passed + '"')
f.close()
def read():
returned_value = value()
print(returned_value)
write()
read()
in test_value.py:
def value():
value="SbjvLSYfNs"
return value
written like this I have a functioning code that prints the value returned from another python file like you asked.
hope it helps in the future, but remember that if you want to return a value, you must specify the return function

Using Pytest to test a Python Program

TI am quite new to Python Programming and have a question on testing using Pytest. In a high-level, I have a program that takes 3 pieces of user input and generates a text file in the end. For my tests, I want to basically compare the files my program outputted, with what it should be.
Now, I am not sure how to go about testing. The program itself takes no arguments, but just relies on 3 pieces of user input, which I'll use monkeypatch to simulate. Do I create a new python file called program_test.py and have methods in here that call the original program? I have tried this, but I'm having trouble actually calling the original program and sending in the simulated inputs. Or, do I have tests in the original program (which doesn't make much sense to me).
I want something like this:
import my_program
def test_1():
inputs = iter(['input1', 'input2', 'input3'])
monkeypatch.setattr('builtins.input', lambda x: next(inputs))
my_program
# now do some assertion with some file comparison
# pseudocode
assert filecompare.cmp(expectedfile, actualfile)
This just seems to be running the original program and I think its to do with the import statement i.e. it is never running test_1(), probably because I never call it? Any help would be appreciated!
Without providing your my_program code it's hard to tell what's going on.
Since you are mentioning import problems, I guess your not defining main() and if __name__ == "__main__".
Here's a little example of how you can test that.
First, structure your my_program to have main function which contains the code and then add if __name__ == "__main__" which will allow you to run main function if the my_program is executed directly but also to import my_program as module to other files (without running it, for more information please see: What does if name == "main": do?).
my_program:
def main():
x = input()
y = input()
z = input()
with open("test", "w") as f_out:
f_out.write(f"{x}-{y}-{z}")
if __name__ == "__main__":
main()
Now you can create a test.py file and test the main function of my_program:
import os
import filecmp
import my_program
def test_success(monkeypatch):
inputs = ["input1", "input2", "input3"]
monkeypatch.setattr("builtins.input", lambda: next(iter(inputs)))
my_program.main()
with open("expected", "w") as f_out:
f_out.write("-".join(inputs))
assert filecmp.cmp("expected", "test")
os.remove("test")
os.remove("expected")
def test_fail(monkeypatch):
inputs = ["input1", "input2", "input3"]
monkeypatch.setattr("builtins.input", lambda: next(iter(inputs)))
my_program.main()
with open("expected", "w") as f_out:
f_out.write("something-else-test")
assert not filecmp.cmp("expected", "test")
os.remove("test")
os.remove("expected")
This is an example so I used os.remove to delete the files. Ideally you would define fixtures in your tests to use tempfile and generate random temporary files which will be automatically deleted after your tests.

Making a Python Program Update to the Version on Disk Immediately When there is a Change

So I am trying to make a python program to write some code to itself the run the code it created before the session ends, like this:
for i in range(10):
with open('test.py','a') as f:
f.writelines(' print("Hello World!")\n')
So, the 3rd line creates a 4th line which would print 'Hello World!', next iteration it would print it twice (because then it would have created yet another line saying the same thing) all the way up to 10 iterations. So, in the end, it looks like this:
for i in range(10):
with open('test.py','a') as f:
f.writelines(' print("Hello World!")\n')
print("Hello World!")
print("Hello World!")
print("Hello World!")
... Up to 10
(However, I mainly want to store outputted data into a variable from this, not prints or anything along those lines).
The problem is that it doesn't update fast enough. When you run the program for the first time you get nothing, then if you close and reopen the code you see all ten 'print('Hello World!')'s. I have no clue how to solve this...
Thanks!
The way you want your program to be dynamically written is possible. (But be mindful, that there are sure better alternatives than this answer provides)
First, you need to have an empty 'program.py' (or any other name) in your import path.
Then it is possible to modify program.py on the fly. The trick is that you can reload your program as a module in python, which will execute it.
import os
from importlib import reload
import program
from io import StringIO
from unittest import mock
def write_program(list_that_contains_strings_that_are_lines, force_new=False):
mode = 'w' if not os.path.exists('program.py') or force_new else 'a+'
with open('program.py', mode) as f:
f.writelines(list_that_contains_strings_that_are_lines)
lines = ['print("Hello!")\n' for _ in range(5)]
out_stream = StringIO()
with mock.patch('sys.stdout', out_stream):
write_program(lines)
reload(program)
out_stream.getvalue()
and program.py will have 5 print statements in the end.
Also, take a look into How can I make one python file run another? for detailed explanation.
Edit: You can redirect stdout stream to some buffer.

Is there a way to store these user defined functions in an external file? [duplicate]

Sorry basic question I'm sure but I can't seem to figure this out.
Say I have this program , the file is called pythonFunction.py:
def function():
return 'hello world'
if __name__=='__main__':
print function()
How can I call it in another program?
I tried:
import pythonFunction as pythonFunction
print pythonFunction.function
Instead of 'hello world', I get ...I have done this in the past by making the first file a class, but I was wondering how to import the function correctly? If it helps, in my real file, I am printing a dictionary
You need to print the result of calling the function, rather than the function itself:
print pythonFunction.function()
Additionally, rather than import pythonFunction as pythonFunction, you can omit the as clause:
import pythonFunction
If it's more convenient, you can also use from...import:
from pythonFunction import function
print function() # no need for pythonFunction.

Importing code from a file as a function in python

Essentially I have a script in one file which I would like to import and run as a function in another file. Here is the catch, the contents of the first file CANNOT be written as function definition it just needs to be a plain old script (I'm writing a simulator for my robotics kit so user experience is important). I have no idea how to go about this.
Adam
Anything can be written as a function.
If you additionally need the ability to call your script directly, you just use the __name__ == '__main__' trick:
def my_function():
... code goes here ...
if __name__ == '__main__':
my_function()
Now you can import my_function from the rest of your code, but still execute the file directly since the block at the end will call the function.
Assuming that the code in the file you need to import is a well bounded script - then you can read in as a text variable and use the "execfile" function to create a function from that script.
By well bounded I mean that you understand all the data it needs and you are able to provide all of it from your program.
An alternative would be to use the "system" call, or the subprocess module to call the script as if it was an external program (depending if you need the script output).
A final approach will be to use exec to create a function - see approach 3.
The approach you use determines what you need your other script to do ..
examples :
hello.py (your file you want to run, but can't change):
# Silly example to illustrate a script which does something.
fp = open("hello.txt", "a")
fp.write("Hello World !!!\n")
fp.close()
Three approaches to use hello.py without importing hello.py
import os
print "approach 1 - using system"
os.system("python hello.py")
print "approach 2 - using execfile"
execfile("hello.py", globals(), locals())
print "approach 3 - exec to create a function"
# read script into string and indent
with open("hello.py","r") as hfp:
hsrc = [" " + line for line in hfp]
# insert def line
hsrc.insert(0, "def func_hello():")
# execute our function definition
exec "\n".join( hsrc) in globals(), locals()
# you now have a function called func_hello, which you can call just like a normal function
func_hello()
func_hello()
print "My original script is still running"

Categories