```python
import pandas as pd
data = pd.read_csv('./seaborn-data/flights.csv')
```

```python
html = data.to_html()
```

```python
data2 = pd.read_csv("C:/Users/NickC/Desktop/Acid buffer.csv")
```

```python
html2 = data2.to_html()
```

```python
html2
```

    '
\n
\n
\n      	\n      Acid	\n      Molecular Formular	\n      Ka	\n      pKa	\n
\n
\n
\n
\n      0	\n      trichloroacetic acid	\n      CCl3COOH	\n      3.020000e-01	\n      0.52	\n
\n
\n      1	\n      benzene sulfonic acid	\n      C6H5SO3H	\n      2.000000e-01	\n      0.70	\n
\n
\n      2	\n      iodic acid	\n      HIO3	\n      1.700000e-01	\n      0.77	\n
\n
\n      3	\n      sulfurous acid	\n      H2SO3	\n      1.550000e-02	\n      1.81	\n
\n
\n      4	\n      chlorous acid	\n      HClO2	\n      1.000000e-02	\n      2.00	\n
\n
\n      5	\n      phosphoric acid	\n      H3PO4	\n      7.590000e-03	\n      2.12	\n
\n
\n      6	\n      chloroacetic acid	\n      CH2ClCOOH	\n      1.410000e-03	\n      2.85	\n
\n
\n      7	\n      lactic acid	\n      CH3CH(OH)COOH	\n      8.320000e-04	\n      3.08	\n
\n
\n      8	\n      nitrous acid	\n      HNO2	\n      4.270000e-04	\n      3.37	\n
\n
\n      9	\n      hydrofluoric acid	\n      HF	\n      3.550000e-04	\n      3.45	\n
\n
\n      10	\n      formic acid	\n      HCOOH	\n      1.780000e-04	\n      3.75	\n
\n
\n      11	\n      benzoic acid	\n      C6H5COOH	\n      6.460000e-05	\n      4.19	\n
\n
\n      12	\n      acetic acid	\n      CH3COOH	\n      1.780000e-05	\n      4.75	\n
\n
\n      13	\n      carbonic acid	\n      H2CO3	\n      4.270000e-07	\n      6.37	\n
\n
\n      14	\n      hypochlorous acid	\n      HClO	\n      2.950000e-08	\n      7.53	\n
\n
\n      15	\n      hypobromous acid	\n      HBrO	\n      2.040000e-09	\n      8.69	\n
\n
\n      16	\n      boric acid	\n      B(OH)3†	\n      7.240000e-10	\n      9.14	\n
\n
\n      17	\n      hydrocyanic acid	\n      HCN	\n      4.900000e-10	\n      9.31	\n
\n
\n      18	\n      phenol	\n      C6H5OH	\n      1.290000e-10	\n      9.89	\n
\n
\n      19	\n      hypoiodous acid	\n      HIO	\n      2.290000e-11	\n      10.64	\n
\n
\n
'

```python
data3 = pd.read_csv("C:/Users/NickC/Desktop/Typical acid buffer.csv")
```

```python
html3 = data3.to_html()
```

```python
html3
```

    '
\n
\n
\n      	\n      Acid buffers	\n      pKa	\n      Base buffers	\n      pka	\n
\n
\n
\n
\n      0	\n      CH3COOH/CH3CO2–	\n      4.75	\n      NH4+/NH3	\n      9.25	\n
\n
\n      1	\n      HNO2/NO2–	\n      3.37	\n      (CH3)3NH+/(CH3)3N	\n      9.81	\n
\n
\n      2	\n      HClO2/ClO2–	\n      2.00	\n      H2PO4–/HPO42–	\n      7.21	\n
\n
\n
'

```python
import math
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
    #获得浮点类型numpy数组
    x = np.arange(1.1,3,0.05)
    #获得函数结果
    y1 = [4.75 + math.log(10, a) for a in x]
    #画图
    plt.plot(x, y1, linewidth=2, color='#007500', label='log10(x) + 4.75')
    #在坐标1处描红
    plt.plot([1,1],[y1[0], y1[1]],"r--",linewidth=2)

    y2 = [6.75 + math.log(10,a) for a in x]
    plt.plot(x,y2, linewidth=2,color='#9F35FF', label='log10(x) + 6.75')

    y3 = [7.75 + math.log(10,a) for a in x]
    plt.plot(x, y3, linewidth=2, color='#f75000', label='log10(x) +7.75')

    plt.legend(loc='lower right')#在右下角显示计算用的函数
    plt.grid(True)#在坐标系上画格子
    #打印图片
    plt.show()
```

```python
import math
import matplotlib.pyplot as plt
import numpy as np
from math import log
x1 = np.arange(0.000001,1,0.0001)
y1 = np.log10(x1) + 1

x2 = np.arange(0.000000001,0.000001,0.0000000001)
y2 = np.log10(x2) + 1

plt.plot(x1,y1)
plt.plot(x2,y2)
plt.grid(True)
plt.show()
```

