NoneType in MU5 on BBC Microbit - bbc-microbit

I have some code for a simple rev counter on the Microbit. When returning the variable rev_per_second, sometimes it is a NoneType (for reasons unknown). I try to trap this within the function, but it doesn't seem to work. Where am I going wrong please.
# part of the function revs()
if end_time < running_time():
try:
rev_per_second = rev_per_second
except TypeError:
rev_per_second = 1
return rev_per_second # make this value available to the main program
# main part of the program
while True:
rev_per_min = revs() # sometimes this is "None" Why??
display.scroll(str(rev_per_min))

The explanation is almost certainly that there is a path through the function that does not end in a return statement, so Python by default returns None.
Check that all paths from your revs() function end at a return statement, otherwise Python will return None if there is no return statement.

Related

Can anyone tell me what's wrong with my code (I am a newbie in programming, pls do cooperate )

I am trying to write a code which calculates the HCF of two numbers but I am either getting a error or an empty list as my answer
I was expecting the HCF, My idea was to get the factors of the 2 given numbers and then find the common amongst them then take the max out of that
For future reference, do not attach screenshots. Instead, copy your code and put it into a code block because stack overflow supports code blocks. To start a code block, write three tildes like ``` and to end it write three more tildes to close. If you add a language name like python, or javascript after the first three tildes, syntax highlighting will be enabled. I would also create a more descriptive title that more accurately describes the problem at hand. It would look like so:
Title: How to print from 1-99 in python?
for i in range(1,100):
print(i)
To answer your question, it seems that your HCF list is empty, and the python max function expects the argument to the function to not to be empty (the 'arg' is the HCF list). From inspection of your code, this is because the two if conditions that need to be satisfied before anything is added to HCF is never satisfied.
So it could be that hcf2[x] is not in hcf and hcf[x] is not in hcf[x] 2.
What I would do is extract the logic for the finding of the factors of each number to a function, then use built in python functions to find the common elements between the lists. Like so:
num1 = int(input("Num 1:")) # inputs
num2 = int(input("Num 2:")) # inputs
numberOneFactors = []
numberTwoFactors = []
commonFactors = []
# defining a function that finds the factors and returns it as a list
def findFactors(number):
temp = []
for i in range(1, number+1):
if number%i==0:
temp.append(i)
return temp
numberOneFactors = findFactors(num1) # populating factors 1 list
numberTwoFactors = findFactors(num2) # populating factors 2 list
# to find common factors we can use the inbuilt python set functions.
commonFactors = list(set(numberOneFactors).intersection(numberTwoFactors))
# the intersection method finds the common elements in a set.

defining a variable to set length of an array is failing but assert and print works

def count = * print response.teams[0].teamMembers.length throws below error
com.jayway.jsonpath.PathNotFoundException: Expected to find an object
with property ['length'] in path $['teams'][0]['teamMembers'] but
found 'net.minidev.json.JSONArray'.
This is not a json object
according to the JsonProvider:
'com.jayway.jsonpath.spi.json.JsonSmartJsonProvider'.
print response.teams[0].teamMembers.length and
assert response.teams[0].teamMembers.length == 9
are working just fine.
Any help here is much appreciated.
Yes, Karate assumes the right-hand-side as Json-Path (which is fine for 90% of the cases). Use parentheses to force JavaScript evaluation when needed.
Try this:
def count = (response.teams[0].teamMembers.length)
For a detailed explanation, please refer to this section in the documentation: Karate Expressions

Passing values from function to function in JES/Jython

I am learning Jython using a program called JES, and I am having trouble understanding how to return values from a function that can be used in another function.
For example:
def driver():
picture = makePicture(pickAFile())
input(picture)
changeRed(picture, reduceRedAmount)
def input(picture):
redReduceAmount = requestInteger("How much should I reduce red by?")
return redReduceAmount
def changeRed(picture, reduceRedAmount):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.9)
I want to be able to just run the driver function in the command area, and have that function include the other functions. I understand that results in functions are local and don't pass through, but I though that if you use 'return' then it stores that value for later use. Am I on the wrong track here? Surely there is a way to pass information between functions?
Try this:
Any "-" just disregard them that is not part of the code, they are just there for spacing to help so that you don't get any syntax errors.
def driver():
picture = makePicture(pickAFile())
input(picture)
changeRed(picture, reduceRedAmount)
repaint(picture)`
or
def changeRed(picture, reduceRedAmount):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.9)
repaint(picture)
or
def changeRed(picture, reduceRedAmount):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.9)
show(picture)
or
def changeRed(picture, reduceRedAmount):
for p in getPixels(picture):
value=getRed(p)
setRed(p,value*0.9)
return(picture)`
One of those repaint, return, show should work to display the new image.
To display other values in command area just use "print something here" for example print 1+1 or print value.
the way I do it is declare it as a global variable the line after the def functionName() and at the LAST line of the functionName() code before you reduce the indent, type return variableNameYouWant.
check this:
def functionName()
global variableNameYouWant
..
..
return variableNameYouWant
What we are doing by following this is declaring the function you want to be a global variable (which must be done before it is delcared with a value, so best to do at the start of the def.) and then before you close the def by decreasing indentation, return the variable outside of the def.
I know it's an old question but I'm striving for upvotes as a newbie. :)
Edit: Thanks for the downvote, anon.

Why not to use a 'Return' statement in VB.NET?

I've been given some code to go through and find problems and things that could be improved and changed (it's a homework task, but this question is unrelated to the task itself), part of the code is:
Function CheckIfSameCell(ByVal FirstCellPosition As CellReference, ByVal SecondCellPosition As CellReference) As Boolean
Dim InSameCell As Boolean
InSameCell = False
If FirstCellPosition.NoOfCellsSouth = SecondCellPosition.NoOfCellsSouth And FirstCellPosition.NoOfCellsEast = SecondCellPosition.NoOfCellsEast Then
InSameCell = True
End If
CheckIfSameCell = InSameCell
End Function
I can't understand why the InSameCell is variable is created, when it can just be assigned to the function name CheckIfSameCell?
Or just use return statements as in the following?
Function CheckIfSameCell(ByVal FirstCellPosition As CellReference, ByVal SecondCellPosition As CellReference) As Boolean
If FirstCellPosition.NoOfCellsSouth = SecondCellPosition.NoOfCellsSouth And FirstCellPosition.NoOfCellsEast = SecondCellPosition.NoOfCellsEast Then
Return True
End If
Return False
End Function
I can understand not returning the expression in the If statement directly, to increase readability.
I know that assigning a return value to the Function name doesn't exit the function, whereas Return does, but is it just a person's style, or is there any advantage to the first version (IMO, the second is more readable)?
Maybe there used to be more checks, where value of InSameCell could change several times and only then get returned. Using return then would change behaviour.
Maybe the author wanted to avoid the tedious renaiming. You know, when you want to rename a function, and you use that function's name many times within its own body, then you have many places to replace, whereas when you introduce a variable you will only have one place to change the name in. (I know the IDE will properly do that for you; but that was not the case in VB6, and habits are difficult to break.)
Maybe the author was much more familiar with VB6 that didn't have return.
Maybe it was a matter of style or policy.
Anyway, I would write it as:
Function CheckIfSameCell(ByVal FirstCellPosition As CellReference, ByVal SecondCellPosition As CellReference) As Boolean
Return FirstCellPosition.NoOfCellsSouth = SecondCellPosition.NoOfCellsSouth AndAlso FirstCellPosition.NoOfCellsEast = SecondCellPosition.NoOfCellsEast
End Function
Assigning the result to the function name is an old style used in VB6 and should not be used any more in VB.NET. Use Return value!
Personally I dislike statements in the style
If condition Then
Return True
Else
Return False
End If
They are just stupid, since condition already yields the return value! Better:
Return condition
It is also the solution chosen by GSerg.
Nobody would write
If x + y = 0 Then
Return 0
ElseIf x + y = 1 Then
Return 1
ElseIf x + y = 2 Then
Return 2
ElseIf x + y = 3 Then
Return 3
...
But some people are constantly doing it when the expression is of type Boolean. I think that they do not realize that conditions are equivalent to arithmetical expressions. They are just arithmetic with Booleans instead of arithmetic with numbers.
Another misconception is that an If-statement requires some comparison like If x > 0 Then. If they have a Boolean variable b they write If b = True Then. But all the If-statement needs is a Boolean value given by a Boolean expression. This expression can be as simple as querying a variable: If b Then.
Why does this work? Because if b is True then b = True yields True and if b is False then b = True yields False. So, b = True is very much like saying x * 1. Of course, this is the same as just x.
The second method is more readable, I concur. It also happens to be my preference for returning out of methods. I really cannot think of a single downside to the latter in comparision, but can for the former. What happens if the method gets longer and someone forgets to set a Boolean flag? A subtle bug would be born. Additionally, it takes more code to write as well. In the latter approach, the code won't compile if it is missing a return, and it also will be shorter.
The only time you need local variables for the return type is when the routine needs to do some other work after the return value is first determined. In the example you post, this is not the case.
Code Complete, 2nd Edition agrees on page 391:
Use a return when it enhances readability In certain routines, once
you know the answer, you want to return it to the calling routine
immediately. If the routine is defined in such a way that it doesn’t
require any further cleanup once it detects an error, not returning
immediately means that you have to write more code.
NOTE: As other answers [1,2] have mentioned, you can reduce the method to a single code statement. Also using AndAlso should help speed up the evaluation by short-circuiting the logical expression early if the first part is false:
Return FirstCellPosition.NoOfCellsSouth = SecondCellPosition.NoOfCellsSouth
AndAlso FirstCellPosition.NoOfCellsEast = SecondCellPosition.NoOfCellsEast
There is one important thing with return and assigning value the the function name. If you (for whatever twisted reason) would like to write something like that
Public Function TestFunct() as Boolean
Dim testVar as Boolean = True
If testVar then
TestFunct = True
Else
TestFunct = False
EndIf
'do more stuff here
...
TestFunct = False
End Function
It will always return false. If you use returns instead it the execution will stop and the function will return correct value.
You might use a variable if for some reason it needs to appear on the right-hand side of an assignment, and you don't want to cause a recursion:
Dim Function F() As Boolean
F = True
If a = b Then
F = Not F()
End If
End Function
In short - Yes your last example is quite valid.
However, most examples used in homework are either used to show other teaching examples. The code in the homework sheet merely shows the basics of using functions in the traditional way and your 2nd example shows the next learning step and is the most compact way of achieving the desired result.
Also, the 1st example could also be used to re-enforce lessons learned earlier - e.g. about assigning variables, use of booleans etc.
One of the best ways to improve your coding skills is to repeatedly practice what you have learned.

How to suppress VB's "Iteration variable shouldn't been used in lambda expression"

I'm working with LINQ in VB.NET and sometimes I get to a query like
For i = 0 To 10
Dim num = (From n In numbers Where n Mod i = 0 Select n).First()
Next
and then it comes the warning "Using the iteration variable in a lambda expression may have unexpected results. Instead, create a local variable within the loop and assign it the value of the iteration variable."
I know it's not a good practice to use the iteration variable in the lambda expression, because lambda expressions are evaluated only when needed. (This question is about that)
Now my question is, how to suppress this warning in cases where the expression is evaluated in-place, with constructions like First(), Single(), ToList(), etc. (It's only a warning, but i like my code clean.)
(Declaring a local variable and passing the iteration variable to it is an option, but I'm looking for a clean solution.)
In this particular case where the lambda is evaluated immediately, then you can safely eliminate the warning by moving the declaration of the iteration variable outside the for loop.
Dim i = 0
For i = 0 To 10
...
I do want to stress though that this only works if the lambda does not escape the for loop (true for your scenario).
Also here is a detailed link to an article I wrote on this warning (why it exists, how to avoid it, etc ...)
http://blogs.msdn.com/b/jaredpar/archive/2007/07/26/closures-in-vb-part-5-looping.aspx