This question already has answers here:
How to test multiple variables for equality against a single value?
(31 answers)
Closed 7 years ago.
I am not sure if it is iterating through the list or being called multiple times... in either case it shouldn't be doing either of those things. I am pretty new to python and programming in general. Here is the function:
"""
Gets the mass that may have an isotope of +1 neutron for C,N or O (if there is one)
#param mass the mass
#return the mass +1
"""
def getMassPlus(mass):
if (mass)+1 in mass_old2:
return (mass)+1
elif (mass)+1.1 in mass_old2:
return (mass)+1.1
elif (mass)+1.2 in mass_old2:
return (mass)+1.2
elif (mass)+.9 in mass_old2:
return (mass)+.9
and here is the function call:
if ((14.00674*multiplyByN)+(15.994915*multiplyByO)+(1.00794*multiplyByH)) == isotope_masses[i]+.5 or isotope_masses[i]-.5:
if isotope_masses[i]+1 or isotope_masses[i]+1.1 or isotope_masses[i]+1.2 or isotope_masses[i]+.9 in mass_old2:
nextMass = getMassPlus(isotope_masses[i])
What happens is that when I call the function, it somehow iterates through the list isotope_masses (which looks like this: isotope_masses = [1,2,3,4,...]) ten times and assigns nextMass ten values as well. It might also help you to know that the second block of code is part of a larger loop that iterates through the length of isotope_masses. I am not really sure why this issue happening, any ideas would be appreciated. Thanks in advance.
Loop:
for i in range(len(isotope_masses)):
if not noNitrogen(molecules[i]): #molecule has nitrogen and possibly hydrogen
if hasDoubleDig('N'):
multiplyByN = int(molecules[i][3:5])
multiplyByH = int(molecules[i][8:])
else:
multiplyByN = int(molecules[i][3])
multiplyByH = int(molecules[i][7:])
if ((14.00674*multiplyByN)+(1.00794*multiplyByH)) == isotope_masses[i]+.5 or isotope_masses[i]-.5:
if isotope_masses[i]+1 or isotope_masses[i]+1.1 or isotope_masses[i]+1.2 or isotope_masses[i]+.9 in mass_old2:
nextMass = getMassPlus(isotope_masses[i])
if float(intensities[mass_old2.index(nextMass)])/float(intensities[mass_old2.index(isotopes_masses[i])]) == multiplyByN * .00364:
file_isotopes.append("Isotope: is N-15")
else:
file_isotopes.append("Mix of isotopes")
elif not noCarbon(molecules[i]): #molecule has carbon and possibly hydrogen
if hasDoubleDig('C'):
multiplyByC = int(molecules[i][1:3])
multiplyByH = int(molecules[i][8:])
else:
multiplyByC = int(molecules[i][1])
multiplyByH = int(molecules[i][7:])
if ((12.0107*multiplyByC)+(1.00794*multiplyByH)) == isotope_masses[i]+.5 or isotope_masses[i]-.5:
if isotope_masses[i]+1 or isotope_masses[i]+1.1 or isotope_masses[i]+1.2 or isotope_masses[i]+.9 in mass_old2:
print isotope_masses[i]
nextMass = getMassPlus(isotope_masses[i])
if float(intensities[mass_old2.index(nextMass)])/float(intensities[mass_old2.index(isotope_masses[i])]) == multiplyByC * .0107:
file_isotopes.append("Isotope is: C-13")
else:
file_isotopes.append("Mix of isotopes")
There is more to the loop but its just repetitive so I only gave two cases in the loop for the sake of brevity.
I think your if statements are always equating to True.
instead of:
if ((14.00674*multiplyByN)+(15.994915*multiplyByO)+(1.00794*multiplyByH)) == isotope_masses[i]+.5 or isotope_masses[i]-.5
you need the second part of the conditional to also be a full comparison:
if ((14.00674*multiplyByN)+(15.994915*multiplyByO)+(1.00794*multiplyByH)) == isotope_masses[i]+.5 or ((14.00674*multiplyByN)+(15.994915*multiplyByO)+(1.00794*multiplyByH)) == isotope_masses[i]-.5
same thing with the second conditional you have in there.
if isotope_masses[i]+1 or isotope_masses[i]+1.1 or isotope_masses[i]+1.2 or isotope_masses[i]+.9 in mass_old2:
equivalent to:
if a or b or c in x:
is being evaluated as
if (bool(a) or bool(b) or bool(c)) in x:
You need to change it to the following form:
if a in x or b in x or c in x:
Pretty sure this is a duplicate of How do I test one variable against multiple values?
Related
I want to make a for loop that checks if list d has elements from list ident and if they don't, I want to add them. When I run this code part by part it works, but I suspect my False statement is not working, because it just doesn't append.
import pandas as pd
ident=['bla','me','you']
d=['bla']
for x in range(len(ident)):
if ident[x] in d == False:
d.append(ident[x])
Here is how I want the output to be:
d=['bla','me','you']
There might be a duplicate for this that I can't find, but just to explain the problem:
Python comparison operators chain. That is why you can write 1 < 2 < 3 < 4 in Python and it will evaluate as (1 < 2) and (2 < 3) and (3 < 4).
By the same mechanism, when you write
if ident[x] in d == False:
it is broadly equivalent to
if (ident[x] in d) and (d == False):
Most of the time if you're tempted to write == False or == True, there's probably a better way to express the condition.
In this case, it should be:
if ident[x] not in d:
I understand that you didn't ask that. But let me try to optimize your code a bit. Because these two lists could have equal length and the search could be very long - up to O(n^2). So here are my small improvements that will allow you to make the full algorithm in O(n) time + fixing your error.
ident=['bla','me','you']
new_ident = dict(zip(ident, ident))
d=['bla']
for i in d:
if i not in new_ident: new_ident[i] = True
ident = new_ident.keys()
This should produce the expected output.
for x in range(len(ident)):
if ident[x] not in d:
d.append(ident[x])
merge = d + list(set(ident) - set(d)) + list(set(d) - set(ident))
it is different way
This question already has answers here:
Accessing the index in 'for' loops
(26 answers)
Closed 2 years ago.
I am creating a program, which through differentiation, can return the coordinates and nature of any stationary points, given an equation.
My whole program so far is:
equation = input("y=")
expression_list = []
for i in equation:
expression_list.append(i)
def derive(expression):
global derivation
derivation = []
for i in expression:
if i == "x" and int(expression[expression.index(i)+2]) != 0:
derivation.append(int(expression[expression.index(i)-1]) * int(expression[expression.index(i)+2]))
derivation.append("x")
derivation.append("^")
derivation.append(int(expression[expression.index(i)+2]) - 1)
derive(expression_list)
expression_list_1st_derivative = derivation
print(expression_list_1st_derivative)
The area of the program that I am having trouble with is:
def derive(expression):
global derivation
derivation = []
for i in expression:
if i == "x" and int(expression[expression.index(i)+2]) != 0:
derivation.append(int(expression[expression.index(i)-1]) * int(expression[expression.index(i)+2]))
derivation.append("x")
derivation.append("^")
derivation.append(int(expression[expression.index(i)+2]) - 1)
derive(expression_list)
expression_list_1st_derivative = derivation
print(expression_list_1st_derivative)
Using y=4x^5+3x^4 as an example, I have created this for loop in the hope of giving ["20","x","^","4","12","x","^","3"] which, if you have studied calculus, you will know as x/dx. I have not included operators yet; that being something I will work on after clearing this hurdle. Currently these lines of code instead give ["20","x","^","4","20","x","^","4"]. What changes must I make to get the correct result?
Your expression.index(i) is finding the first position of i, not the one that you are currently processing.
Instead you can use enumerate and then you have the current index number available.
It would also be better if your function returned a value (here, a list) instead of setting a global variable:
def derive(expression):
derivation = []
for index, i in enumerate(expression): # <== note use of "enumerate"
if i == "x" and int(expression[index+2]) != 0:
derivation.append(int(expression[index-1]) * int(expression[index+2]))
derivation.append("x")
derivation.append("^")
derivation.append(int(expression[index+2]) - 1)
return derivation # <== note return value
expression_list = ["20","x","^","4","12","x","^","3"]
expression_list_1st_derivative = derive(expression_list)
print(expression_list_1st_derivative)
I have been attempting to program a calculator using the tkinter module in Python, and I have made 14 functions corresponding to each number and symbol on the calculator. The code below is for the number 1, for example.
The program doesn't return the values as it should, however. I use the values from the previous function in further functions as parameters, but they don't seem to go through and I constantly get result 0.
The variables a and b correspond to two numbers to be used in the calculation and num is a counter for the program to know when to give the number to a and when to give it to b. I have tried inserting a print in this code and a and b was printing correctly but it seems to be a problem with the return.
Any help would be appreciated.
def num1(num,a,b):
if num == 0:
a=a+1
num=num+1
elif num == 1:
b=b+1
return num
return a
return b
Python function only return one value. When you write return a;return b, you only return the first occurrence.
What you need to do , is pack those elements and return them as a tuple:
def num1(num,a,b):
if num == 0:
a=a+1
num=num+1
elif num == 1:
b=b+1
return num, a, b
you need to keep in mind that the first return statement that reaches the work flow causes the end of the current function and returns the value supplied.
the return a; return b lines will never be reached, the execution flow returns to the caller after the first return statement
You can return a list, dictionary,tuple, variable. But a function can't return multiple times. You can try inserting the values in a list and then return the list.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
calling func. change the input
I have to write a recursive function that takes a list of numbers in input and returns a list of numbers in output, for example called like this:
rec_cumsum([2,2,2,3])
the output should be like:
[2,4,6,9]
Thing is, I cant seem to get my head around for this to work.. this got me questioning my whole recursive thinking..
what i have so far is :
newlist = []
k = 1
def rec_cumsum(numbers):
if len(numbers) == 0:
return 0
if len(numbers) > 1 and len(numbers) != (k+1):
newlist[k+1] == newlist[k+1] + newlist[k]
k = k+1
return rec_cumsum(numbers)
but I'm getting errors which doesn't really make any sense to me.
the recursion should always take the number, and add it to the one before it, than save it in the next location of the list.. (new one or original one)
I would write it like this:
def cumulative_sum(lst,prev=0):
if not lst:
return []
else:
elem = prev+lst[0]
return [elem] + cumulative_sum(lst[1:],prev=elem)
print cumulative_sum([2,2,2,3])
Now to look at your code (note I didn't actually work through the logic to decide whether it would give the correct result, the following only addresses possible exceptions that your code is probably throwing):
You're probably getting an IndexError because of this line:
newlist[k+1] == newlist[k+1] + newlist[k]
You're assigning to a list position which doesn't exist yet. You could pre-allocate your list:
newlist = [0]*len(lst)
but even if you fix that, you'll get a recursion error with your code because of the line:
k = k + 1
The problem here is that on the left hand side, k is local whereas on the right hand side, k is global. So essentially each time you run this, you're getting the local k == 2 and not touching the global one. If you really want to modify the global k, you need to declare k as global via global k. Of course, then you need to reset k every time you're going to use this function which would be a somewhat strange API.
I've just started exploring the wonders of programming. I'm trying to write a code to identify numeric palindromes. Just looking at numbers and not texts. I'm trying to learn to use recursion here. But I'm just not getting anywhere and I can't figure out what's wrong with it.
My idea was to check first string vs the last, then delete these two if they match, and repeat. Eventually there'll be nothing left (implying it is a palindrome) or there will be a couple that doesn't match (implying the reverse).
I know there are better codes to finding palindromes in but I just wanted to try my hand at recursion.
So what's wrong?
def f(n):
global li
li=list(str(n))
if (len(li)==(1 or 0)):
return True
elif li[len(li)-1]==li[0]:
del li[0]
del li[len(li)-1]
if len(li)==0:
return True
if len(li)>0:
global x
x=''.join(li)
str(x)
f(x)
else:
return False
Thanks in advance!
A few comments
Why are x and li globals? In recursion, all variables should be local.
Why are you converting back and forth between str and list? You can subscript both of them
You need to return the result of your recursive call: return f(x)
Try these suggestions, and see how it works out.
Before looking into it too much, if (len(li)==(1 or 0)): doesn't do what you're expecting it to do. (1 or 0) will always evaluate to 1.
You probably want:
if len(li) in (1, 0):
There are a couple of problems with your solution. Let me analyse them line by line.
You don't need global statements if you don't intend to change variables outside of function scope. Thus, I removed two lines with global from your code.
li=list(str(n)): casting a string to a list is unnecessary, as a string in Python has a similar interface to an immutable list. So a simple li = str(n) will suffice.
if (len(li)==(1 or 0)):: although it looks OK, it is in fact an incorrect way to compare a value to a few other values. The or operator returns the first "true" value from its left or right operand, so in this case it always returns 1. Instead, you can use the in operator, which checks whether the left operand is an element of a right operand. If we make the right operand a tuple (1, 0), all will be well. Furthermore, you don't need parentheses around the if statement. You should write: if len(li) in (1, 0):
elif li[len(li)-1]==li[0]: is fine, but we can write this shorter in Python, because it supports negative list indexing: elif li[-1] == li[0]:
Because we don't use lists (mutable sequences) because of point 2., we can't do del li[0] on them. And anyway, removing the first element of a list is very inefficient in Python (the whole list must be copied). From the very same reason, we can't do del li[len(li)-1]. Instead, we can use the "splicing" operator to extract a substring from the string: li = li[1:-1]
if len(li)==0: is unnecessary long. In Python, empty strings and lists resolve to False if tested by an if. So you can write if not li:
if len(li)>0:: You don't have to check again if li is not empty -- you checked it in point 6. So a simple else: would suffice. Or even better, remove this line completely and unindent the rest of the function, because the body of the if in 6. contains a return. So if we didn't enter the if, we are in the else without writing it at all.
x=''.join(li): We don't need to convert our string to a string, because of the decision made in 2. Remove this line.
str(x): This line didn't do anything useful in your code, because str() doesn't modify its argument in place, but returns a new value (so x = str(x) would have more sense). You can also remove it.
f(x): This is a valid way to call a recursive function in Python, but you have to do something with its value. Return it perhaps? We'll change it to: return f(li) (as we don't have an x variable any more).
We end up with the following code:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
if not li:
return True
return f(li)
else:
return False
It's almost what we need, but still a little refinement can be made. If you look at the lines if not li: return True, you'll see that they are not necessary. If we remove them, then f will be called with an empty string as the argument, len(li) will equal 0 and True will be returned anyway. So we'll go ahead and remove these lines:
def f(n):
li = str(n)
if len(li) in (1, 0):
return True
elif li[-1] == li[0]:
li = li[1:-1]
return f(li)
else:
return False
And that's it! Good luck on your way to becoming a successful programmer!
Split the whole show out into a list, then just:
def fun(yourList):
if yourList.pop(0) == yourList.pop(-1):
if len(yourList) < 2:
return True # We're a palindrome
else:
return fun(yourList)
else:
return False # We're not a palindrome
print "1234321"
print fun(list("1234321")) # True
print "6234321"
print fun(list("6234321")) # False
def palindrome(n):
return n == n[::-1]
It's hard to tell what you intend to do from your code, but I wrote a simpler (also recursive) example that might make it easier for you to understand:
def is_palindrome(num):
s = str(num)
if s[0] != s[-1]:
return False
elif not s[1:-1]:
return True
else:
return is_palindrome(int(s[1:-1]))
number = int(raw_input("Enter a number: "))
rev = 0
neg = number
original = number
if (number < 0):
number = number * -1
else:
number = number
while ( number > 0 ):
k = number % 10
number = number / 10
rev = k + ( rev * 10 )
if (number < 1):
break
if ( neg < 0 ):
rev = ( rev * -1)
else:
rev = (rev)
if ( rev == original):
print "The number you entered is a palindrome number"
else:
print "The number you entered is not a palindrome number"
This code even works for the negative numbers i am new to programming in case of any errors
dont mind.