Import Variable Substitution Matrices based on string input Python - python

I am trying to import a substitution matrix to implement the Needleman-Wunsch algorithm in Python based on a given input.
If I want to select one Matrix I can do it like this:
from Bio.SubsMat import MatrixInfo as matlist
scoring_mat = matlist.blosum62
What would I have to do If I wanted to import any matrix based on an input? I have this for the moment:
def blosum(name):
index = str(name)
x= "blosum"+index
return x
a= blosum(62)
scoring_mat = matlist.a
Unfortunately, it is giving me the following error:
AttributeError: module 'Bio.SubsMat.MatrixInfo' has no attribute 'a'
What would I have to do to make it work?
Thanks in advance!

Try scoring_mat = getattr(matlist,a) instead. It worked for me.

Related

return a 2d array without brackets

I'm trying to create a function that returns a 2d array without the brackets on the sides of the array, And I can't use print since I'm using this function for a discord bot and want to return the array instead of printing it.
Here's some of my code:
import numpy as np
example_array = np.array([["⚪", "⚪", "⚪"], ["⚪", "⚪", "⚪"], ["⚪", "⚪", "⚪"]])
def get_array():
for row in example_array:
return "".join(map(str,row))
X = print_array()
Here's the output if I print/send X:
⚪⚪⚪
How can I use a function to return the full array?
I think what you want to do is something like this
"".join(["".join(i) for i in example_array])
would give us
'⚪⚪⚪⚪⚪⚪⚪⚪⚪'

Insert newline after equals sign in self documenting f-string in python3.8

With python3.8, a new feature is self documenting format strings. Where one would normally do this:
>>> x = 10.583005244
>>> print(f"x={x}")
x=10.583005244
>>>
One can now do this, with less repetition:
>>> x = 10.583005244
>>> print(f"{x=}")
x=10.583005244
>>>
This works very well for one line string representations. But consider the following scenario:
>>> import numpy as np
>>> some_fairly_long_named_arr = np.random.rand(4,2)
>>> print(f"{some_fairly_long_named_arr=}")
some_fairly_long_named_arr=array([[0.05281443, 0.06559171],
[0.13017109, 0.69505908],
[0.60807431, 0.58159127],
[0.92113252, 0.4950851 ]])
>>>
Here, the first line does not get aligned, which is (arguably) not desirable. I would rather prefer the output of the following:
>>> import numpy as np
>>> some_fairly_long_named_arr = np.random.rand(4,2)
>>> print(f"some_fairly_long_named_arr=\n{some_fairly_long_named_arr!r}")
some_fairly_long_named_arr=
array([[0.06278696, 0.04521056],
[0.33805303, 0.17155518],
[0.9228059 , 0.58935207],
[0.80180669, 0.54939958]])
>>>
Here, the first line of the output is aligned as well, but it defeats the purpose of not repeating the variable name twice in the print statement.
The example is a numpy array, but it could have been a pandas dataframe etc. as well.
Hence, my question is: Can a newline character be inserted after the = sign in self documenting strings?
I tried to add it like this, but it does not work:
>>> print(f"{some_fairly_long_named_arr=\n}")
SyntaxError: f-string expression part cannot include a backslash
I read the docs on format-specification-mini-language, but most of the formatting there only works for simple data types like integers, and I was not able to achieve what I wanted using those that work.
Sorry for the long write-up.
Wouldn't recommend this at all, but for possibility's sake:
import numpy as np
_old_array2string = np.core.arrayprint._array2string
def _array2_nice_string(*args, **kwargs):
non_nice_string = _old_array2string(*args, **kwargs)
dimension_strings = non_nice_string.split("\n")
if len(dimension_strings) > 1:
dimension_string = dimension_strings[1]
dimension_indent = len(dimension_string) - len(dimension_string.lstrip())
return "\n" + " " * dimension_indent + non_nice_string
return non_nice_string
np.core.arrayprint._array2string = _array2_nice_string
Outputs for:
some_fairly_long_named_arr = np.random.rand(2, 2)
print(f"{some_fairly_long_named_arr=}")
some_fairly_long_named_arr=array(
[[0.95900608, 0.79367873],
[0.58616975, 0.17757661]])
and
some_fairly_long_named_arr = np.random.rand(1, 2)
print(f"{some_fairly_long_named_arr=}")
some_fairly_long_named_arr=array([[0.62492772, 0.80453153]]).
I made it so if if the first dimension is 1, it is kept on the same line.
There is a non-internal method np.array2string that I tried to re-assign, but I never got that working. If someone could find a way to re-assign that public function instead of this internally used one, I'd imagine that'd make this solution a lot cleaner.
I figured out a way to accomplish what I wanted, after reading through the CPython source:
import numpy as np
some_fairly_long_named_arr = np.random.rand(4, 2)
print(f"""{some_fairly_long_named_arr =
}""")
Which produces:
some_fairly_long_named_arr =
array([[0.23560777, 0.96297907],
[0.18882751, 0.40712246],
[0.61351814, 0.1981144 ],
[0.27115495, 0.72303859]])
I would rather prefer a solution that worked in a single line, but this seems to be the only way for now. Perhaps another way will be implemented in a later python version.
However note that the indentation on the continuation line has to be removed for the above mentioned method, as such:
# ...some code with indentation...
print(f"""{some_fairly_long_named_arr =
}""")
# ...more code with indentation...
Otherwise, the alignment of the first line is broken again.
I tried using inspect.cleandoc and textwrap.dedent to alleviate this, but could not manage to fix the indentation issue. But perhaps this is the subject of another question.
Edit: After reading this article, I found a single line solution:
f_str_nl = lambda object: f"{chr(10) + str(object)}" # add \n directly
# f_str_nl = lambda object: f"{os.linesep + str(object)}" # add \r\n on windows
print(f"{f_str_nl(some_fairly_long_named_arr) = !s}")
which outputs:
f_str_nl(some_fairly_long_named_arr) =
[[0.26616956 0.59973262]
[0.86601261 0.10119292]
[0.94125617 0.9318651 ]
[0.10401072 0.66893025]]
The only caveat is that the name of the object gets prepended by the name of the custom lambda function, f_str_nl.
I also found that a similar question was already asked here.