```python
import sympy
import numpy as np
import math
x = sympy.Symbol('x')
y = x*(0.5+x)*10**(4)/(1.77*(1-x))
print(sympy.solve(x*(0.5+x)*10**(4)/(1.77*(1-x))-1,x))
```

    [-0.500530624715971, 0.000353624715971055]

```python
-math.log10(3.54*10**(-4))
```

    3.450996737974212

```python
import sympy
import numpy as np
import math
x = sympy.Symbol('x')
y = x*(0.4+x)*10**(4)/(1.77*(1.1-x))
print(sympy.solve(y-1,x))
```

    [-0.400662944614088, 0.000485944614088362]

```python
-math.log10(4.85*10**(-4))
```

    3.3142582613977365

# Chapter 12
## if Tests and Syntax Rules

This chapter presents the Python if statement, which is the main statement used for selecting from alternative actions based on test results. Because this is our first in-depth look at compound statements—statements that embed other statements—we will also explore the general concepts behind the Python statement syntax model here in more detail than we did in the introduction in Chapter 10. Because the if statement introduces the notion of tests, this chapter will also deal with Boolean expressions and fill in some details on truth tests in general.

# General Format
The Python if statement is typical of if statements in most procedural languages. It
takes the form of an if test, followed by one or more optional elif (“else if”) tests and
a final optional else block. The tests and the else part each have an associated block
of nested statements, indented under a header line. When the if statement runs, Python
executes the block of code associated with the first test that evaluates to true, or the
else block if all tests prove false. The general form of an if statement looks like this

```python
if 1:
    print('true')
elif 2:
    print('I saw what I saw. I saw whitewalker.')
```

    true

# General Format

if <test1>:          # if test

    <statements1>    # Associated block

elif <test2>:

    <statements2>    # Optional else

else:

    <statements3>

# Multiway Branching

```python
x = 'killer rabbit'
if x == 'roger':
    print("how's jessica?")
elif x == 'bugs':
    print("what's up doc?")
else:
    print("Run away! Run away!")
```

    Run away! Run away!

```python
choice = 'ham'
print({'spam':1.25,'ham':1.99,'eggs':0.99,'bacon':1.10}[choice])
```

    1.99

```python
from sympy import *
init_printing()
init_session()
```

    IPython console for SymPy 1.4 (Python 3.7.4-64-bit) (ground types: python)

    These commands were executed:
    >>> from __future__ import division
    >>> from sympy import *
    >>> x, y, z, t = symbols('x y z t')
    >>> k, m, n = symbols('k m n', integer=True)
    >>> f, g, h = symbols('f g h', cls=Function)
    >>> init_printing()

    Documentation can be found at https://docs.sympy.org/1.4/

```python
import math
```

```python
math.sqrt(3)*math.tan(math.radians(18)) + math.tan(math.radians(18))*math.tan(math.radians(12)) + math.sqrt(3)*math.tan(math.radians(12))
```

```python
expand(exp(x))
```

```python
series(exp(-x))
```

```python
plot(log(2**x+2**(x**2))-Rational(7,8))
solveset(log(2**x+2**(x**2))-Rational(7,8),x)
```

```python
simplify_logic(log(2**x+2**(x**2)) > Rational(7,8))
```

```python
summation(1/(2*n-1)-1/(2*n),(n,1,10000))-2**(0.5)/2
```

```python
x = 'killer rabbit'
if x == 'roger':
    print("how's jessica?")
elif x == 'bugs':
    print("what's up doc?")
else:
    print("Run away! Run away!")
```

    Run away! Run away!

```python
choice = 'ham'
print({'spam': 1.25, 'ham': 1.99, 'eggs': 0.99, 'bacon': 0.10}[choice])
```

    1.99

```python
if choice == 'spam':
    print(1.25)
elif choice == 'ham':
    print(1.99)
elif choice == 'eggs':
    print(0.99)
elif choice == 'bacon':
    print(1.10)
else:
    print('Bad choice')
```

    1.99

```python
branch = {'spam': 1.25, 'ham': 1.99, 'eggs': 0.99}
print(branch.get('spam','Bad choice'))
print(branch.get('bacon','Bad choice'))
```

    1.25
    Bad choice

```python
choice = 'bacon'
if choice in branch:
    print(branch[choice])
else:
    print("Bad choice")
```

    Bad choice

# Python Syntax Rules

