So I am trying to change a randomized variable to a string with a function, any ideas why this isn't working?
def letter(x):
if x == 1:
x = "A"
elif x == 2:
x = "C"
elif x == 3:
x = "G"
elif x == 4:
x = "T"
else:
print "Error"
randint18= random.randrange(1,5)
letter(randint18)
print randint18 `
You have to return the value from the function, and assign it to a variable.
def letter(x):
...
return x
randint18 = random.randrange(1, 5)
result = letter(randint18)
print result
mine isn't a proper answer, which have been provided already, but a suggestion for improving your code. I'd do it in a comment, but the code formatting ain't good enough.
Why not use a dictionary for the mapping, instead of a sequence of if's? You could still place it in a function if you like:
letter = {1:'A', 2:'C', 3:'G', 4:'T'}
randint18 = random.randrange(1,5)
mapping = letter.get(randint18, 'Error')
print mapping
mind you, a list would be even more efficient, if the mapping started form zero:
letter = ['A', 'C', 'G', 'T']
randint18 = random.randrange(0,4)
try: # in case your random index were allowed to go past 3
mapping = letter[randint18]
except IndexError:
mapping = 'Error'
print mapping
You cannot alter the variable in place you must return it and capture the returned value.
import random
def letter(x):
if x == 1:
x = "A"
elif x == 2:
x = "C"
elif x == 3:
x = "G"
elif x == 4:
x = "T"
else:
print "Error"
return x # return it here
randint18= random.randrange(1,5)
randint18 = letter(randint18) # capture the returned value here
print randint18
There is a simpler way to achieve what you want, using a dictionary to map the values.
import random
def letter(x):
mapd = {1:'A', 2:'C', 3:'G', 4:'T'}
return mapd.get(x, None)
randint18= random.randrange(1,5)
randint18 = letter(randint18)
print randint18
You forgot to include a return in your function
def letter(x):
if x == 1:
x = "A"
elif x == 2:
x = "C"
elif x == 3:
x = "G"
elif x == 4:
x = "T"
else:
print "Error"
return x
randint18 = random.randrange(1,5)
returned_result = letter(randint18)
print returned_result
Add a return value of the function
return x
value_you_want = letter(randint18) ##add the return statement. Output will be saved to value_you_want
Please note that the variables defined inside a function are local to the function and cannot be accessed outside the scope of the function. You were expecting the value of x outside the function which is not possible. Just to check run your function and try to access the value in variable x. It will give error.
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
print x
NameError: name 'x' is not defined
Related
I can't seem to figure out why my function doesn't print anything when called.
This is the function (and a list that's used in the function):
old_letters = ['a', 'p', 'c', 'f']
def try_update_letter_guessed(letter_guessed, old_letters_guessed):
length = len(letter_guessed)
english_validation = letter_guessed.isalpha()
already_used = letter_guessed in old_letters_guessed
if (length > 1) or (english_validation == False) or (already_used == True):
print("X")
delim = "->"
res = delim.join(sorted(old_letters_guessed))
print(res)
return False
elif (length == 1) and (english_validation == True) and (already_used == False):
old_letters_guessed.append(letter_guessed)
return True
However, when I call my function (with arguments) like so:
try_update_letter_guessed('A', old_letters)
it doesn't print anything at all.
What am I missing?
When letter_guessed is 'A', then (length > 1) or (english_validation == False) or (already_used == True) is not true, so this goes to the elif, and that doesn't print anything.
If you try with arguments which will make that condition true, then it does print:
>>> try_update_letter_guessed('AB', old_letters)
X
A->a->c->f->p
False
>>> try_update_letter_guessed('a', old_letters)
X
A->a->c->f->p
False
Use print() inside the elif block. Because the argument 'A' will only lead into the elif block so after appending to the old_letters_guessed if you want to see something in the console use the print() function.
I have a dataframe shown below:
Name X Y
0 A False True
1 B True True
2 C True False
I want to create a function for example:
example_function("A") = "A is in Y"
example_function("B") = "B is in X and Y"
example_function("C") = "C is in X"
This is my code currently (incorrect and doesn't look very efficient):
def example_function(name):
for name in df['Name']:
if df['X'][name] == True and df['Y'][name] == False:
print(str(name) + "is in X")
elif df['X'][name] == False and df['Y'][name] == True:
print(str(name) + "is in Y")
else:
print(str(name) + "is in X and Y")
I eventually want to add more Boolean columns so it needs to be scalable. How can I do this? Would it be better to create a dictionary, rather than a dataframe?
Thanks!
If you really want a function you could do:
def example_function(label):
s = df.set_index('Name').loc[label]
l = s[s].index.to_list()
return f'{label} is in {" and ".join(l)}'
example_function('A')
'A is in Y'
example_function('B')
'B is in X and Y'
You can also compute all the solutions as dictionary:
s = (df.set_index('Name').replace({False: pd.NA}).stack()
.reset_index(level=0)['Name']
)
out = s.index.groupby(s)
output:
{'A': ['Y'], 'B': ['X', 'Y'], 'C': ['X']}
I think you can stay with a DataFrame, the same output can be obtained with a function like this:
def func (name, df):
# some checks to verify that the name is actually in the df
occurrences_name = np.sum(df['Name'] == name)
if occurrences_name == 0:
raise ValueError('Name not found')
elif occurrences_name > 1:
raise ValueError('More than one name found')
# get the index corresponding to the name you're looking for
# and select the corresponding row
index = df[df['Name'] == name].index[0]
row = df.drop(['Name'], axis=1).iloc[index]
outstring = '{} is in '.format(name)
for i in range(len(row)):
if row[i] == True:
if i != 0: outstring += ', '
outstring += '{}'.format(row.index[i])
return outstring
of course you can adapt this to the specific shape of your df, I'm assuming that the column containing names is actually 'Name'.
Currently, what I have is
ntries = 0
def test_guess(code,guess):
if guess == code:
return True
ntries += 1
else:
return False
blackpegs = 0
whitepegs = 0
code_remainder = ''
guess_remainder = ''
ntries += 1
for x, y in zip(code,guess):
if x==y:
blackpegs += 1
elif not x==y:
code_remainder += x
guess_remainder += y
for i in guess_remainder:
if code_remander.find(i) != -1: #if i is found in the remainder of the code
whitepegs += 1
code_remainder = code_remainder.replace(i, 'X', 1)
return code_remainder
return guess_remainder
return blackpegs
return whitepegs
Right below, I have
if test_guess(code,guess)==True:
print 'You won!"
elif test_guess(code,guess)==False:
print 'Not quite. You get',blackpegs,'black pegs,',whitepegs,'white pegs.'
blackpegs in my final print statement keeps coming up as undefined. Why is it not set to be equal to the blackpegs counter?
if guess == code:
return True
ntries += 1
if your guess == code, then return true, next step can't be executed!
You can only have one return statement.
return code_reminder
Causes the function to immediately exit. You will want to do something like
return code_remainder, guess_remainder, blackpegs, whitepegs
and then when you call the function, use:
code_remainder, guess_remainder, blackpegs, whitepegs = test_guess(code,guess)
General Tip:
Variables/references declared within a function only exist within that function. You will need to explicitly return those variables/references if you want to use them outside of the function. Of course there are also some exceptions to this rule, but it is best that you stick to this method for now.
blackpegs doesn't have a value unless the else statement is reached. i.e. if guess == code, blackpeg is not defined.
It needs to be set to zero before the if else statements or otherwise addressed prior to being called in the return statement.
Hi I have problems because this function creates the numbers which I wanted but also generates a None. How should I write this code to not produce the NONE
def binary (str):
b = []
for x in str:
b.append(format(ord(x), 'b'))
return ((b))
clave = "1001001000010001001000110111111100110000100011001010100000110001110110011111010010011111000011111001000011101011001101000001110010011110010110000000"
c = list(clave)
msg = binary("Lol")
print("".join(msg))
m = list("".join(msg))
print("Now the right")
def OTP(m,c):
for i in range (0,len(m)):
if c[i]== "1" and m[i]== "1":
m.pop(i)
m.insert(i,"0")
elif c[i] == "1" and m[i] == "0":
m.pop(i)
m.insert(i,"1")
return print("".join(m))
msg1 = OTP(m,c)
print(msg1)
The reason OPT returns none is because you return the return result of the print function -
return print("".join(m))
Which is indeed None. To obtain the string you should just do -
return "".join(m)
I'm generating a dictionary in a function and then returning this dictionary. I can't seem to access the returned dict as a dictionary though despite it being the correct format.. It is treating the data as a string only, ie i can print it but can't print d.keys() or d.items() What the heck am I doing wrong?????
data when printed as a str()
{1: '214902885,214902909', 2: '214902910,214902934', 3: '214902935,214902959', 4: '214902960,214902984', 5: '214902985,214903009', 6: '214903010,214903034', 7: '214903035,214903059', 8: '214903060,214903084', 9: '214903085,214903109', 10: '214903110,214903139'}
Error when I try to print d.items() or d.keys()
print bin_mapping.keys()
AttributeError: 'str' object has no attribute 'keys'
Once I have returned the dict from a function do I have to redefine it as a dictionary? I'd really appreciate some help as I'm super frustrated :/
Thanks,
As suggested here is the code.. Function I'm calling to return the dictionary first..
def models2bins_utr(id,type,start,end,strand):
''' chops up utr's into bins for mC analysis'''
# first deal with 5' UTR
feature_len = (int(end) - int(start))+1
bin_len = int(feature_len) /10
if int(feature_len) < 10:
return 'null'
#continue
else:
# now calculate the coordinates for each of the 10 bins
bin_start = start
d_utr_5 = {}
d_utr_3 = {}
for i in range(1,11):
# set 1-9 first, then round up bin# 10 )
if i != 10:
bin_end = (int(bin_start) +int(bin_len)) -1
if str(type) == 'utr_5':
d_utr_5[i] = str(bin_start)+','+str(bin_end)
elif str(type) == 'utr_3':
d_utr_3[i] = str(bin_start)+','+str(bin_end)
else:
pass
#now set new bin_start
bin_start = int(bin_end) + 1
# now round up last bin
else:
bin_end = end
if str(type) == 'utr_5':
d_utr_5[i] = str(bin_start)+','+str(bin_end)
elif str(type) == 'utr_3':
d_utr_3[i] = str(bin_start)+','+str(bin_end)
else:
pass
if str(type) == 'utr_5':
return d_utr_5
elif str(type) == 'utr_3':
return d_utr_3
Calling the function and trying to access the dict
def main():
# get a list of all the mrnas in the db
mrna_list = get_mrna()
for mrna_id in mrna_list:
print '-----'
print mrna_id
mrna_features = features(mrna_id)
# if feature utr, send to models2bins_utr and return dict
for feature in mrna_features:
id = feature[0]
type = feature[1]
start = feature[2]
end = feature[3]
assembly = feature[4]
strand = feature[5]
if str(type) == 'utr_5' or str(type) == 'utr_3':
bin_mapping = models2bins_utr(id,type,start,end,strand)
print bin_mapping
print bin_mapping.keys()
You return a string early on:
bin_len = int(feature_len) /10
if int(feature_len) < 10:
return 'null'
Perhaps you wanted to raise an exception instead here, or at the very least, return an empty dictionary or use None as a flag value.
If you use None do test for it:
bin_mapping = models2bins_utr(id,type,start,end,strand)
if bin_mapping is not None:
# you got a dictionary.
I'm wondering what return 'null' is supposed to achieve. My guess is that once in a while, you call the function with the wrong parameters and get this string back.
I suggest to throw an exception instead (raise Exception('Not enough arguments') or similar) or to return an empty dict.
You should also learn about repr() because it gives you more information about an object which makes debugging much easier.