Function that will take an index of an image and return its color

I'm trying to write a function that will take an image as input and then return a function that will take an index and return the color of that index. This is what I got so far:
def generator(image):
def index2color(index1):
return image[index1]
return index2color
Lets try it:
generator2 = generator("flower.jpg")
print (generator2((3)))
>>> w
So this will return the index in the string but not the index for the picture. Any suggestions would be greatly appreciated!
You need to read the image in to an appropriate object first, then operate on the image object. Like this:
flower_img = cv2.imread('flower.jpg')
generator2 = generator(flower_img)
Consider working through this for a better understanding of what you can do: https://docs.opencv.org/3.1.0/d3/df2/tutorial_py_basic_ops.html

Can't define a term in Python

First post so I'll try to be specific as possible.
I'm trying to define a term ybar1 in Python. I'm intending for ybar1 to be the average of a list y1
where y1 = [1, 2, 3, 4, 5]
What I'm doing first is:
import numpy as np
then defining a new function
def funk(y1):
print np.sum(y1)/len(y1)
return;
So now when I compute funk(y1) I get a number, 3
Now is where it gets weird. I try to say:
ybar1 = funk(y1)
, which returns the value 3
but then when I type ybar1 alone, I get no output.
Thoughts?
Try this:
def funk(y1):
return np.sum(y1)/len(y1)
You were not actually returning a value from the function, only printing a result on the console. Also, there's a better way to compute the average using numpy:
def funk(y1):
return np.mean(y1)

Evaluating a formula given by user for multiple values

I am writing a python script that needs to take an equation from a user in the form of something like this
z=x^2+3x+9 +y^3 or z =cos(pi/2+x) + 2sin(y)
and evaluate the function at runtime over many values for x and y. How would I go about using the input given by a user as a function? Meaning I would like to be able to do something like this:
input = input("please input 3 variable function.")
function = evaluate_function(input)
for x and y:
result = evaluate function
return result
Is something like this possible? I have looked around and the closed thing I have found to what I want to do seems to be this (How to process user supplied formulas?), but it is only talking about evaluating for a single value of x and z not iterating over many values. Any help would be greatly appreciated.
Update: As suggested below I found this (http://lybniz2.sourceforge.net/safeeval.html) about using eval() which seems to be pretty much what I want to do
Interpreting math formulas is sympy's domain. parse_expr is its safe parsing function, and its global_dict and local_dict arguments govern what predefined symbols are available.
Yes, parsing and substitution should work:
from sympy.parsing.sympy_parser import parse_expr
eq = parse_expr(raw_input('enter an equation of x, y and/or z'))
for v in ((1,2,3),(1,2,4)):
res = eq.subs(dict(zip((x,y,z),v)))
dat = (tuple(v) + (eq, res))
print('at x=%s, y=%s, z=%, %s = %s' % dat)

Categories

Resources