Just in recent times I went through one of my code (in Python) in which guard evaluation was badly missed. I shortened my code to make it a brief one
>>> x = 4
>>> y = 0
>>> x >= 1 and (x/y) > 2
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
x >= 2 and (x/y) > 2
ZeroDivisionError: integer division or modulo by zero
here we need to add guard
>>> x >= 1 and y != 0 and (x/y) > 2 # y!=0 is a guard
False
Now I have two questions:
I believe similar kind of scenario could have been best caught with
C++, as it compiles the code and will produce a warning at first. Let
me know if I am wrong here?
Other question is that we use py_compile.compile('file_name') and it
just verifies syntax. Don't we have any module in Python that can catch
these kind of misses?
Since python is a loosely typed language, thus it become difficult(impossible i believe) to analyze the code for the variable types. We can use pep8 or pylint to analyze the code. They can only inform us about the indenting and code writing as per PEP.
For below file guard_eval.py
sherry#Sherry-Linux:~$ cat guard_eval.py
x=6
y=0
if x >= 1 and (x/y) > 2:
print True
else:
print False
sherry#Sherry-Linux:~$ pep8 guard_eval.py
guard_eval.py:1:2: E225 missing whitespace around operator
guard_eval.py:2:2: E225 missing whitespace around operator
guard_eval.py:4:1: W191 indentation contains tabs
guard_eval.py:6:1: W191 indentation contains tabs
pylint provides code ratings as well :)
But in case of C++ we can modify the compiler to analyze code with the variable type and hint user to have guard expression for integer/integer division while compiling.
Related
I'm new to coding and python so i'm doing an online free course. There's one task that i'm supposed to do that is not working properly, and apparently the problem is identation. Here's the code:
c = 0
while c < 5:
c += 1
if c == 3:
continue
print (c)
So the last line is aligned with the previous one, and the code only runs properly after I delete one identation from the last line. How do I configure this to be automatic so I won't have to delete it all the time?
TLDR: In general, no, you cannot configure this automatically. However, there are some specific cases where we can say a statement is definitely in the wrong scope with the help of a linter. The onus is still on the programmer to actually correct the program, though, even with the help of the linter.
General Case:
No programming language can know what scope you'd like a statement to be in. That is for you, the programmer, to express in the language. Python's scoping happens to be determined by whitespace, not curly braces, like in some other popular languages (namely C/C++/Java/Perl).
Consider:
if x:
do_y()
do_z()
vs.
if x:
do_y()
do_z()
Both are legal Python programs, and both are (potentially) logically correct, depending on the application. Maybe you only want to call do_z() if x is true (first example). Or maybe you always want to call do_z() regardless of x (second example). Only the application developer can decide which they want. And which one you want might actually change over time, depending on circumstance. So it should be very clear that this decision (in general) cannot be made automatically.
Using pylint:
However, sometimes what we can say is that some statement is definitely in the wrong scope (like in your example above, a statement immediately after a continue can never be reached).
You can use a linter (like pylint) to help with this:
In test.py I've placed your question code and gave it a quick pylint:
(so) URSA-MattM-MacBook:stackoverflow mmessersmith$ cat test.py
c = 0
while c < 5:
c += 1
if c == 3:
continue
print(c)
(so) URSA-MattM-MacBook:stackoverflow mmessersmith$ pylint test.py
************* Module test
test.py:1:0: C0111: Missing module docstring (missing-docstring)
test.py:1:0: C0103: Constant name "c" doesn't conform to UPPER_CASE naming style (invalid-name)
test.py:6:8: W0101: Unreachable code (unreachable)
------------------------------------------------------------------
Your code has been rated at 5.00/10 (previous run: 5.00/10, +0.00)
Note that this line: test.py:6:8: W0101: Unreachable code (unreachable). That's telling you that line 6 can never be executed, regardless of program state.
Furthermore, note that any linter still cannot automatically correct indent. There are two legal possibilities for where the print(c) statement should be indented:
c = 0
while c < 5:
c += 1
if c == 3:
continue
print (c)
and
c = 0
while c < 5:
c += 1
if c == 3:
continue
print (c)
Both are legal (and reasonable) Python programs! The first will print c in every iteration of the while loop, the second will only print c after the loop has finished. Only you, the programmer, can decide which one you'd like. All the linter can say is "you almost certainly didn't mean to put a statement immediately after a continue, since that code will never be executed".
Again, it is up to you where you'd like the statement. No automated tool can automatically place the statement for you, because it can't possibly know what you want to accomplish.
In your code, print(c) is after continue. But statements after continue is not executed. continue works as ignore the statements after it and go for the next iteration. So print(c) doesn't work. Your code should be like this :-
c = 0
while c < 5:
c += 1
if c == 3:
continue
print (c)
This will print
1
2
4
5
I have to edit a python file such that after every if condition, i need to add a line which says
if condition_check:
if self.debug == 1: print "COVERAGE CONDITION #8.3 True (condition_check)"
#some other code
else:
if self.debug == 1: print "COVERAGE CONDITION #8.4 False (condition_check)"
#some other code
The number 8.4(generally y.x) refer to the fact that this if condition is in function number 8(y) (the functions are just sequentially numbers, nothing special about 8) and x is xth if condition in yth function.
and of course, the line that will be added will have to be added with proper indentation. The condition_check is the condition being checked.
For example:
if (self.order_in_cb):
self.ccu_process_crossing_buffer_order()
becomes:
if (self.order_in_cb):
if self.debug == 1: print "COVERAGE CONDITION #8.2 TRUE (self.order_in_cb)"
self.ccu_process_crossing_buffer_order()
How do i achieve this?
EXTRA BACKGROUND:
I have about 1200 lines of python code with about 180 if conditions - i need to see if every if condition is hit during the execution of 47 test cases.
In other words i need to do code coverage. The complication is - i am working with cocotb stimulus for RTL verification. As a result, there is no direct way to drive the stimulus, so i dont see an easy way to use the standard coverage.py way to test coverage.
Is there a way to check the coverage so other way? I feel i am missing something.
If you truly can't use coverage.py, then I would write a helper function that used inspect.stack to find the caller, then linecache to read the line of source, and log that way. Then you only have to change if something: to if condition(something): throughout your file, which should be fairly easy.
Here's a proof of concept:
import inspect
import linecache
import re
debug = True
def condition(label, cond):
if debug:
caller = inspect.stack()[1]
line = linecache.getline(caller.filename, caller.lineno)
condcode = re.search(r"if condition\(.*?,(.*)\):", line).group(1)
print("CONDITION {}: {}".format(label, condcode))
return cond
x = 1
y = 1
if condition(1.1, x + y == 2):
print("it's two!")
This prints:
CONDITION 1.1: x + y == 2
it's two!
I have about 1200 lines of python code with about 180 if conditions - i need to see if every if condition is hit during the execution of 47 test cases. In other words i need to do code coverage. The complication is - i am working with cocotb stimulus for RTL verification.
Cocotb has support for coverage built in (docs)
export COVERAGE=1
# run cocotb however you currently invoke it
I am 12 years old and working on my science fair project. 1000s of packages are stolen everyday so for my science fair project I am building a thing that goes on peoples porches. It detects a package and when the package is taken off without verification it beeps very loudly and takes a picture of the thief. I am writing the code in python 3 on my raspberry pi. I have never coded in python before but I know c and html and css. I haven't added the verification part yet but that will be somewhere in the code eventually and it will change the pin value to 0 or 1 if PIN is entered. **My code is giving me this error:
if pin == 1
^
SyntaxError: invalid syntax**
from Bluetin_Echo import Echo
import RPi.GPIO as GPIO
import time
import nexmo
import picamera
GPIO.setup(40,GPIO.OUT)
pin = 1
TRIGGER_PIN = 38
ECHO_PIN = 36
result = echo.read('in')
alarm = 40
speed_of_sound = 315
echo = Echo(TRIGGER_PIN, ECHO_PIN, speed_of_sound)
if pin == 1
if result < '5'
if result >= '10'
GPIO.output(14, 1)
<code>
In Python, since there are no brackets when declaring a block, we rely on indentation and punctuation. The : symbol is used to start an indent suite of statements in case of if, while, for, def and class statements.
if expression:
# something
pass
while expression:
# something
pass
for x in sequence:
# something
pass
def fct():
# something
pass
(pass is a null operation, it does nothing; useful in places where your code will eventually go, but has not been written yet)
So, your code should actually be:
if pin == 1:
if result < '5':
if result >= '10':
GPIO.output(14, 1)
Also, take care that:
You are comparing result with '5' and '10' as strings, not as numbers; I'm not saying this is really a mistake, but are you sure these should't be numbers?
You'll never reach the line with GPIO.output(14, 1). You check the result to be less than 5, but later, bigger than 10, which is impossible.
Since you are a beginner with Python, I recommend you to search in the documentation the things you struggle with. There are also nice tutorials on Python on different websites such CodeAcademy or w3schools.
I also recommend you to use an IDE for your projects, one that supports Python. Most of the time, they will point out the syntax errors you make before executing the code. I'm using Pycharm for my projects (you can download the Community version for free). You can also set up Sublime Text 3, Atom, Visual Code or Notepad++ with the appropriate plugins to help you.
Good luck with your project!
Occasionally I will handle some condition that I'm fairly certain would be an edge case, but I can't think of an example where it would come up, so I can't come up with a test case for it. I'm wondering if there's a way to add a pragma to my code such that if, in the future some change in the tests accidentally starts covering this line, I'd would be alerted to this fact (since such accidental coverage will produce the needed test case, but possibly as an implementation detail, leaving the coverage of this line fragile). I've come up with a contrived example of this:
In mysquare.py:
def mysquare(x):
ov = x * x
if abs(ov) != ov or type(abs(ov)) != type(ov):
# Always want this to be positive, though why would this ever fail?!
ov = abs(ov) # pragma: nocover
return ov
Then in my test suite I start with:
from hypothesis import given
from hypothesis.strategies import one_of, integers, floats
from mysquare import mysquare
NUMBERS = one_of(integers(), floats()).filter(lambda x: x == x)
#given(NUMBERS)
def test_mysquare(x):
assert mysquare(x) == abs(x * x)
#given(NUMBERS)
def test_mysquare_positive(x):
assert mysquare(x) == abs(mysquare(x))
The nocover line is never hit, but that's only because I can't think of a way to reach it! However, at some time in the far future, I decide that mysquare should also support complex numbers, so I change NUMBERS:
NUMBERS = one_of(integers(), floats(),
complex_numbers()).filter(lambda x: x == x)
Now I'm suddenly unexpectedly covering the line, but I'm not alerted this fact. Is there something like nocover that works more like pytest.xfail - as a positive assertion that that particular line is covered by no tests? Preferably compatible with pytest.
Coverage.py doesn't yet have this feature, but it's an interesting one: A warning that a line marked as not covered, was actually covered. As a difficult hack, you could do something like disable your nocover pragma, and collect the lines covered, and compare them to the line numbers with the pragma.... Ick.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 13 years ago.
I just completed a program that should (hopefully) play a GUI Tetris program. I've cleaned up all the syntax errors, but now when I double-click, or go through the Command Prompt to run the program a DOS window pops up for less than a second and disappears without ever running the program.
What's going on?
Heres a link to the code at codepad.org
http://codepad.org/tq4et1rO
Wow, there's really a huge number of errors in your code. I started running it under pdb, identifying and fixing them one by one, but after 20 or so I gave up. What I fixed so far (in diff's output, lines start with < to mean they're in your version, or with > to mean they're in my partially fixed version). Note the variety: you often write Flase instead of False, use wrong capitalization, use - (minus) instead of = (equals), misspell variables (e.g. Boardd instead of Board, even instead of event), rnage instead of range, and so on, and so forth.
37c37
< self.isStarted = Flase
---
> self.isStarted = False
63c63
< self.isWaitingAfterLine - Flase
---
> self.isWaitingAfterLine = False
87c87
< for i in range(Board.BoardHeight * Board.Boardwidth):
---
> for i in range(Board.BoardHeight * Board.BoardWidth):
135c135
< if even.GetId() == Boardd.ID_TIMER:
---
> if event.GetId() == Board.ID_TIMER:
205c205
< self.curY = Board.Height - 1 + self.curPiece.minY()
---
> self.curY = Board.BoardHeight - 1 + self.curPiece.minY()
214c214
< for i in rnage(4):
---
> for i in range(4):
217c217
< if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.Boardheight:
---
> if x < 0 or x >= Board.BoardWidth or y < 0 or y >= Board.BoardHeight:
278c278
< self.coords = [[0, 0] for i in rnage(4)]
---
> self.coords = [[0, 0] for i in range(4)]
356c356,357
< Tetris(None, -1, 'Tetris')
---
> tetris = Tetris(None, -1, 'Tetris')
> app.SetTopWindow(tetris)
After all these fixes, I've stopped upon spotting one more typo (you def sqaureHeight when you clearly mean squareHeight) -- I have no idea how many typos and other mistakes are still hiding in these 360 lines of code... A density of more such bugs than 1/10th of the lines is plenty high enough for me.
I heartily recommend that you start with much less ambitious projects and teach yourself to carefully "copyedit" your code for these typos you appear to be so prone to: it's possible to be dyslexic and an excellent programmer at the same time, but it does take extra effort and diligence on your part. Tools such as pylint may also help a little, although they do have limits.
Edit: as it turns out, after fixing a couple of occurences of sqaure into square, the program does run -- and immediately shows an empty window saying "Game Over" and gets to the raw_input prompt you have as your very last line. So beyond the many typos there must be one or more nasty logic-level bugs as well. I repeat the entreaty to start with something much, much simpler in your first forays into programming.
Running your script actually does produce a traceback:
Traceback (most recent call last):
File "tetris.py", line 356, in <module>
Tetris(None, -1, 'Tetris')
File "tetris.py", line 10, in __init__
self.statusbar - self.CreateStatusBar()
AttributeError: 'Tetris' object has no attribute 'statusbar'
Your script has an error on line 10:
self.statusbar - self.CreateStatusBar()
You mean to be assigning there, not subtracting from an attribute that does not yet exist.
An error occurred. Unfortunately, the DOS window closed (because the Python program ended) and you didn't get to see the actual error. Start a DOS window yourself (start -> run -> 'cmd') and run the program from there. That will show you the traceback.
The DOS window pops up because you are using the wrong python binary (python.exe instead of pythonw.exe?)
It does not show anything because, there is a bug in you program. If there is no stack trace I guess you forgot to enter the main loop. Try posting some code.
Traceback (most recent call last):
Line 3, in <module>
import wx
ImportError: No module named wx
You need to install wxPython
You may want to change (at the bottom of your script)
app = wx.App()
to
app = wx.App(redirect=False)
Otherwise the segmentation faults that happen as wxPython is starting up won't be printed to the console, and can be a nightmare to track down.