simple function statement is not giving any output - python-3.x

Tried to write a simple function in python version 3.7 system is neither giving any error nor it is giving any output.
def say_hello():
print('Hello user')
say_hello()

Python uses indentation for a code block (body of a function, loop etc.) i.e it starts with indentation and ends with the first unindented line.
So your method invocation was inside the method definition because of that it didn't even printed any output below code will fix your problem.
def say_hello():
print('Hello User')
say_hello()

Related

Except python does not catch Windows error FileNotFoundError | "The system cannot find the specified path." [duplicate]

I have this python code:
import os
try:
os.system('wrongcommand')
except:
print("command does not work")
The code prints:
wrongcommand: command not found
Instead of command does not work. Does anyone know why it's not printing my error message?
If you want to have an exception thrown when the command doesn't exist, you should use subprocess:
import subprocess
try:
subprocess.run(['wrongcommand'], check = True)
except subprocess.CalledProcessError:
print ('wrongcommand does not exist')
Come to think of it, you should probably use subprocess instead of os.system anyway ...
Because os.system() indicates a failure through the exit code of the method
return value == 0 -> everything ok
return value != 0 -> some error
The exit code of the called command is directly passed back to Python.
There is documentation telling you that os.system() would raise an exeption in case of a failure. os.system() just calls the underlaying system() call of the OS and returns its return value.
Please read the os.system() documentation carefully.
Although subprocess might be your best friend. os.system is still useful in somewhere, especially to the programmer play C/C++ mode.
Hence, the code will be below.
import os
try:
os_cmd = 'wrongcommand'
if os.system(os_cmd) != 0:
raise Exception('wrongcommand does not exist')
except:
print("command does not work")
There are two problems in your code snippet. First of all, never just do try: ... except:, always be specific about which exception you want to handle. Otherwise, your program simply swallows any kind of error, also those that you do not expect. In most cases, this will lead to unexpected behavior at some other point during runtime.
Furthermore, os.system() calls should most of the time be replaced by their counterparts from the subprocess module.
To see what goes wrong, leave out the try/except block and actually look at the traceback/exception. As others have pointed out, you will notice that there is no exception in your case which is why your custom string is not printed.
Bottom line: think about which specific exceptions can occur in your code block. Think hard about which of them you expect to happen for certain reasons and handle those appropriately. Do not handle those that you do not expect.
wrongcommand: command not found is the output of the shell os.system is using to invoke the command. os.system did not throw an exception
EDIT: edited by copy-and-pasting part of mgilson's comment
There is one more easiest ways is:
import os
def dat():
if os.system('date') == 0:
print("Command successfully executed")
else:
print("Command failed to execute")
dat()

Missing module docstring (missing-module-docstring)

I am running below the addition of two numbers in jupyter
'''
This program `summationoftwonumbers` and displays their results
'''
A = 1
B = 5
print('Sum of Numbers:',A+B)
It is running fine giving an output as "Sum of Numbers: 6"
But when running a file by using PyLint, summationoftwonumber.ipynb gives the below errors.
summationoftwonumbers.ipynb:1:0: C0114: Missing module docstring (missing-module-docstring)
summationoftwonumbers.ipynb:1:0: W0104: Statement seems to have no effect (pointless-statement)
I do not understand why this is happening.
It's that you used quotes to write a comment, which in some cases creates a docstring. Python is warning you that the statement has no effect in your program. To get rid of the warning you could rewrite the line:
''' This program summationoftwonumbers and displays their results '''
as a normal comment:
# This program summationoftwonumbers and displays their results

How do I pass through or wrap the print command(stdout) so that print also calls a function every call?