# Python has a simple, statement-based syntax
## Statements execute one after another, until you say otherwise
### Because Python's path through a program is called the control flow, statements such as if that affect it are often called control-flow statements
## Block and statement boundaries are detected automatically
### Python uses the indentation of statements under a header to group the statements in a nested block. Similarly, Python statements are not normally terminated with semicolons, rather, the end of a line usually marks the end of the statement coded on that line.
## Compound statements = header + ":" + indented statements.
### The indented statements are called a block (or sometimes, a suite). In the if statement, the elif and else clauses are part of the if, but they are also header lines withe nested blocks of their own.
## Blank lines, spaces, and comments are usually ignored.
### Spaces inside statements and expressions are almost always ignored (except in string literals, and when used for indentation). Comments are always ignored: they start with a # character (not inside a string literal) and extend to the end of the current line.
## Docstrings are ignored but are saved and displayed by tools
### Docstrings are part of Python's larger documentation strategy and are covered in the last chapter in this part of the book.

```python
from sympy import *
init_printing()
init_session()
```

    IPython console for SymPy 1.4 (Python 3.7.4-64-bit) (ground types: python)

    These commands were executed:
    >>> from __future__ import division
    >>> from sympy import *
    >>> x, y, z, t = symbols('x y z t')
    >>> k, m, n = symbols('k m n', integer=True)
    >>> f, g, h = symbols('f g h', cls=Function)
    >>> init_printing()

    Documentation can be found at https://docs.sympy.org/1.4/

```python
limit(summation(1/n**2,(n,1,oo)),n,oo)
```

```python
float(pi**2/6)
```

```python
summation(1/n**2,(n,1,oo))
```

```python
float(summation(1/n**2,(n,1,10000)))
```

```python
pprint(series(sin(x)))
pprint(series(cos(x)))
```

         3     5
        x     x     ⎛ 6⎞
    x - ── + ─── + O⎝x ⎠
        6    120
         2    4
        x    x     ⎛ 6⎞
    1 - ── + ── + O⎝x ⎠
        2    24

# Block Delimiters: Indentation Rules

```python
x = 1
if x:
    y=2
    if y:
        print('block2')
    print('block1')
print('block0')
```

    block2
    block1
    block0

```python
   x ='spam'
if 'rubbery' in 'shrubbery':
    print(x*8)
```

    spamspamspamspamspamspamspamspam

```python
A1 = -13.212; B1 = -13122.470; C1= 4.354; D1 = -0.00330;
```

```python
from sympy import *
init_printing()
init_session()
T,ratio,Fsteam,Kp,x,P,F0 = symbols('T, ratio, Fsteam,Kp,x,P,F0')
```

    IPython console for SymPy 1.4 (Python 3.7.4-64-bit) (ground types: python)

    These commands were executed:
    >>> from __future__ import division
    >>> from sympy import *
    >>> x, y, z, t = symbols('x y z t')
    >>> k, m, n = symbols('k m n', integer=True)
    >>> f, g, h = symbols('f g h', cls=Function)
    >>> init_printing()

    Documentation can be found at https://docs.sympy.org/1.4/

```python
def KT(T):
    return exp(A1 + B1/T + C1*log(T,10) + D1*T)*10**5
```

```python
print(KT(T))
```

    0.18285266951191*T**(4.354/log(10))*exp(-0.0033*T - 13122.47/T)

```python
plot(KT(T),(T,600,1500))
```

```python
simplify(solveset(Kp-(P*x**2)/((1-x)*(1+x+Fsteam/F0)),x))
```

$\displaystyle \left\{\frac{- Fsteam Kp + \sqrt{Kp \left(4 F_{0}^{2} Kp + 4 F_{0}^{2} P + 4 F_{0} Fsteam Kp + 4 F_{0} Fsteam P + Fsteam^{2} Kp\right)}}{2 F_{0} \left(Kp + P\right)}, - \frac{Fsteam Kp + \sqrt{Kp \left(4 F_{0}^{2} Kp + 4 F_{0}^{2} P + 4 F_{0} Fsteam Kp + 4 F_{0} Fsteam P + Fsteam^{2} Kp\right)}}{2 F_{0} \left(Kp + P\right)}\right\} \setminus \left\{1, - \frac{F_{0} + Fsteam}{F_{0}}\right\}$

```python
F0 = 152.2
def Conv1(T):
    return (sqrt(4*F0*(1.7 + KT(T))*KT(T)*F0))/(2*F0*(1.7+KT(T)))
```

```python
plot(Conv1(T),(T,500,2000))
```

```python
def Conversion(T):
    return (-KT(T)*152.2*3.5+sqrt((KT(T)*152.2*3.5)**2+4*152.2*(1.7+KT(T))*KT(T)*(152.2+152.2*3.5)))/(2*152.2*(1.7+KT(T)))
```

```python
plot(Conversion(T),(T,500,2000))
```

# A Few Special Cases

```python
L = ["Good",
    "Bad",

    "Ugly"] # Open pairs may span lines
```

```python
a = b = 1.03; c = d = e = 'str'; f = g = [a, b, c, d, e, f, g];
if a == b and c == d and \
d == e and f == g:
    print('olde') # Backslashes allow continuations...
```

    olde

