Multiply method for a binary list - python

I am passing parameters x and y to this multIter class in the console as follows:
import BigInteger as bi
x =bi.BigInteger([1,0,1,1])
y= bi.BigInteger([1,0,0,1])
bi.BigInteger.multIter(x,y)
I am currently getting the wrong answers when I call this method. There is some logical error in the line answer = self.add(x), that I am not able to figure out.
def multIter(self,y):
a_bits = self._bits
b_bits = y._bits
answer = 0
for i in range(0,len(b_bits)):
if(b_bits[i] == 1):
x= self.multByPow2(i)
answer = self.add(x)
return answer

There is indeed a logical error at the statement you indicate. In each iteration that has a 1-bit, that answer = self.add(x) assignment ignores the previous value of answer, and just overwrites it. You should not add x to self, but add x to answer. For that to work, answer must be initialised as an instance of BigInteger, and not as 0.
So replace that part of the code with:
answer = bi.BigInteger([0])
for i in range(0,len(b_bits)):
if b_bits[i] == 1:
x = self.multByPow2(i)
answer = answer.add(x)
This will work fine assuming the other used methods of BigInteger have been correctly implemented.

Related

Python Recursive Try-Except [duplicate]

This question already has an answer here:
Recursive code returns None [duplicate]
(1 answer)
Closed 3 years ago.
I'm trying to make a recursive try-except function in order to deal with occasional errors. In pandas, we can create quantiles for dataframes, however, it might happen that the borders of two or more quantiles coincide and, thus, there isn't a border actually. Sopandas will throw an error. To circumvent this, you can just lower the number of quantiles and that's what I'm attempting to do here.
import pandas as pd
quantiled, dict_bins = recursive_lower_labels(model_quant = model_quant,
n_quantiles = n_quantiles,
reverse = reverse)
def recursive_lower_labels(model_quant,
n_quantiles,
reverse = False):
'''
Recursively lowers the number of labels until it works.
'''
if n_quantiles == 0: # base case
return 'Error: There are no Quantiles to be used.'
# Not very important...
# I'm using this to either use normal or reverse labels.
if reverse == False:
labels = range(1, n_quantiles + 1)
elif reverse == True:
labels = range(n_quantiles, 0, -1)
try:
qt, dc = pd.qcut(model_quant,
q = n_quantiles,
labels = labels,
retbins = True)
return qt, dc
except:
recursive_lower_labels(model_quant,
n_quantiles = n_quantiles - 1,
reverse = reverse)
The error I'm getting is (pointing to the function call up top):
cannot unpack non-iterable NoneType object
I suspect it's one of two mistakes I'm making:
There is a problem with scoping somewhere. Maybe n_quantiles? It doesn't seem likely, from my unexperienced debugging.
There is an issue with respect to placing a return before the function recursive call inside the except statement. I've tried a lot of combinations here, even with an extra else at the end and it didn't work either.
By the way, if not recursive, this does work.
EDIT:
My question was marked as a duplicate and this edit is to address that evaluation. Firstly, it was marked as a duplicate of a question that was also marked as such, which is strange, but not that relevant. The important and useful concept that differs those questions from mine is that they both had functions that, although recursive, did not necessarily return something all the time, while mine did return something always and, thus, made it seem that the return on the recursion was not necessary — which turns out to not be true.
All you have to do is return your recursion. With some light refactoring:
def recursive_lower_labels(model_quant,
n_quantiles,
reverse=False):
"""
Recursively lowers the number of labels until it works.
"""
if n_quantiles == 0: # base case
return 'Error: There are no Quantiles to be used.'
# Not very important...
# I'm using this to either use normal or reverse labels.
if reverse:
labels = range(n_quantiles, 0, -1)
else:
labels = range(1, n_quantiles + 1)
try:
return pd.qcut(model_quant,
q=n_quantiles,
labels=labels,
retbins=True)
except:
return recursive_lower_labels(model_quant,
n_quantiles=n_quantiles - 1,
reverse=reverse)

Parameter hint assignment through a function in LMFIT

I want to set the parameter hints for models held in a dictionary. I have created a function which is called for setting the hints. First, a primary model is created and then I want to create different models, identical to the primary, but with different prefixes. The set_hints function accepts a parameter comp which defined what hints will be set. This is a simplified part of my code:
import lmfit
def foo (x, a):
return x + a
def set_hints(mod, comp="2"):
mod.set_param_hint("a", value=1, vary=True)
if comp == "2":
mod.set_param_hint("a", value=0, vary=False)
return mod.param_hints
m = lmfit.Model(foo)
models = {}
for i in range(2):
hints = set_hints(m, comp="2")
models["m%i" % i] = lmfit.Model(m.func, m.independent_vars,
prefix="m%i" %i,
param_names=m.param_names)
for par in m.param_names:
models["m%i" % i].param_hints[par] = hints[par]
# models["m%i" % i].param_hints = hints
for key in models.keys():
print key
print "value:"
print models[key].param_hints["a"]["value"]
print "vary:"
print models[key].param_hints["a"]["vary"]
which outputs:
m0
value:
1
vary:
True
m1
value:
0
vary:
False
Which doesn't make any sense to me! The value and vary hints should be 0 and False respectively in both cases. It is like at the second iteration of the loop, the condition comp == "2" of the set_hints function is not satisfied for the 1st iteration of the loop and the hints are changed retroactively! If I uncomment the commented line and not set the hints iteratively, the result is good. But what is happening now I find it completely absurd. Please help me understand what is happening!
The code seems very weird, but I assume it comes from a larger design. I think this must be a bug, though I'm not certain what that is. I will create an Issue on the lmfit github site.

