Compiled without errors, but does not print anything - python

This gets compiled without any errors, but does not print anything.
def main():
test = readfile('text.txt')
print test
main()
def readfile(filename):
with open(filename) as f:
lines = f.readlines()
print lines
return lines

You should call main from outside itself. Otherwise it never gets called.
Basically it could look like this:
def main():
test = readfile('text.txt')
print test
def readfile(filename):
with open(filename) as f:
lines = f.readlines()
print lines
return lines
main()
There is nothing as an entry-point in python, like the main-function in C. A function called main is just another function. Your script will be executed from top to bottom.
Or without main:
with open(filename) as f: print(f.readlines())

main in python (on the end of the file):
def main():
print("main")
if __name__ == "__main__":
main()

Related

Declaring CSV write globally

I have a script, but broken down it looks like this
import csv
#Global
writervariable = ''
def function1(): <--uses the writervariable.writerow
def function2():
def main():
writervariable = csv.writer(file)
function1()
function2()
main()
I am getting the error str has no writerow method, which make sense, but I thought setting it to csv.writer would change its type.
When I was just prototyping my script, I did this all in one big chaos function, and it worked.
Adding minimal reproducible example:
import csv
writer = ''
def function1():
writer.writerow(['data1', 'data2'])
def main():
with open('TestFile', 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['header1', 'header2'])
function1()
main()
You get the error because you actually have 2 writervariables in 2 different scopes. One is a string in the global scope, and another one - a csv.writer in the scope of the main() function.
When you try to call writervariable.writerow() inside the function1(), this function can "see" the writervariable in the global scope, which is a string, but the scope of the main function is out of visibility.
What you want to do is to pass the writervariable from the main() function to function1() and then use it there:
def function1(csv_writer): <--uses the writervariable.writerow
csv_writer.writerow()
def function2():
def main():
writervariable = csv.writer(file)
function1(writervariable)
function2()
main()

Can I call the function 'main' more than once in a program?

I am writing a program that has user enter selections in a command line GUI and do not want the program to end until the user selects 'Exit'.
So far, my only solution is to end the workhorse function with a call to 'main()' so as to not exit out.
def parse(file):
out_file = functions(file)
main()
def get_selection():
return selection
def main():
file_to_parse = get_selection()
parse(file_to_parse)
return
if __name__ == '__main__':
main()
My code runs and no other considerations are needed at this time in regards to time or security. I am just wondering how gross of a programming error/mistake/bad opinion I am making.
def parse(file):
out_file = functions(file)
def get_selection():
return selection
def main():
file_to_parse = get_selection()
while file_to_parse.lower() != 'exit':
parse(file_to_parse)
file_to_parse = get_selection()
return
if __name__ == '__main__':
main()
May be something like this would work. Check out looping and strings in Python.
You can use a while loop. But your solution works right?

how to achieve - file write open on __del__?

I m trying to do a some activity on class obj destruction.
How do I achieve file open in __del__ function?
(I m using Python 3.4)
class iam(object):
def __init__(self):
print("I m born")
def __del__(self):
f = open("memory_report.txt", "w")
f.write("He gone safe")
f.close()
if __name__ == '__main__':
i = iam()
print("Script Ends. Now to GC clean memory")
Output:
I m born
Script Ends. Now to GC clean memory
Exception ignored in: <bound method iam.__del__ of <__main__.iam object at 0x00000000022F1A58>>
Traceback (most recent call last):
File "F:\Kumaresan\Code\Python\CommonLib\src\kmxPyQt\devConsole3\tet.py", line 14, in __del__
NameError: name 'open' is not defined
Below code is work fine.
class iam(object):
def __init__(self):
print("I m born")
def __del__(self):
#"open" function still in __builtins__
f = open("memory_report.txt", "w")
f.write("He gone safe")
f.close()
def write_iam():
i=iam()
if __name__ == '__main__':
write_iam()
print("Script Ends. Now to GC clean memory")
In this case:
class iam(object):
def __init__(self):
print("I m born")
def __del__(self):
#__builtins__.open has remove
f = open("memory_report.txt", "w")
f.write("He gone safe")
f.close()
if __name__ == '__main__':
i = iam()
print("Script Ends. Now to GC clean memory")
When exit the __main__ function, before GC delete the "i" instance (execute i.__delete__) "open" function has remove from __builtins__.
As others have mentioned, don't use the ____del___ method to perform such cleanup. Instead, use either contextmanagers (with-statement) or register atexit-handlers.
The problem is, as MuSheng tried to explain, that the __builtins__ are removed before your __del__ is called.
You can trigger the __del__ yourself by assigning None to the variable.
MuSheng's code could be this:
class iam():
def __init__(self):
print("I m born")
def __del__(self):
#"open" function still in __builtins__
with open("memory_report.txt", "w") as f:
f.write("He gone safe")
if __name__ == '__main__':
i = iam()
i = None # This triggers `__del__`
print("Script Ends. Now to GC clean memory")
MuSheng deserves some upvotes, IMO
Below is an alternate I used - Using atexit handlers:
import atexit
class iam(object):
def __init__(self):
print("I m born")
atexit.register(self.cleanup)
def cleanup(self):
f = open("memory_report.txt", "w")
f.write("He gone safe")
f.close()
print ("Done")
if __name__ == '__main__':
i = iam()
print("Script Ends. Now to GC clean memory")
Output:
I m born
Script Ends. Now to GC clean memory
Done