```python
f = e
if (a == b and c == d and
   d == e and e == f):
    print(sin(x))
```

    sin(x)

```python
x = 1 + 2 + 3\
+ 4
```

```python
print(x)
```

    10

# Truth Tests

# In Python:
-------------------------------------------------------------------------------
* Any nonzero number or nonempty object is true.
* Zero numbers, empty object, and the special object None are considered false.
* Comparisons and equality tests are applied recursively to data structures.
* Boolean and and or operators return a true or false operand object.
-------------------------------------------------------------------------------

```python
if 1 and 2:
    print("Is true if both X and Y are True")
if 1 or 0:
    print("Is true if either X or Y is true")
if not None:
    print("Is true if X is false (the expression returns True or False)")
```

    Is true if both X and Y are True
    Is true if either X or Y is true
    Is true if X is false (the expression returns True or False)

```python
2 < 3, 3 < 2 # Less-than: return True or False (1 or 0)
```

    (True, False)

```python
print(2 and 3, 3 and 2,\
      # Return left operand if false
[] and {},\
3 and [])
```

    3 2 [] []

```python
from sympy import *
init_session()
```

    IPython console for SymPy 1.4 (Python 3.7.4-64-bit) (ground types: python)

    These commands were executed:
    >>> from __future__ import division
    >>> from sympy import *
    >>> x, y, z, t = symbols('x y z t')
    >>> k, m, n = symbols('k m n', integer=True)
    >>> f, g, h = symbols('f g h', cls=Function)
    >>> init_printing()

    Documentation can be found at https://docs.sympy.org/1.4/

```python
a11,a12,a13,a21,a22,a23,a31,a32,a33=symbols("a11,a12,a13,a21,a22,a23,a31,a32,a33")
b11,b12,b13,b21,b22,b23,b31,b32,b33=symbols("b11,b12,b13,b21,b22,b23,b31,b32,b33")
```

```python
help(matrix_multiply_elementwise)
```

    Help on function matrix_multiply_elementwise in module sympy.matrices.dense:

    matrix_multiply_elementwise(A, B)
        Return the Hadamard product (elementwise product) of A and B

        >>> from sympy.matrices import matrix_multiply_elementwise
        >>> from sympy.matrices import Matrix
        >>> A = Matrix([[0, 1, 2], [3, 4, 5]])
        >>> B = Matrix([[1, 10, 100], [100, 10, 1]])
        >>> matrix_multiply_elementwise(A, B)
        Matrix([
        [  0, 10, 200],
        [300, 40,   5]])

        See Also
        ========

        __mul__

```python
A = Matrix([[a11, a12, a13], [a21, a22, a23],[a31,a32,a33]])
B = Matrix([[b11, b12, b13],[b21, b22, b23],[b31,b32,b33]])
```

```python
matrix_multiply_elementwise(A,B)
```

$\displaystyle \left[\begin{matrix}a_{11} b_{11} & a_{12} b_{12} & a_{13} b_{13}\\a_{21} b_{21} & a_{22} b_{22} & a_{23} b_{23}\\a_{31} b_{31} & a_{32} b_{32} & a_{33} b_{33}\end{matrix}\right]$

```python
A, B, A * B
```

$\displaystyle \left( \left[\begin{matrix}a_{11} & a_{12} & a_{13}\\a_{21} & a_{22} & a_{23}\\a_{31} & a_{32} & a_{33}\end{matrix}\right], \  \left[\begin{matrix}b_{11} & b_{12} & b_{13}\\b_{21} & b_{22} & b_{23}\\b_{31} & b_{32} & b_{33}\end{matrix}\right], \  \left[\begin{matrix}a_{11} b_{11} + a_{12} b_{21} + a_{13} b_{31} & a_{11} b_{12} + a_{12} b_{22} + a_{13} b_{32} & a_{11} b_{13} + a_{12} b_{23} + a_{13} b_{33}\\a_{21} b_{11} + a_{22} b_{21} + a_{23} b_{31} & a_{21} b_{12} + a_{22} b_{22} + a_{23} b_{32} & a_{21} b_{13} + a_{22} b_{23} + a_{23} b_{33}\\a_{31} b_{11} + a_{32} b_{21} + a_{33} b_{31} & a_{31} b_{12} + a_{32} b_{22} + a_{33} b_{32} & a_{31} b_{13} + a_{32} b_{23} + a_{33} b_{33}\end{matrix}\right]\right)$

```python
Vx,Vy,Vz = symbols("Vx,Vy,Vz")
Wx,Wy,Wz = symbols("Wx,Wy,Wz")
```

```python
V = Matrix([[Vx],[Vy],[Vz]])
W = Matrix([[Wx],[Wy],[Wz]])
```

