This is my program and I am getting the following mentioned error:
def main():
print "hello"
if __name__=='__main__':
main()
Error
File "hello.py", line 8
main()
^
IndentationError: expected an indented block
Your indentation is off. Try this :
def main():
print "hello"
if __name__=='__main__':
main()
All function blocks, as well as if-else, looping blocks have to be indented by a tab or 4 spaces (depending on environment).
if condition :
statements //Look at the indentation here
...
Out-of-block //And here
Refer to this for some explanation.
Normal Code
Indent block
Indent block
Indent block 2
Indent block 2
You should do:
def main():
print "hello"
if __name__=='__main__':
main()
It can be either spaces or tabs.
Also, the indentation does NOT need to be same across the file, but only for each block.
For example, you can have a working file like this, but NOT recommended.
print "hello"
if True:
[TAB]print "a"
[TAB]i = 0
[TAB]if i == 0:
[TAB][SPACE][SPACE]print "b"
[TAB][SPACE][SPACE]j = i + 1
[TAB][SPACE][SPACE]if j == 1:
[TAB][SPACE][SPACE][TAB][TAB]print "c
Your code should look like:
def main():
print "hello"
if __name__=='__main__':
main()
You probably want something like:
def main():
print "hello"
if __name__=='__main__':
main()
Pay attention to the indentations. Leading whitespace at the beginning of a line determines the indentation level of the line, which then is used to determine the grouping of statements in Python.
Just sharing this stupidity. I had a very similar error IndentationError: expected an indented block def main() since I had commented out the whole body of a previous "some_function".
def some_function():
# some_code
# return
def main():
print "hello"
if __name__=='__main__':
main()
Related
I've written simple code to handle just one case and correct the indentation (again simple and it relies on the user taking caution while using it) of a string containing a Python function declared using the def keyword and execute it.
def fix_index(string):
i=0;
t=string.find("def")+3;
string=string.replace(string[string.find("def"):t], "#")
while string.find(" ") != -1:
string = string.replace(" ", "")
i += 1
l=list(string);l[string.find(":")-i+2]+="$$$$"
return "".join(l).replace("$$$$", " ").replace("#", "def ").lstrip();
def switch(exp):
def exec(obj):
items = obj.items();
for k, v in items:
if(k==exp):
print(fix_index(v))
return eval(fix_index(v))();
return {"case":exec};
bread = "bread"
switch(bread)["case"]({
"cheese":
"""
def a():
print("cheese");
""",
"bread":
"""
def b():
print("bread");
"""
})
the output for the formatted function string:
C:\Users\User>python -u "c:\Users\User\folder\switch.py"
def b():
print("bread");
the error I'm getting:
Traceback (most recent call last):
File "c:\Users\User\folder\switch.py", line 27, in <module>
switch(bread)["case"]({
File "c:\Users\User\folder\switch.py", line 21, in exec
return eval(fix_index(v))();
File "<string>", line 1
def b():
^
SyntaxError: invalid syntax
I've also just realized I didn't name the function what I indented intended to (should've posted this when awake to avoid accidental pun).
Anyways what I fail to understand is what part in my produced string exactly contains "invalid syntax".
I'll appreciate any help.
if what you are looking for is to reproduce a switch statement, you can do it with the following function:
def switch(v): yield lambda *c: v in c
It simulates a switch statement using a single pass for loop with if/elif/else conditions that don't repeat the switching value:
for example:
for case in switch(x):
if case(3):
# ... do something
elif case(4,5,6):
# ... do something else
else:
# ... do some other thing
It can also be used in a more C style:
for case in switch(x):
if case(3):
# ... do something
break
if case(4,5,6):
# ... do something else
break
else:
# ... do some other thing
For your example, it could look like this:
meal = "bread"
for case in switch(meal):
if case("cheese"):
print("Cheese!")
elif case("bread"):
print("Bread!")
or this:
meal = "bread"
for case in switch(meal):
if case("cheese"):
print("Cheese!")
break
if case("bread"):
print("Bread!")
break
When there is a print statement inside a function, it is not printing.
I dont understand what is going wrong.
def test():
print("please print this")
return "return this"
And, my main function is like this:
if __name__ == "__main__":
classwhereiwrotefunction.test()
When I use a debugger, and try to store the return value in a variable, it does show the value. But, does not print it.
the problem is with indentation I guess. Try the below code it will work.
class Class_name:
def test(self):
print("please print this")
return "return this"
if __name__ == "__main__":
class_name = Class_name()
print(class_name.test())
>> please print this
>> return this
I have a python function that runs other functions.
def main():
func1(a,b)
func2(*args,*kwargs)
func3()
Now I want to apply exceptions on main function. If there was an exception in any of the functions inside main, the function should not stop but continue executing next line. In other words, I want the below functionality
def main():
try:
func1()
except:
pass
try:
func2()
except:
pass
try:
func3()
except:
pass
So is there any way to loop through each statement inside main function and apply exceptions on each line.
for line in main_function:
try:
line
except:
pass
I just don't want to write exceptions inside the main function.
Note : How to prevent try catching every possible line in python? this question comes close to solving this problem, but I can't figure out how to loop through lines in a function.
If you have any other way to do this other than looping, that would help too.
What you want is on option that exists in some languages where an exception handler can choose to proceed on next exception. This used to lead to poor code and AFAIK has never been implemented in Python. The rationale behind is that you must explicitely say how you want to process an exception and where you want to continue.
In your case, assuming that you have a function called main that only calls other function and is generated automatically, my advice would be to post process it between its generation and its execution. The inspect module can even allow to do it at run time:
def filter_exc(func):
src = inspect.getsource(func)
lines = src.split('\n')
out = lines[0] + "\n"
for line in lines[1:]:
m = re.match('(\s*)(.*)', line)
lead, text = m.groups()
# ignore comments and empty lines
if not (text.startswith('#') or text.strip() == ""):
out += lead + "try:\n"
out += lead + " " + text + "\n"
out += lead + "except:\n" + lead + " pass\n"
return out
You can then use the evil exec (the input in only the source from your function):
exec(filter_exc(main)) # replaces main with the filtered version
main() # will ignore exceptions
After your comment, you want a more robust solution that can cope with multi line statements and comments. In that case, you need to actually parse the source and modify the parsed tree. ast module to the rescue:
class ExceptFilter(ast.NodeTransformer):
def visit_Expr(self, node):
self.generic_visit(node)
if isinstance(node.value, ast.Call): # filter all function calls
# print(node.value.func.id)
# use a dummy try block
n = ast.parse("""try:
f()
except:
pass""").body[0]
n.body[0] = node # make the try call the real function
return n # and use it
return node # keep other nodes unchanged
With that example code:
def func1():
print('foo')
def func2():
raise Exception("Test")
def func3(x):
print("f3", x)
def main():
func1()
# this is a comment
a = 1
if a == 1: # this is a multi line statement
func2()
func3("bar")
we get:
>>> node = ast.parse(inspect.getsource(main))
>>> exec(compile(ExceptFilter().visit(node), "", mode="exec"))
>>> main()
foo
f3 bar
In that case, the unparsed node(*) write as:
def main():
try:
func1()
except:
pass
a = 1
if (a == 1):
try:
func2()
except:
pass
try:
func3('bar')
except:
pass
Alternatively it is also possible to wrap every top level expression:
>>> node = ast.parse(inspect.getsource(main))
>>> for i in range(len(node.body[0].body)): # process top level expressions
n = ast.parse("""try:
f()
except:
pass""").body[0]
n.body[0] = node.body[0].body[i]
node.body[0].body[i] = n
>>> exec(compile(node, "", mode="exec"))
>>> main()
foo
f3 bar
Here the unparsed tree writes:
def main():
try:
func1()
except:
pass
try:
a = 1
except:
pass
try:
if (a == 1):
func2()
except:
pass
try:
func3('bar')
except:
pass
BEWARE: there is an interesting corner case if you use exec(compile(... in a function. By default exec(code) is exec(code, globals(), locals()). At top level, local and global dictionary is the same dictionary, so the top level function is correctly replaced. But if you do the same in a function, you only create a local function with the same name that can only be called from the function (it will go out of scope when the function will return) as locals()['main'](). So you must either alter the global function by passing explicitely the global dictionary:
exec(compile(ExceptFilter().visit(node), "", mode="exec"), globals(), globals())
or return the modified function without altering the original one:
def myfun():
# print(main)
node = ast.parse(inspect.getsource(main))
exec(compile(ExceptFilter().visit(node), "", mode="exec"))
# print(main, locals()['main'], globals()['main'])
return locals()['main']
>>> m2 = myfun()
>>> m2()
foo
f3 bar
(*) Python 3.6 contains an unparser in Tools/parser, but a simpler to use version exists in pypi
You could use a callback, like this:
def main(list_of_funcs):
for func in list_of_funcs:
try:
func()
except Exception as e:
print(e)
if __name__ == "__main__":
main([func1, func2, func3])
I was taking my course at codeacademy until something went wrong and couldn't proceed, a little help please :( here is my code
def by_three(num):
if num%3 == 0:
def cube(num):
else:
print "False"
def cube(num):
return num**3
by_three(9)
I get...
File "<stdin>", line 4
else:
^
IndentationError: expected an indented block
Unknown error.
I will really appreciate your help people!!
You probably wanted to call (use) the function cube() instead of defining it (in your by_three() function definition), so your corrected code will be:
def by_three(num):
if num%3 == 0:
print cube(num) # Instead of your original "def cube(num):"
else:
print "False"
def cube(num):
return num**3
by_three(9)
On line 3 def cube(num): you have an extra def and :. Remove those
When defining a function you need def and colon, where as for calling it you don't need one. The correct code
def by_three(num):
if num%3 == 0:
cube(num)
else:
print "False"
def cube(num):
return num**3
by_three(9)
Is it possible to determine the level of indentation of a line in Python while the program is running? I want to be able to organize a log file according to an outline structure of the script that is being run.
In the following example, the 'first message' function would yield 0, 'second message' would be 1, 'third message' 2 and 'fourth, fifth, sixth' message would be 0
logger.debug('First message')
if True:
logger.info('Second message')
if True:
logger.info('Third message')
logger.warning('Fourth message')
logger.error('Fifth message')
logger.critical('Sixth message')
The corresponding log file would look something like this:
First message
Second message
Third message
Fourth message
Fifth message
Sixth message
I was able to determine the indentation level using the inspect.getouterframes() function. This assumes that 4 ' ' characters are used instead of '\t' characters for indentation.
import inspect
def getIndentationLevel():
# get information about the previous stack frame
frame, filename, line_number,function_name, lines, index = inspect.getouterframes(inspect.currentframe())[1]
# count the number of characters in the line
original_length = len(lines[0])
# trim the line of left spaces and record the new length
new_length = len(lines[0].lstrip())
# take the difference between the two values and divide by 4 to get the level number
return int((original_length - new_length) / 4)
First, I retrieve the code context of the caller:
import inspect
context = inspect.getframeinfo(frame.f_back).code_context
This gives me a list of code lines; I ignore all but the first of those lines. Then I use a regular expression to get the whitespace at the start of this line; if you are using tabs, you have to replace them with the appropriate amount of spaces first:
import re
indent = re.compile("^ *")
firstline = context[0]
firstline = firstline.replace("\t", " ")
match = indent.match(firstline)
For testing purposes, I replace the spaces with dots, so I can see what's going on, and construct my prefix:
white = "." * match.span(0)[1] # Change "." to " "!
Now I can use this to modify my message msg I sent to my logger:
do_some_logging(white + msg)
It would be nice if I could simply wrap an existing logger with a decorator that turns this logger into a whitespace-aware logger. Suppose I have, for testing purposes, a really primitive logger that simply prints messages to stdout:
def pseudo_logger(msg):
"""Pseudo-logging function."""
print(msg)
This logger has a first parameter for the logging message, and potentially some other positional parameters and keywords. I want to write a decorater for such a function:
from functools import wraps
def indented(func):
"""Turns the logger func(msg) into an indented logger."""
#wraps(func)
def wrapped(msg, *args, **kwargs):
# ... compute white ...
func(white + msg, *args, **kwargs)
return wrapped
Now I can get a new logger as, for example:
new_logger = intented(pseudo_logger)
Putting it all together gives:
from functools import wraps
import inspect
import re
def indented(func):
"""Turns the logger func(msg) into an indented logger."""
indent = re.compile("^ *")
#wraps(func)
def wrapped(msg, *args, **kwargs):
frame = inspect.currentframe()
context = inspect.getframeinfo(frame.f_back).code_context
firstline = context[0]
match = indent.match(firstline)
white = "." * match.span(0)[1] # Change "." to " "!
func(white + msg, *args, **kwargs)
return wrapped
#indented
def pseudo_logger(msg):
"""Pseudo-logging function."""
print(msg)
def main():
pseudo_logger("This is an indented message!")
if True:
pseudo_logger("Another message, but more indented!")
pseudo_logger("This "
"will ignore the indention of the second "
"or third line.")
if __name__ == "__main__":
main()
I would be hesitant to use this in production code, though. Using code inspection like this is brittle, and depending on where you call this, it might lead to unexpected effects.