Python Unit Testing checking stdout of a list after while loop

I tried to word the question right, but what I'm trying to do is check the stdout of a list after the while statement. I mock the user input for two iterations and break during the thirs iteration.
here is my run code.
def main():
pirateList = []
maxLengthList = 6
while len(pirateList) < maxLengthList:
item = input("Argh! Enter the item: ")
if item == "exit":
break;
else:
pirateList.append(item)
print(pirateList)
print(pirateList)
main()
here is my test code, i should be expecting [bow, arrow]
import unittest
from unittest.mock import patch
import io
import sys
from RunFile import main
class GetInputTest(unittest.TestCase):
#patch('builtins.input', side_effect=["bow", "arrow","exit"])
def test_output(self,m):
saved_stdout = sys.stdout
try:
out = io.StringIO()
sys.stdout = out
main()
output = out.getvalue().strip()
assert output.endswith('[bow, arrow]')
finally:
sys.stdout = saved_stdout
if __name__ == "__main__":
unittest.main()
when I run this code the program just gets hung up.No errors or tracks
The import statement you are having
from RunFile import main
Actually runs the main function, as it should, and asks for the input. You should have the standard if-clause there:
if __name__ == "__main__":
main()
You might also want to change the stdout handling, here is an example:
class GetInputTest(unittest.TestCase):
#patch('builtins.input', side_effect=["bow", "arrow","exit"])
#patch('sys.stdout', new_callable=StringIO)
def run_test_with_stdout_capture(self , mock_output, mock_input ):
main()
return mock_output.getvalue()
def test( self ):
print ("GOT: + " + self.run_test_with_stdout_capture())
if __name__ == "__main__":
unittest.main()
Do note that you cannot print inside the #patch sys.stdout -- it will get captured!

How to run bottle and a concurrent function?

I have a web server which creates a file upon being called. I would like to add somewhere a function, run concurently, which would check this file and act upon its contents but I do not know where to place it in the code. The code for the web server:
import bottle
import pickle
import time
class WebServer(object):
def __init__(self):
bottle.route("/", 'GET', self.root)
bottle.run(host='0.0.0.0', debug=True)
def root(self):
with open("watchdog.txt", "wb") as f:
pickle.dump(time.time(), f)
if __name__ == "__main__":
WebServer()
The function I would like to run together with the web server:
def check():
with open("watchdog.txt", "rb") as f:
t1 = pickle.load(f)
t2 = time.time()
if t2 - t1 > 10:
print("stale watchdog")
The call to WebServer() puts the program into a loop (which is OK, the web server is listening) so I would like to put check() somewhere where it could be combined with a callback (akin to self.root.after() in Tkinter). How to best do this?
NB: I omitted in the code above error checking, accounting for missing watchdog.txt, etc. for the sake of simplicity.
One solution I finally found is to use the Event Scheduler:
import bottle
import pickle
import time
import threading
class WebServer(object):
def __init__(self):
bottle.route("/", 'GET', self.root)
bottle.run(host='0.0.0.0', debug=True)
def root(self):
with open("watchdog.txt", "wb") as f:
pickle.dump(time.time(), f)
def check():
try:
with open("watchdog.txt", "rb") as f:
t1 = pickle.load(f)
except IOError:
pass
else:
t2 = time.time()
if t2 - t1 > 10:
print("stale watchdog")
else:
print("fresh watchdog")
finally:
threading.Timer(10, check).start()
if __name__ == "__main__":
check()
WebServer()

Categories