```python
matrix_multiply_elementwise(V,W) == matrix_multiply_elementwise(W,V)
```

    True

```python
from sympy.vector import CoordSys3D
a = CoordSys3D('a')
b = a.create_new('b', transformation='spherical')
```

```python
b.transformation_from_parent()
```

```python
b.transformation_to_parent()
```

```python
from sympy import *
from sympy.vector import CoordSys3D
C = CoordSys3D('C')
Vx,Vy,Vz = symbols("Vx,Vy,Vz")
Wx,Wy,Wz = symbols("Wx,Wy,Wz")
```

```python
V = Vx*C.i + Vy*C.j + Vz*C.k
W = Wx*C.i + Wy*C.j + Wz*C.k
```

```python
init_printing()
print(V.cross(W))
print(W.cross(V))
```

    (Vy*Wz - Vz*Wy)*C.i + (-Vx*Wz + Vz*Wx)*C.j + (Vx*Wy - Vy*Wx)*C.k
    (-Vy*Wz + Vz*Wy)*C.i + (Vx*Wz - Vz*Wx)*C.j + (-Vx*Wy + Vy*Wx)*C.k

```python
(V.cross(W)).components
```

```python
V.dot(W) == W.dot(V)
```

    True

```python
Txx,Txy,Txz = symbols("Txx Txy Txz")
Tyx,Tyy,Tyz = symbols("Tyx Tyy Tyz")
Tzx,Tzy,Tzz = symbols("Tzx Tzy Tzz")
T = Matrix([[Txx,Txy,Txz],[Tyx,Tyy,Tyz],[Tzx,Tzy,Tzz]])
```

```python
V.to_matrix(C)
```

$\displaystyle \left[\begin{matrix}Vx\\Vy\\Vz\end{matrix}\right]$

```python
help(mathematica_code)
```

    Help on function mathematica_code in module sympy.printing.mathematica:

    mathematica_code(expr, **settings)
        Converts an expr to a string of the Wolfram Mathematica code

        Examples
        ========

        >>> from sympy import mathematica_code as mcode, symbols, sin
        >>> x = symbols('x')
        >>> mcode(sin(x).series(x).removeO())
        '(1/120)*x^5 - 1/6*x^3 + x'

```python
type(T)
```

    sympy.matrices.dense.MutableDenseMatrix

```python
from sympy import init_printing, Matrix
init_printing(use_unicode=True)
```

```python
T
```

$\displaystyle \left[\begin{matrix}Txx & Txy & Txz\\Tyx & Tyy & Tyz\\Tzx & Tzy & Tzz\end{matrix}\right]$

```python
help(T.cross)
```

    Help on method cross in module sympy.matrices.matrices:

    cross(b) method of sympy.matrices.dense.MutableDenseMatrix instance
        Return the cross product of ``self`` and ``b`` relaxing the condition
        of compatible dimensions: if each has 3 elements, a matrix of the
        same type and shape as ``self`` will be returned. If ``b`` has the same
        shape as ``self`` then common identities for the cross product (like
        `a \times b = - b \times a`) will hold.

        Parameters
        ==========
            b : 3x1 or 1x3 Matrix

        See Also
        ========

        dot
        multiply
        multiply_elementwise

```python
V = Matrix([[Vx], [Vy], [Vz]])
```

```python
T*V
```

$\displaystyle \left[\begin{matrix}Txx Vx + Txy Vy + Txz Vz\\Tyx Vx + Tyy Vy + Tyz Vz\\Tzx Vx + Tzy Vy + Tzz Vz\end{matrix}\right]$

```python
Matrix([(T.col(0)).dot(V), (T.col(1)).dot(V), (T.col(2)).dot(V)])
```

$\displaystyle \left[\begin{matrix}Txx Vx + Tyx Vy + Tzx Vz\\Txy Vx + Tyy Vy + Tzy Vz\\Txz Vx + Tyz Vy + Tzz Vz\end{matrix}\right]$

```python
## 1 gradient
from sympy import *
from sympy.vector import Del, gradient
init_session()
C = CoordSys3D('C')
delop = Del() # nabla算子

# 标量场 f = x**2*y-xy
f = C.x**2*C.y - C.x*C.y

res = delop.gradient(f, doit=True) # 使用nabla算子
# res = delop(f).doit()
res = gradient(f) # 直接使用gradient

print(res) # (2*C.x*C.y - C.y)*C.i + (C.x**2 - C.x)*C.j
```

    IPython console for SymPy 1.4 (Python 3.7.4-64-bit) (ground types: python)

    These commands were executed:
    >>> from __future__ import division
    >>> from sympy import *
    >>> x, y, z, t = symbols('x y z t')
    >>> k, m, n = symbols('k m n', integer=True)
    >>> f, g, h = symbols('f g h', cls=Function)
    >>> init_printing()

    Documentation can be found at https://docs.sympy.org/1.4/

    (2*C.x*C.y - C.y)*C.i + (C.x**2 - C.x)*C.j