I am trying to automating a long running job, and I want to be able to upload all console outputs to another log like on CloudWatch Logs. For the most part this can be done by making and using a custom function instead of print. But there are functions in MachineLearning like Model.summary() or progress bars while training that outputs to stdout on their own.
I can get all get all console outputs at the very end, via an internal console log. But what I need is real-time uploading of stdout as its called by whomever. So that one can check the progress by taking a look at the logs on Cloudwatch instead of having to log into the machine and check the internal console logs.
Basically what I need is:
From: call_to_stdout -> Console(and probably other stuff)
To: call_to_stdout -> uploadLog() -> Console(and probably other stuff)
pseudocode of what I need
class stdout_PassThru:
def __init__(self, in_old_stdout):
self.old_stdout = in_old_stdout
def write(self, msg):
self.old_stdout.write(msg)
uploadLogToCloudwatch(msg)
def uploadLogToCloudwatch(msg):
# Botocore stuff to upload to Cloudwatch
myPassThru = stdout_PassThru(sys.stdout)
sys.stdout = myPassThru
I've tried googling this, but the best I ever get is stringIO stuff, where I can capture stdout, but I cannot do anything with it until the function I called ends and I can insert code again. I would like to run my upload Log code everytime stdout is used.
Is this even possible?
Please and thank you.
EDIT: Someone suggested redirect/output to file. The problem is that, that just streams/writes to the file as things are outputted. I need to call a function that does work on each call to stdout, which is not a stream. If stdout outputs everytime it flushes itself, then having the function call then would be good too.
I solved my problem. Sort of hidden in some other answers.
The initial problem I had with this solution is that when it is tested within a Jupyter Notebook, the sys.stdout = myClass(sys.stdout) causes Jupyter to... wait? Not sure but it never finishes processing the paragraph.
But when I put it into a python file and ran with python test.py it ran perfectly and as expected.
This allows me to in a sense pass thru calls to print, while executing my own function every call to print.
def addLog(message):
# my boto function to upload Cloudwatch logs
class sendToLog:
def __init__(self, stream):
self.stream = stream
def write(self, o):
self.stream.write(o)
addLog(o)
self.stream.flush()
def writelines(self, o):
self.stream.writelines(o)
addLog(o)
self.stream.flush()
def __getattr__(self, attr):
return getattr(self.stream, attr)
sys.stdout = sendToLog(sys.stdout)

Correct usage of assertRaises in Python unit tests

I'm trying to figure out how to correctly use assertRaises() in Python unit testing. I have a ValueError in my function that gets raised. However, when testing in my unit tests, I'm getting mixed results with two different ways of using `assertRaises().
When I write the test like this, it works:
import unittest
class MyTest(unittest.TestCase):
#classmethod
def setUpClass(cls):
pass
def test_error(self):
with self.assertRaises(ValueError):
func(a)
However, if I write my test like below, it does not work even though the ValueError gets raised:
def test_error(self):
self.assertRaises(ValueError, func(a))
Does anyone have any insight as to why one way would work and the other wouldn't?
The asserRaises method takes a variable argument list, where the first argument is the function object, and the optional other arguments are the function arguments. You have to call it either this way (the usual way):
def test_error(self):
self.assertRaises(ValueError, func, a)
Or using a lambda:
def test_error(self):
self.assertRaises(ValueError, lambda: func(a))
The problem with your call is that it would execute your function before calling assertRaises, as the result of the function call instead of the function itself is passed as an argument - so the exception would occur before assertRaises could handle it.
Having said that, I would always prefer the context manager variant, as it is better readable.

How to redirect the stdout of a multiprocessing.Process

I'm using Python 3.7.4 and I have created two functions, the first one executes a callable using multiprocessing.Process and the second one just prints "Hello World". Everything seems to work fine until I try redirecting the stdout, doing so prevents me from getting any printed values during the process execution. I have simplified the example to the maximum and this is the current code I have of the problem.
These are my functions:
import io
import multiprocessing
from contextlib import redirect_stdout
def call_function(func: callable):
queue = multiprocessing.Queue()
process = multiprocessing.Process(target=lambda:queue.put(func()))
process.start()
while True:
if not queue.empty():
return queue.get()
def print_hello_world():
print("Hello World")
This works:
call_function(print_hello_world)
The previous code works and successfully prints "Hello World"
This does not work:
with redirect_stdout(io.StringIO()) as out:
call_function(print_hello_world)
print(out.getvalue())
With the previous code I do not get anything printed in the console.
Any suggestion would be very much appreciated. I have been able to narrow the problem to this point and I think is related to the process ending after the io.StringIO() is already closed but I have no idea how to test my hypothesis and even less how to implement a solution.
This is the workaround I found. It seems that if I use a file instead of a StringIO object I can get the things to work.
with open("./tmp_stdout.txt", "w") as tmp_stdout_file:
with redirect_stdout(tmp_stdout_file):
call_function(print_hello_world)
stdout_str = ""
for line in tmp_stdout_file.readlines():
stdout_str += line
stdout_str = stdout_str.strip()
print(stdout_str) # This variable will have the captured stdout of the process
Another thing that might be important to know is that the multiprocessing library buffers the stdout, meaning that the prints only get displayed after the function has executed/failed, to solve this you can force the stdout to flush when needed within the function that is being called, in this case, would be inside print_hello_world (I actually had to do this for a daemon process that needed to be terminated if it ran for more than a specified time)
sys.stdout.flush() # This will force the stdout to be printed

Resources