Declaring a variable via a Zapier input in Python

I'm trying to do a simple declaration of an inputted variable to an integer, but am receiving an error:
Bargle. We hit an error creating a run python. :-( Error:
Your code had an error! Traceback (most recent call last): File "/tmp/tmpXq4aAP/usercode.py", line 7, in the_function num = int(input['managers']) KeyError: 'num'
The following is the code i'm using:
num = int(input['num'])
if num >= 100 :
big_num = true
else:
big_num = false
return {'big_num': big_num}
Your error is right here:
num = int(input['num'])
Change those square brackets for round brackets:
num = int(input('num'))
If you are on Python 2 you should use raw_input
num = int(raw_input('num'))
In Zapier, the code:
input['varname']
refers to the variable that is passed in the "Code by Zapier" Action.
The error you are getting sounds to me like you have not defined the num variable prior to your code.
Also, True and False need to be capitalized.
Otherwise, see below, this setup works...
num = int(input['num'])
if num >= 100 :
big_num = True
else:
big_num = False
return {'big_num': big_num}
Many of these answers reference the input() built in - we override that in Code by Zapier (since it literally makes zero sense to have user input on an automated script). In it's place is a dictionary defined by some fields above.
Definitely confusing for folks unfamiliar with the context of Zapier - we'll look into renaming it and just nulling the input build.
Input is a kernel method and it can't be subscriptable , there is an syntax error change the code to like this.
num = int(input('num'))
Within Zapier, the proper way to convert Input Data (every input into a Code Step is a String) to Integers is as follows:
num = int(input.get('num'))
or
num = int(input['num'])
If the number comes attached with a decimal, strip the unwanted characters from the String before converting to an Integer. For a number like 80.0 this would look like:
num = int(input['num'][:-2])

Square root function in Python - what's wrong with it?

I literally just started learning Python this week. (I will be a computer science fresher in a month!)
Here's a function I wrote to compute the square root of x.
#square root function
def sqrt(x):
"""Returns the square root of x if x is a perfect square.
Prints an error message and returns none if otherwise."""
ans = 0
if x>=0:
while ans*ans <x:
ans = ans + 1
if ans*ans == x:
print(x, 'is a perfect square.')
return ans
else:
print(x, 'is not a perfect square.')
return None
else: print(x, 'is a negative number.')
But when I save it and type sqrt(16) into the Python shell, I get an error message.
NameError: name 'sqrt' is not defined
I'm using Python 3.1.1.
Is there something wrong with my code?
Any help would be appreciated.
Thanks
UPDATE
Okay, thanks to you guys I realized I hadn't imported the function.
And when I tried to import it, I got an error because I saved it in a generic My Documents file instead of C:\Python31. So after saving the script as C:\Python31\squareroot.py, I typed into the shell (having restarted it):
import squareroot
And got a NEW error!
>>> import squareroot
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
import squareroot
File "C:\Python31\squareroot.py", line 13
return ans
SyntaxError: 'return' outside function
Meaning there WAS a bug in my original code! I'm going to look at some of the suggested corrections below right now. If you've spotted anything else, say. Thanks :)
UPDATE 2 - IT WORKED!!!!!!!!!!
Here's what I did.
First, I used a cleaned up version of code kindly posted by IamChuckB. I made a new script with this in it (changed the function name from sqrt to sqrta to differentiate):
def sqrta(x):
"""Returns the square root of x if x is a perfect square.
Prints an error message and returns none if otherwise."""
ans = 0
if x>=0:
while ans*ans <x:
ans = ans + 1
if ans*ans == x:
print(x, 'is a perfect square.')
return ans
else:
print(x, 'is not a perfect square.')
return None
else:
print(x, 'is a negative number.')
And, importantly, saved it as C:\Python31\squareroota.py (Again, added an "a" at the end to differentiate between this the other, failed, file.)
Then I reopened Python shell and did this:
>>> import squareroota
Nothing happened, no error, great! Then I did this:
>>> squareroota.sqrta(16)
And got this!
16 is a perfect square.
4
Wow. I know this might seem like playing with ABC blocks in school but it honestly blew my mind. Thank you very much everyone!
Yes I believe you have to actually import your function into the shell.
from yourfile import sqrt
Be careful. I think if you're in the shell and you make changes, you have to reimport your function for those changes to show up. As delnan mentions below you can reload
your file after changeing it..
Firstly, your loop will always end on its first iteration since you essentially have if (...) return else return. Try this instead:
def sqrt(x):
"""Returns the square root of x if x is a perfect square.
Prints an error message and returns none if otherwise."""
ans = 0
if x >= 0:
while ans * ans <= x:
if ans * ans == x:
print(x, 'is a perfect square.')
return ans
ans = ans + 1
print(x, 'is not a perfect square.')
return None
else: print(x, 'is a negative number.')
But note that Python offers a built-in power operator:
def sqrt(x):
return x ** 0.5
To answer your question specifically, you will have to import your function. If the file in which this is written is sqrt.py, to use this function in another file you would need from sqrt import sqrt.
The NameError means that your python shell does not recognize the function. You probably forgot to import the script.
Assuming that you saved your file as myscript.py (in the same directory as where you start your python shell), you have to use:
import myscript
for the functions defined inside to be available. Note that you'll have to call myscript.sqrt in order to run your function sqrt: it is only available in the myscript namespace.
An alternative is to type from myscript import sqrt: in that case, you make your myscript.sqrt available in the namespace as sqrt. Be careful that you don't overwrite a builtin function with this from ... import ......
Here's your original code, just cleaned up so it will run. The problem with it as originally formatted was with indentation.
The while block should be indented one level (4 spaces) deep to denote it is in the def block for the function sqrt.
Having the if/else blocks inside of the while statements means that check is done each pass through the loop; therefore, the first time through when ans is only equal to one, that test will be done, your output with be printed and a value returned. We need to change this. Several of the other answers give more straight-forward ways to phrase this in python but, in keeping as close to the code you've written as possible, all you actually have to do is move the if block and the else block out of the while block. Code is shown below:
def sqrt(x):
"""Returns the square root of x if x is a perfect square.
Prints an error message and returns none if otherwise."""
ans = 0
if x>=0:
while ans*ans <x:
ans = ans + 1
if ans*ans == x:
print(x, 'is a perfect square.')
return ans
else:
print(x, 'is not a perfect square.')
return None
else:
print(x, 'is a negative number.')
Sample input and output are shown:
In:
sqrt(9)
Out:
9 is a perfect square.
In:
sqrt(8)
Out:
8 is not a perfect square.
EDIT: In my opinion, Python is a great first language. When I was first starting off with it, I found the MIT OpenCourseWare class very useful. One very important note: the class is taught using Python 2.x instead of 3.x so some of the given code won't work right for you. Even if you don't watch all the video lectures, the assignments they give are of a reasonable difficulty and the reading assignments reference some excellent python learning materials.
The Udacity CS101 class also offers a good, directed introduction to programming in Python (and also uses Python 2.x) but I only worked through about half of the assignments there. I'd still recommend taking a look at it, however.