```python
init_printing(use_unicode=True)
print(x**2*y-x*y)
```

    x**2*y - x*y

```python
from sympy import mathematica_code as mcode
mcode(x**2*y-x*y)
```

    'x^2*y - x*y'

```python
V.dot(W)
```

$\displaystyle Vx Wx + Vy Wy + Vz Wz$

```python
A  = 't' if 'spam' else 'f' # Nonempty is None
```

```python
A
```

    't'

```python
A = 't' if '' else 'f'
```

```python
A
```

    'f'

```python
['f','t'][bool('')]
```

    'f'

```python
['f','t'][bool('spam')]
```

    't'

# Chapter Summary

In this chapter, we studied the Python if statement. Additionally, because this was our
first compound and logical statement, we reviewed Python’s general syntax rules and
explored the operation of truth tests in more depth than we were able to previously.
Along the way, we also looked at how to code multiway branching in Python and
learned about the if/else expression introduced in Python 2.5.
The next chapter continues our look at procedural statements by expanding on the
while and for loops. There, we’ll learn about alternative ways to code loops in Python,
some of which may be better than others. Before that, though, here is the usual chapter
quiz.

```python

```

Chapter 12 if Tests and Syntax Rules .ipynb


# Examples of usage

```python
import rna
from BasePredictor import BasePredictor
from NaivePredictor import NaivePredictor
from GeneticPredictor import GeneticPredictor
from MFTPredictor import MFTPredictor

%matplotlib inline
```

    Using gpu device 0: GeForce GTX 970M (CNMeM is disabled, cuDNN not available)

### Data
Examples are loaded from a file in FASTA-like format (see secondary.fa as an example). If you don't want to load RNA sequences with provided method, you can insert your data directly to predictor's **train** method. Such data should be a numpy array, and its dimensions should be $(n \times 2)$, wherein the first column contains RNA sequences, and the second column contains bracket notations that describe the secondary structure.

### Naïve Predictor
This predictor is a simple MLP. It looks for the most similar RNA sequence in training data and applies the same structure to predicted sequence. The performance of such a predictor is not very good, but it can be quite accurate when there exists a homologous RNA sequence in training examples. One can use Genetic Predictor afterwards, to improve the result.

```python
p = NaivePredictor(22, substrings=False, max_examples=100, library='lasagne', data_model='matrix')
X = p.load_data("secondary.fa", capitalize=True, purify=True, repair=True)
print("Shape of the data:")
print(X.shape)

print("\nA few of loaded examples:")
print(X[:10])
```

    Shape of the data:
    (939, 2)

    A few of loaded examples:
    [['GGCGUAAGGAUUACCUAUGCC' '(((((..((....)).)))))']
     ['GGACUAGCGGAGGCUAGUCC' '(((..(((....)))..)))']
     ['GCGCUGACAAAGCGC' '(((((.....)))))']
     ['GGCCGAUGGUAGUGUGGGGUCUCCCCAUGCGAGAGUAGGCC'
      '((((.......(((((((.....))))))).......))))']
     ['GGGAGCUCAACUCUCCCCCCCUUUUCCGAGGGUCAUCGGAACCA'
      '(((((.......))))).......(((((......)))))....']
     ['GGGUGACUCCAGAGGUCGAGAGACCGGAGAUAUCACCC'
      '((((((((((...((((....))))))))...))))))']
     ['GGUGUGAACACC' '((((....))))']
     ['GACAGGGGAAACUUUGUC' '(((((((....)))))))']
     ['GCCAGAUUGAGCCUGGGAGCUCUCUGGCC' '((((((..((((......)))))))))).']
     ['GGCCAGAUUGAGCCUGGGAGCUCUCUGGCC' '(((((((..((((......)))))))))))']]

### Molecule class
You can store RNA sequences as an instance of Molecule class. It provides tools for the structure visualization.

```python
m = rna.Molecule(X[1, 0], X[1, 1])
rna.pair_matrix(m, show=True)
rna.complementarity_matrix(m, show=True)
m.show()
```

