Parameter in Python - python

Let's say there is a parameter n. Can n be any numbers? For example, question like this: Given a non-negative number num, return True if num is within 2 of a multiple of 10. This is what I am thinking:
def near_ten(num):
n = int #So I assume n can be any integer
if abs(num - n*10) <=2:
return True
Return False
However, there are two problems. First, in n*10, * is a unsupported operand type cuz I thought I could use Python as a calculator. 2nd, I cannot just simply say n = int, then n can be viewed as a variable as any number (or integer) in a math function. If there is a way that I could use n in that way, then life would be so much easier.
Finally I figure it out in another way which doesn't include "n" as a parameter:
def near_ten(num):
if num%10<=2:
return True
if (num+2)%10<=2:
return True
return False
However, I'm still curious about "n" as a parameter mentioned before. Since I'm just a starter, so this is really confusing.

In Python, int is a type. Types are first-class objects in Python, and can be bound to names. Of course, trying to multiply a type by a number is usually meaningless, so the operation is not defined by default. It can be referred to by the new name though.
n = int
print(n(3.4))
print(n('10') == 10)

Here is a much simpler solution:
def near_mult_ten(num):
return abs(num - (num+5) // 10 * 10) <= 2
Edit: Fixed.

try this:
d=a%10
if d<=2 or d>=8:
return True
return False
I am new to coding as well so forgive any mistakes.

i am not sure if you have ran your code or not, but python is a high level interpreted language, python CAN distinguish between variable types and therefore you do not need to explicitly declare them, your function header is valid.
you can also do operations between integers and floats/doubles without the need of casting, python already handles that for you
your function will raise an error in any compiler, ur n variable is declared, you have defined it, but you have not initialized it

Related

Am I doing something wrong trying to #jit this Python function

I've got this Python function which I'm trying to #jit, but I can't really get around it (it's the first time I try jitting something, so I'm here to learn more than anything). I'll include the code (commented) and I'll explain what it does briefly:
def pwrchk(n, m):
no_prob = [] #The list that will contain the exponents
for i in range(2, m+1): #Start from 2 because 1 is useless
power = n**i
is_good = True #If this becomes false later, there's a zero.
for j in range(math.floor(math.log(power, 10)) + 1):
#The formula in the range is the number of digits of 'power'
digit = power % 10 #Returns the last digit so it can be checked
if digit in digits:
is_good = False #This is the check
power = 0
break
power = power // 10 #Gets rid of the digit just checked
if is_good:
no_prob.append(i) #Append to the list of "good" exponents
return no_prob
This function computes n^i , with 2 < i < m, and checks if n^i contains a zero in its digits, and then returns a list of which exponents are such that n^i contains no zeros. It works absolutely fine in normal Python compilation.
Since for big values of m the execution time gets really long (I've tried m = 10^6 and it goes to a crawl), I thought of putting it in Anaconda to #jit it. The problem is that when I use the #jit decorator it tells me that it keeps falling back to object mode, so I can't compile it in nopython mode.
I tried changing the lists to numpy arrays and populating them with the powers of n out of the for cycle, changing math.floor(math.log(power, 10)) using numpy to manage the arrays, nothing.
Am I doing something wrong? I'm sure there's a simple explanation to it that's just going over my head, but as said before I'm kinda new to Numba, so if I'm doing something really dumb please tell me, so I won't do it again in the future, and if I need to provide something else I'll update with anything needed.

Subtracting two numbers of any base between 2 and 10

For two numbers x and y that are base b, does this work for subtracting them? The numbers are given in string format and 2 <= b <= 10.
def n2b(n, b): # function to convert number n from base 10 to base b
if n == 0:
return 0
d = []
while n:
d.append(int(n % b))
n /= b
return ''.join(map(str,d[::-1]))
x = int(x,b) # convert to integers in base 10
y = int(y,b)
z = x - y
z = n2b(z,b) # convert back to base b, still in integer form
You have some confusion about how integers work in python. As the comments above say: python always stores integers in binary form and only converts them to a base when you print them. Depending on how you get x and y and how you need to give back z the code needs to be different
Situation 1: x, y and z are all integers
In this case you only need to do
z = x - y
And you're done.
Situation 2: x, y and z are all strings
In this case you first need to convert the strings into integers with the right base. I think that's your case, since you already deal with int(x, b) which is correct to transform a string into an integer (e.g. int("11", 2) gives 3 (integer represented in base 10). I would advice you to reform your code into something like this:
x_int = int(x, b)
y_int = int(y, b)
z_str = n2b(x_int - y_int, b)
In your code x is first a string and then an integer, which is bad practice. So e.g. use x_int instead of x.
Now it comes down to if your n2b function is correct. It looks good from the distance, although you're not handling signs and bases bigger than 10. There is a broadly accepted convert integer to base b answer so you might take this to be sure.
This is exactly the problem I just ran into in the google foobar challenge (which I suspect is the same source of ops problem). Granted its years later and op has no use for my answer but someone else might.
The issue
The function op used looked a lot like a copy and paste of this provided by the accepted answer but slightly modified (although I didn't look to closely).
I used the same function and quickly realized that I needed my output to be a string. Op appears to have realized the same thing based on the return statement at the end of the function.
This is why most of the test cases passed. Op did almost everything right.
See, the function begins with
if n==0:
return 0
One of the test cases in the foobar challenge uses 0 as the input. Its an easy line to miss but a very important one.
Solution
When I was presented this problem, I thought about the possible outlier cases. 0 was my first idea (which turned out to be right). I ran the program in vscode and would ya look at that - it failed.
This let me see the error message (in my case it was a list rather than int but op would have received a similar error).
The solution is simply changing return 0 to return '0' (a string rather than int)
I wasn't super excited to write out this answer since it feels a bit like cheating but its such a small detail that can be so infuriating to deal with. It doesn't solve the challenge that foobar gives you, just tells you how to get past a speed bump along the way.
Good luck infiltrating commander lambda's castle and hopefully this helps.

Compare different types in python 3.4

`From what I've read, python 2 allows comparing with different types, but for some reason, python 3 has removed that. Regardless of whether or not it is a good idea to do so, I want to compare two arbitrary values, either of the same type or different.
I read that in python 2 comparing different types is done by comparing the name of the type, so I tried to implement this.
def less_than_or_equal(a, b):
if type(a) == type(b):
return a <= b
else:
return str(type(a)) <= str(type(b))
After I did this, I realized that some types that normally would get compared like a float and an int won't compare right using this.
How could I accomplish this?
You could try the comparison and then fall back on type strings:
def leq(a,b):
try:
return a <= b
except TypeError:
return str(type(a)) <= str(type(b))
I strongly recommend against attempting this, as the 2.x behaviour is widely considered a mistake. But if you simply must emulate it...
In 2.7, the default/fallback comparison rules are as follows (source code citation):
None compares less than anything else.
Numeric values compare less than non-numeric values (except None). This is implemented by special-casing as if they had an empty-string type name, which compares less than any other string type name. Note here that we are talking about the case where ordinary numeric comparison already failed (for example, between two complex values).
Everything else compares according to its type name, then its address if they are the same type.
Here is a 3-way comparison routine that should emulate the 2.x behaviour in 3.x:
from numbers import Number
def typename_or_blank(x):
return '' if isinstance(x, Number) else type(x).__name__
def python2_cmpkey(x, y):
if x == y:
return 0
try:
return -1 if x < y else 1
except TypeError:
if type(x) is type(y):
return id(x) - id(y)
if x is None:
return -1
if y is None:
return 1
return -1 if typename_or_blank(x) < typename_or_blank(y) else 1
To get the less_than_or_equal from the question, simply compare if the result is <= 0. To get a usable sort key for sorted, min, max etc., simply wrap with functools.cmp_to_key.

Python floating point error that has left me puzzled [duplicate]

This question already has answers here:
approximate comparison in python
(3 answers)
Closed 8 years ago.
I just recently ran into a problem where I needed to append numbers to a list only if they weren't in the list already, and then I had to run those numbers through a comparison later on. The problem arises in floating point arithmetic errors. To illustrate what is basically happening in my code:
_list = [5.333333333333333, 6.666666666666667, ...]
number = some_calculation()
if number not in _list:
_list.append(number) #note that I can't use a set to remove
#duplicates because order needs to be maintained
new_list = []
for num in _list:
if some_comparison(num): #note that I can't combine 'some_comparison' with the
new_list.append(num) #above check to see if the item is already in the list
The problem is that some_calculation() would sometimes generate an inexact number, such as 5.333333333333332, which is, as far as my calculations need to go, the same as the first element in _list in this example. The solution I had in mind was to simply round all the numbers generated to 9 or so decimal places. This worked for a short amount of time, until I realized that some_comparison compares num against, again, an inexact calculation. Even if I didn't round the numbers in _list, some_comparison would still return an inexact value and thus would evaluate to False.
I am absolutely puzzled. I've never had to worry about floating point errors so this problem is quite infuriating. Does anyone have any ideas for solutions?
NOTE: I would post the actual code, but it's very convoluted and requires 7 or 8 different functions and classes I made specifically for this purpose, and reposting them here would be a hassle.
Make the comparison something like
if(abs(a-b) <= 1e-6 * (a + b)):
This is standard practice when using floating point. The real value you use (instead of 1e-6) depends on the magnitude of the numbers you use and your definition of "the same".
EDIT I added *(a+b) to give some robustness for values of different magnitudes, and changed the comparison to <= rather than < to cover the case where a==b==0.0.
You can subclass list and add in a tolerance to __contains__:
class ListOFloats(list):
def __contains__(self, f):
# If you want a different tolerance, set it like so:
# l=ListOFloats([seq])
# l.tol=tolerance_you_want
tol=getattr(self, 'tol', 1e-12)
return any(abs(e-f) <= 0.5 * tol * (e + f) for e in self)
_list = ListOFloats([5.333333333333333, 6.666666666666667])
print(5.333333333333333 in _list)
# True
print(6.66666666666666 in _list)
# True
print(6.66666666666 in _list)
# False
Use round on both the values in the list and the comparison values. They won't be exact but they'll be consistent, so a search will return the expected results.

Pythonic way of checking for 0 in if statement?

In coding a primality tester, I came across an interesting thought. When you want to do something if the result of an operation turns out to be 0, which is the better ('pythonic') way of tackling it?
# option A - comparison
if a % b == 0:
print('a is divisible by b')
# option B - is operator
if a % b is 0:
print('a is divisible by b')
# option C - boolean not
if not a % b:
print('a is divisible by b')
PEP 8 says that comparisons to singletons like None should be done with the is operator. It also says that checking for empty sequences should use not, and not to compare boolean values with == or is. However, it doesn't mention anything about checking for a 0 as a result.
So which option should I use?
Testing against 0 is (imo) best done by testing against 0. This also indicates that there might be other values than just 0 and 1.
If the called function really only returns 0 on success and 1 on fail to say Yes/No, Success/Failure, True/False, etc., then I think the function is the problem and should (if applicable) be fixed to return True and False instead.
just personal : I prefer the not a % b way because it seems to be highly readable. But now, to lower the confusion level in the code, I will use the == 0, as it express what you expect to test exactly in a more accurate way. It's the "care for debug" approach.
0 isn't guaranteed to be a singleton so don't use is to test against it: currently C Python re-uses small integers so there is probably only one int with the value 0 plus a long if you're still on Python 2.x, and any number of float zeroes not to mention False which all compare equal to 0. Some earlier versions of Python, before it got a separate bool type used a different int zero for the result of comparisons.
Use either == (which would be my preference) or just the not, whichever you prefer.
A and C are both valid and very pythonic.
B is not, because
0 semantically is not a singleton (it is in cPython, but that is an implementation detail).
It will not work with float a or b.
It is actually possible that this will not work in some other implementation of Python.

Categories

Resources