python list Index out of range error

I am working on a python tetris game that my proffessor assigned for the final project of a concepts of programming class. I have got just about everything he wanted to work on it at this point but I am having a slight problem with one part of it. Whenever I start moving pieces left and right I keep getting "index out of range error". This only happens when it is up against a piece. Here are the culprits that are giving me grief.
def clearRight(block=None):
global board, activeBlock, stackedBlocks
isClear = True
if(block == None):
block = activeBlock
if(block != None):
for square in block['squares']:
row = square[1]
col = square[0]+1
if(col >= 0 and stackedBlocks[row][col] !=None):
isClear=False
return isClear
def clearLeft(block=None):
global board, activeBlock, stackedBlocks
isClear = True
if(block == None):
block = activeBlock
if(block != None):
for square in block['squares']:
row = square[1]
col = square[0]-1
if(col >= 0 and stackedBlocks[row][col] !=None):
isClear=False
return isClear
I am not looking to get anyone to fix it for me, I'm only looking for tips on how to fix it myself. Thanks in advance for any help that is given.
There a typo that would cause that problem in the first method.
When you're checking each cell in the block shifted one right, you don't check if they are off the grid.
if (col >= 0 and ...)
probably should be
if (col < num_cols and ...)
I also agree with CrazyDrummer, make a generic clear function
Spoilers ...
def clear(x_offset, block=None):
if not block:
block = activeBlock
if not block: return True
for x,y in block:
x += x_offset
if not (0 <= x < num_cols) or stackedBlocks[x, y]:
return False
return True
Look at what's different when you're getting the exception. Try printing out program state information to help you zero in. There's only one place where you access an array with variable indexes, so you can narrow your search radius a bit.
Separate suggestion: Make a generic clear that takes determines what direction you want to clear from by the parameters.
I highly recommend the book debugging rules!, it will aid you in searching out and properly fixing problems. :D

Categories