```python
p.train()
print("We will be trying to predict the secondary structure of the following sequence: GGCCUGAGGAGACUCAGAAGCC.\n")
print(p.predict("GGCCUGAGGAGACUCAGAAGCC"))
print("\nThis is the correct structure. Next tests check if our predictor can cope with slightly different sequences (reverse sequence or changed basepairs).\n")
print(p.predict("GGCCUGAGGAGACUCAGAAGCC"[::-1]))
print(p.predict("CCCCUGAGGAGACUCAGAAGGG"))
print(p.predict("AUCCUGAGGAGACUCAGAAGAU"))
print(p.predict("AUCGUGAUGAGACUCAAAAGAU"))
```

    We will be trying to predict the secondary structure of the following sequence: GGCCUGAGGAGACUCAGAAGCC.

    0.994215 0.363563
    GGCCUGAGGAGACUCAGAAGCC
    (((((((......))))..)))

    This is the correct structure. Next tests check if our predictor can cope with slightly different sequences (reverse sequence or changed basepairs).

    0.929067 0.999614
    CCGAAGACUCAGAGGAGUCCGG
    (((..((((......)))))))
    0.554652 0.453151
    CCCCUGAGGAGACUCAGAAGGG
    (((((((......))))..)))
    0.868492 0.443768
    AUCCUGAGGAGACUCAGAAGAU
    (((((((......))))..)))
    0.694795 0.792209
    AUCGUGAUGAGACUCAAAAGAU
    (((((((((....)))))))))

### Genetic Predictor
As we see, sometimes finding the most similar structure is not enough. We should find a way to improve our results, so let us try a different approach to the problem. A simple genetic algorithm can repair sequences with incorrect basepairs and sharp loops. Then it makes random connections and evaluates the new structure.

Let's look at the last prediction of our Naive Predictor. Obviously, it is not the correct structure. We can try to improve the result with a Genetic Predictor.

```python
p = GeneticPredictor(num_epoch=20)
p.predict(rna.Molecule("AUCGUGAUGAGACUCAAAAGAU", "(((((((((....)))))))))"))
```

    [
     AUCGUGAUGAGACUCAAAAGAU
     (((.(((......)))...))),
     AUCGUGAUGAGACUCAAAAGAU
     (((.(((......))..).))),
     AUCGUGAUGAGACUCAAAAGAU
     (((.(..((.....))..)))),
     AUCGUGAUGAGACUCAAAAGAU
     (((.(((......)).)..))),
     AUCGUGAUGAGACUCAAAAGAU
     (((.(..((.....)).).)))]

One of the structures of the last population looks better than others:

