> For the complete documentation index, see [llms.txt](https://book.ncrnalab.org/teaching/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.ncrnalab.org/teaching/part-i.-programming-skills/3.python.md).

# 3.Python

* python是一种接近伪代码的脚本语言。python开发效率高，简单易读，所以有这样一种说法:

> Life is Short, You Need Python (Bruce Ecke)

* 原生的python和perl语言一样，对文本处理（字符串操作，正则表达式等）有很好的支持，而且比perl语言更加简单易读，所以目前在生物信息分析中应用非常广泛。
* python和R语言一样有非常好的软件生态，这极大地扩展了python的应用场景。
* 在生物信息分析中经常用到的python package既包括一些一般性的工具，也包括一些专门针对生物信息学问题开发的工具。
  * 一般性工具例如:
    * 数值计算和科学计算: [numpy](https://numpy.org/)和[scipy](https://scipy.org/)
    * 处理表格数据: [pandas](https://pandas.pydata.org/)
    * 机器学习算法的实现: [sklearn](https://scikit-learn.org/)
    * 数据可视化: [matplotlib](https://matplotlib.org/)和[seaborn](https://seaborn.pydata.org/)
    * 统计分析: [statsmodel](https://www.statsmodels.org/stable/index.html)
    * ...
  * 专门针对生物信息学问题开发的工具例如:
    * 常用生物信息算法的实现和文件格式的解析[biopython](https://biopython.org/)
    * 读取bam文件: [pysam](https://pysam.readthedocs.io/en/latest/api.html)
    * 高效读取fasta文件: [pyfaidx](https://github.com/mdshw5/pyfaidx)
    * 单细胞测序数据分析: [scanpy](https://scanpy.readthedocs.io/)
    * ...
* 我们能遇到的相当大一部分数据分析的问题，都可以直接用前人已经实现好的python package解决。熟悉这些常用的工具可以让我们从繁琐的编码中解放出来，用很少的代码量解决实际的问题。
* 和学习R语言一样，为了能用好这些已有的工具，我们首先需要熟悉原生python的语法和常用的数据结构。
* 本教程默认使用**python3**

## 0) python语法规范

python非常注意规范的书写语法，以缩进为例，python强制要求使用tabs/spaces来缩进。推荐使用tab或四个空格来缩进。

```python
# use a tab
for i in range(3):
    print(i)
# use 2 spaces
for i in range(3):
  print(i)
# use 4 spaces
for i in range(3):
    print(i)
```

## 1) Basic Practice Guide

### 1.0) 在终端运行python脚本

创建一个python脚本`welcome.py`，在文件中写入如下内容：

```python
print('welcome to python!')
```

在相同目录下运行:

```bash
python welcome.py    #use python to run welcome.py
```

> 你也可以将python的脚本文件做成一个可执行文件，直接执行， 即在python脚本的第一行添加 python的路径：
>
> ```python
> #! /usr/bin/env python
> print('welcome to python!')
> ```
>
> 现在就可以不需要指明python解释器，直接运行python脚本了:

```bash
chmod +x welcome.py  #set the python script as executable
./welcome.py
```

### 1.1) Basic print

```python
print("The \n makes a new line")
print("The \t is a tab")
print('I\'m going to the movies')
```

```python
firstVariable = 'Hello World!'
print(firstVariable)
print(firstVariable.lower())
print(firstVariable.upper())
print(firstVariable.title())
```

### 1.2) Simple Math

```python
print (1+1)
print (130-2.0)
print (126/3)
print (2*3)
print (2**3)
print (10%3)
```

### 1.3) if statement

| Comparison Operator | Function                 |
| ------------------- | ------------------------ |
| <                   | less than                |
| <=                  | less than or equal to    |
| >                   | greater than             |
| >=                  | greater than or equal to |
| ==                  | equal                    |
| !=                  | not equal                |

```python
num = 3
if num % 3 == 0:
    print("if statement satisfied")
```

| Logical Operator | Description                                                                  |
| ---------------- | ---------------------------------------------------------------------------- |
| and              | If both the operands are True then condition becomes True.                   |
| or               | If any of the two operands are True then condition becomes True.             |
| not              | Used to reverse the logical (not False becomes True, not True becomes False) |

```python
# both the conditions are true, so the num will be printed out
num = 3
if num > 0 and num  < 15:
    print(num)
```

### 1.4) else and elif

```python
my_num = 5
if my_num % 2 == 0:
    print("Your number is even")
elif my_num % 2 == 1:
    print("Your number is odd")
else: 
    print("Are you sure your number is an integer?")
```

### 1.5) Swap values

```python
a = 1
b = 2
b, a = a, b
print(a, b)
```

### 1.6) List

请务必注意，python的索引都是**从0开始的**，而不是1！

| z =   | \[3, | 7, | 4, | 2] |
| ----- | ---- | -- | -- | -- |
| index | 0    | 1  | 2  | 3  |

* **Accessing Values in List:**

```python
# Defining a list
z = [3, 7, 4, 2]
```

```python
# The first element of a list is at index 0
z[0]
```

```python
# Access Last Element of List 
z[-1]
```

* **Slicing Lists:**

```python
# first index is inclusive (before the :) and last (after the :) is not. 
# not including index 2
z[0:2]
```

```python
# everything up to index 3
z[:3]
```

```python
# index 1 to end of list
z[1:]
```

* **Minimum, Maximum, Length, and Sum of a list:**

```python
print(min(z), max(z), len(z), sum(z))
```

* **Add to the End of List:**

```python
x = [3, 7, 2, 11, 8, 10, 4]
y = ['Steve', 'Rachel', 'Michael', 'Adam', 'Monica', 'Jessica', 'Lester']
x.append(3)
y.append('James')
print(x)
print(y)
```

* **list comprehension:**

```python
#Use for loops
a = []
for i in range(10):
    a.append(i + 10)
print(a)
```

```python
#Use list comprehension
a = [i + 10 for i in range(10)]
print(a)
```

### 1.7) Dictionary

字典是另一种可变容器模型，可存储任意类型对象。

字典的每个键值 `key->value` 对用冒号 `:` 分割，每个键值对之间用逗号 `,` 分割，整个字典包括在花括号 `{}` 中。

键一般是唯一的，如果重复最后的一个键值对会替换前面的，值不需要唯一。

* **定义和获取字典中的值:**

```python
dict = {'a': 1, 'b': 2, 'b': '3'};
dict['b']
```

* **修改字典：**

```python
dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};

dict['Age'] = 8; # update existing entry
dict['School'] = "DPS School"; # Add new entry


print ("dict['Age']: ", dict['Age'])
print ("dict['School']: ", dict['School'])
```

* **Dict comprehension：**

```python
#Use for-loops:
a = {}
for i in range(10):
    a[i] = chr(ord('A') + i) 
print(a)
```

```python
#Use dict comprehension:
a = {i:chr(ord('A') + i) for i in range(10)}
print(a)
```

## 2) Homework

* 在电脑上安装Anaconda，在jupyter notebook中运行本教程中的相关代码，观察输出.

## 3) More Reading

* [Advanced Tutorial - Python](https://lulab1.gitbook.io/training/part-i.-programming-skills/5.python_basics) - by Binbin Shi
* [廖雪峰python教程](https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000)

## 4) Recommended Software for Python

### 4.1) Anaconda

我们**建议**安装Anaconda，并使用Jupyter Notebook运行代码，体会python的代码风格和规范。

* Anaconda是一个管理和安装python包的管理软件，它也包含一些非常有用的工具如jupyter notebook

  > * [官网下载地址](https://www.anaconda.com/download/)，也可以在TUNA镜像站[免流量下载Anaconda](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/)

| Operating System | Download Link                                                                                                                   | Notes      |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| Mac              | [Anaconda3-5.2.0-MacOSX-x86\_64.pkg](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.2.0-MacOSX-x86_64.pkg)   |            |
| Linux            | [Anaconda3-5.2.0-Linux-x86\_64.sh](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.2.0-Linux-x86_64.sh)       | 注意需要添加环境变量 |
| Windows          | [Anaconda3-5.2.0-Windows-x86\_64.exe](https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.2.0-Windows-x86_64.exe) |            |

用`conda`安装python package，以`h5py`为例:

```bash
conda install h5py
```

用`conda`更新`h5py`至最新版本:

```bash
conda update h5py
```

### 4.2) jupyter notebook

[jupyter notebook](http://jupyter.org/) 是一款基于浏览器的交互性极强的python开发环境，在科研和工业界都广泛使用，可以帮助使用者方便的可视化结果，快速书写和调整代码，**非常推荐使用。**

* **打开 jupyter notebook**

```bash
jupyter notebook
```

或者使用软件版的Anaconda中集成的jupyter软件打开。

* **使用 jupyter notebook**
  * 保存，增加，删除，复制，粘贴代码框，上下移动代码框，运行，终止代码框，重启kernel（将会**清空内存**），切换代码框版式；
  * 使用shift+enter运行代码框，使用enter换行；
  * 可以搭配插件nbextenstion使用，提供更多功能。

#### 示例：

* **展示图片：**

![jupyter\_image](https://4115668567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LPVsf5VZbQ7h14X29qW%2F-LPVv7obRlTivTDgBNhr%2F-LPVvHIpKpHJK8zPk86P%2Fjupyter_image.png?generation=1540298192171563\&alt=media)

* **展示dataframe（与pandas配合）：**

![jupyter\_dataframe](https://4115668567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LPVsf5VZbQ7h14X29qW%2F-LPVv7obRlTivTDgBNhr%2F-LPVvHIrpvqPCpsT-d9n%2Fjupyter_dataframe.png?generation=1540298192130077\&alt=media)

* **方便的可视化（与matplotlib，seaborn等配合）：**

![jupyter\_matplotlib](https://4115668567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LPVsf5VZbQ7h14X29qW%2F-LPVv7obRlTivTDgBNhr%2F-LPVvHItsaaj4yP-lcMx%2Fjupyter_matplotlib.png?generation=1540298192180190\&alt=media)

* **支持markdown：**

![jupyter\_markdown](https://4115668567-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LPVsf5VZbQ7h14X29qW%2F-LPVv7obRlTivTDgBNhr%2F-LPVvHIvEv-N8wGhoWKZ%2Fjupyter_markdown.png?generation=1540298192075123\&alt=media)