It is indeed one of the most probable structures according to other predictors that you can find online, e.g. [this web server](http://rna.urmc.rochester.edu/RNAstructureWeb/Servers/Predict1/Predict1.html).

The last example will show that Genetic Predictor can make predictions from scratch. It makes it competitive with other more complex predictors. Its decision process is almost completely random, and it may converge to local minima, but it has very simple implementation, which makes it faster than other predictors. Let's try to predict the same sequence the Naive Predictor has earlier predicted correctly.

```python
predictions = []

# we use the predictor 10 times and choose the best result to avoid locality
for test in range(10):
    predictions += p.predict(rna.Molecule("GGCCUGAGGAGACUCAGAAGCC"))

print(sorted(predictions, key=lambda x: x.evaluate())[-3:])
```

    [
    GGCCUGAGGAGACUCAGAAGCC
    ((((((((....)))))..)))
    ,
    GGCCUGAGGAGACUCAGAAGCC
    ((((((((....)))))..)))
    ,
    GGCCUGAGGAGACUCAGAAGCC
    ((((((((....)))))..)))
    ]

The prediction is correct.

### MFT Predictor
MFT Predictor is based on [this article](http://aitopics.org/sites/default/files/classic/Hunter/03-Steeg.pdf) (Steeg). The network works similarly to Hopfield networks. However, neurons can have activation level equal to any number $a_i \in [0, 1]$, and not only binary. The activation function is given by the formula:

\begin{equation}
a_i = \sum_j a_j w_{ij} + f(i),
\end{equation}
where
- $a_i$ - activation of $i$-th neuron,
- $w_{ij}$ - edge weight between neurons $i$ and $j$,
- $f(i)$ - node weight for neuron's basepair.

```python
p = MFTPredictor(num_epoch=100, alpha=6, beta=8, gamma=30, temperature=1/5)
predictions = []
for i in range(10):
    print(p.predict(rna.Molecule("GGCCUGAGGAGACUCAGAAGCC")))
```

    GGCCUGAGGAGACUCAGAAGCC
    (((.(..(((..)))..).)))
    GGCCUGAGGAGACUCAGAAGCC
    (((.(...((...))..).)))
    GGCCUGAGGAGACUCAGAAGCC
    ((.((....))...).....).
    GGCCUGAGGAGACUCAGAAGCC
    (((.(.....(...)...))))
    GGCCUGAGGAGACUCAGAAGCC
    ((((((((....)))))..)))
    GGCCUGAGGAGACUCAGAAGCC
    (......(....((...).)))
    GGCCUGAGGAGACUCAGAAGCC
    ((.((....)).).).(...).
    GGCCUGAGGAGACUCAGAAGCC
    (((.(...((...))..).)))
    GGCCUGAGGAGACUCAGAAGCC
    (.(....)(...(...)...))
    GGCCUGAGGAGACUCAGAAGCC
    ((((((((....)))))..)))

It seems that this predictor can produce good predictions, but it is dependent on many parameters that can be learnt from data. However, the training method is not well implemented yet.

```python

```


# Homework 3
### Due Date:  Tuesday, September 19th at 11:59 PM

---
## Problem 1:  `Git` and recovering from a mistake
You will do this problem in the Jupyter notebook so I can see your output.  Once again, you will work with your playground repository.

**NOTE:** At the beginning of each cell, you MUST type `%%bash`.  If you don't do that then you will not be able to work with the necessary bash commands.

Follow the following steps for this problem:

1. First cell:
  1. Type `cd /tmp` to enter the temporary directory
  2. git clone url_to_your_playground_repo
2. Second cell:
  1. Go into your local `playground` directory (`cd /tmp/playground`)
  2. Type `git pull origin mybranch1`
  3. `ls`
3. Third cell:
  1. Go into your local `playground` directory (`cd /tmp/playground`)
  2. Type `git status`
4. Fourth cell:
  1. Go into your local `playground` directory (`cd /tmp/playground`)
  2. Type `git reset --hard origin/master`
  3. `ls`
5. Fifth cell:
  1. Go into your local `playground` directory (`cd /tmp/playground`)
  2. Type `git status`

The whole point of this problem was to show you how to get your local repo back to an earlier state.  In this exercise, you accidentally merged something to `master` that you didn't want.  Rather than starting to delete things all over the place, you can simply reset your `HEAD` to a previous commit.

## Problem 2:  `Git` and checking out a single file
Sometimes you don't want to merge an entire branch from the upstream but just one file from it. There is a direct use case for such a situation. Suppose I've made an error in this homework (or a lecture) and want to correct it. I fix the mistake in the upstream repo. In the meantime you have edited some other files and you really don't want to manually ignore my older copies of those files. Rather, you want to fix just one file from this new branch. This is how you do it.

As usual, be sure to type in `%%bash` before you write any `bash` commands in a cell.

**Note:** The steps below assume that you have already cloned the `playground` repo in this notebook.

1. First cell:
  1. Go into the `playground` repo and fetch the changes from the master branch of the `course` remote.
2. Second cell:
  1. `git checkout course/master -- README.md`.  The `--` means that `README.md` is a file (as opposed to a `branch`).
  2. `cat README.md`.  This just looks at the updated file.
3. Third cell:
  1. `git status`
  2. Commit the changes to your local repo with an appropriate commit message.
  3. `git status`
  4. Push the changes to your remote repo.

## Problem 3
This problem is related to the Lecture 4 exercises.
1. Open the `languages.txt` file.  This file contains all the languages that students listed as their primary language in the course survey.
2. Load the language strings from the file into a list.
3. Use the `Counter` method from the `collections` library to count the number of occurrences of each element of the list.
  + **NOTE:**  It is not necessary to use the `most_common()` method here.
4. Create a bar plot to display the frequency of each language.  Be sure to label the x-axis!
  + Remember, to create plots in the notebook you must put the line `%matplotlib inline` at the beginning of your notebook.
  + Be sure to import matplotlib:  `import matplotlib.pyplot as plt`.
  + To generate the bar plot write `plt.bar(x_coords, freqs)`.  You need to define `x_coords` and `freqs`.
  + **Hint:** You may want to use the `numpy` `arange` function to create `x_coords`.  Remember, `x_coords` is the x-axis and it should have points for each distinct language.
  + **Hint:** To get `freqs`, you may want to use the `values()` method on your result from step 3.  That is, `freqs = result_from_3.values()`.
  + **Hint:** To label the x-axis you should use `plt.xticks(x_coords, labels)` where labels can be accessed through the `keys()` method on your result from step 3.

---
## Problem 4
In chemical kinetics, the reaction rate coefficient for a given reaction depends on the temperature of the system.  The functional relationship between the reaction rate coefficient and temperature is given by the Arrhenius rate:
\begin{align}
k\left(T\right) = A T^{b}\exp\left(-\frac{E}{RT}\right)
\end{align}
where $A$, $b$, and $E$ are parameters, $R = 8.314 \dfrac{\textrm{J}}{\textrm{mol} \textrm{ K}}$  is the universal gas constant, and $T$ is the temperature.

Write a function which returns $k\left(T\right)$ given $A$, $b$, $E$, and $T$.  Here are a few requirements:
* The function should test for exceptions where necessary.
* Pass the parameters $A$, $b$, and $E$ in as a list.
* Make $R$ a keyword argument to the function.

---
## Problem 5
Using `numpy` arrays, plot $k\left(T\right)$ for $T\in\left(0, 5000\right]$ for three different sets of parameters $\left\{A, b, E\right\}$.  Make sure all three lines are on the same figure and be sure to label each line.  You may use the function from Problem 2.  You may want to play with the parameters a little bit to get some nice curves but you won't lose points for ugly curves either (as long as they're correct!).