Last active
January 11, 2023 11:21
-
-
Save biomadeira/fbc52b3f13483990feee13076da79083 to your computer and use it in GitHub Desktop.
Example code snippets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "id": "2229f17b", | |
| "metadata": {}, | |
| "source": [ | |
| "# Best coding pratices\n", | |
| "Here are some best practices, tips, and tricks written in Python.\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "54b1e013", | |
| "metadata": {}, | |
| "source": [ | |
| "## Presentation code snippets\n", | |
| "\n", | |
| "These are a collection of snippets used in the \"code development and code release - best practices\" training presentation.\n", | |
| "\n", | |
| "The presentation is available online from [Google Docs](https://docs.google.com/presentation/d/1l9Gm9_jywRbvdqf4yiXU2RfngVtShcZCoWy5EWVcWEM/edit?usp=sharing).\n", | |
| "\n", | |
| "### The importance of UNIX skills\n", | |
| "```bash\n", | |
| "# present work directory\n", | |
| "pwd\n", | |
| "# change directories\n", | |
| "cd directory\n", | |
| "cd ../\n", | |
| "cd /Users/username/directory\n", | |
| "\n", | |
| "# list files using wildcards\n", | |
| "ls -lh sequence*.fasta\n", | |
| "\n", | |
| "# concatenating (opening) a file to view its contents\n", | |
| "cat sequence.fasta\n", | |
| "# other useful commands to interacting with the file\n", | |
| "head sequence.fasta # view the top 10 lines\n", | |
| "tail sequence.fasta # view the last 10 lines\n", | |
| "more sequence.fasta # open file for viewing \n", | |
| "less sequence.fasta # open file for viewing (alternative)\n", | |
| "most sequence.fasta # open file for viewing (alternative)\n", | |
| "\n", | |
| "# installing a python module\n", | |
| "pip install biopython\n", | |
| "\n", | |
| "# other features such as piping and string replacing \n", | |
| "cut -f1 results.txt | grep -v \"miRNA\" | sed s/T/U/ > outfile.txt\n", | |
| "\n", | |
| "# cloning a git repository from GitHub\n", | |
| "git clone https://github.com/ebi-jdispatcher/taxonomy-resolver.git\n", | |
| "\n", | |
| "# running a command line tool such as blastp\n", | |
| "blastp -query sequence.fasta -db bacteria.proteins.fasta -evalue 1e-6 \\\n", | |
| "-num_threads 4 -out blastp.txt\n", | |
| "```\n", | |
| "\n", | |
| "### Naming conventions\n", | |
| "\n", | |
| "Numbered filenames should be padded with zeros:\n", | |
| "\n", | |
| "```bash\n", | |
| "file_01.csv\n", | |
| "file_02.csv\n", | |
| "…\n", | |
| "file_10.csv\n", | |
| "file_11.csv\n", | |
| "```\n", | |
| "\n", | |
| "Classes and Exceptions should use mixed case or “CamelCase”\n", | |
| "```python\n", | |
| "class SequenceCoords:\n", | |
| " coords: Tuple[int, int]\n", | |
| "```\n", | |
| "\n", | |
| "Private variables/methods - start with underscore\n", | |
| "```python\n", | |
| "_single_leading_underscore = 'value'\n", | |
| "```\n", | |
| "\n", | |
| "Avoid conflicts with language keywords - end with underscore\n", | |
| "```python\n", | |
| "tkinter.Toplevel(master, class_='ClassName')\n", | |
| "```\n", | |
| "\n", | |
| "Constants and globals - capital letters (with underscores)\n", | |
| "```python\n", | |
| "MAX_OVERFLOW = 1000\n", | |
| "```\n", | |
| "\n", | |
| "### Code style\n", | |
| "\n", | |
| "Module imports\n", | |
| "```python\n", | |
| "# Wrong:\n", | |
| "import sys, os\n", | |
| "\n", | |
| "# Correct:\n", | |
| "import os\n", | |
| "import sys\n", | |
| "\n", | |
| "# Correct:\n", | |
| "from subprocess import Popen, PIPE\n", | |
| "\n", | |
| "```\n", | |
| "\n", | |
| "Whitespace\n", | |
| "```python\n", | |
| "# Wrong:\n", | |
| "spam( ham[ 1 ], { eggs: 2 } )\n", | |
| "\n", | |
| "# Correct:\n", | |
| "spam(ham[1], {eggs: 2})\n", | |
| "\n", | |
| "# Wrong:\n", | |
| "if x == 4 : print(x , y) ; x , y = y , x\n", | |
| "\n", | |
| "# Correct:\n", | |
| "if x == 4: print(x, y); x, y = y, x\n", | |
| " \n", | |
| "```\n", | |
| "\n", | |
| "Line break before binary operators\n", | |
| "```python\n", | |
| "# Correct:\n", | |
| "# easy to match operators with operands\n", | |
| "income = (gross_wages\n", | |
| " + taxable_interest\n", | |
| " + (dividends - qualified_dividends)\n", | |
| " - ira_deduction\n", | |
| " - student_loan_interest)\n", | |
| "```" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "b02fe589", | |
| "metadata": {}, | |
| "source": [ | |
| "## Live demo code snippets" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "a44e733f", | |
| "metadata": {}, | |
| "source": [ | |
| "### Naming conventions" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "id": "123c686c", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# Variable names should be lowercase and separate words by underscores. \n", | |
| "age = 30\n", | |
| "name = \"Alice\"\n", | |
| "\n", | |
| "# Function names should be lowercase and separate words by underscores.\n", | |
| "def say_hello(name):\n", | |
| " print(f\"Hello, {name}!\")\n", | |
| "\n", | |
| "# Class names should be capitalized and use CamelCase\n", | |
| "class Person:\n", | |
| " def __init__(self, name, age):\n", | |
| " self.name = name\n", | |
| " self.age = age\n", | |
| " \n", | |
| "# Constants should be in all uppercase, separated by underscores\n", | |
| "PI = 3.14\n", | |
| "GRAVITY = 9.8" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "id": "5c90063c", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# imports\n", | |
| "import math\n", | |
| "import random\n", | |
| "\n", | |
| "# common abbreviations\n", | |
| "import pandas as pd\n", | |
| "import numpy as np\n", | |
| "\n", | |
| "from Bio import SeqIO" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "id": "0fa06fda", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "'missing_file.txt' is not available!\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "filename = \"missing_file.txt\"\n", | |
| "# tries to open the txt file\n", | |
| "try:\n", | |
| " with open(filename, 'r') as filehandle:\n", | |
| " for line in filehandle:\n", | |
| " print(line)\n", | |
| "except FileNotFoundError as e:\n", | |
| " print(f\"'{filename}' is not available!\")\n", | |
| " pass" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "4e2b3f5e", | |
| "metadata": {}, | |
| "source": [ | |
| "### Comments and self-documenting code" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "id": "14ac9482", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "6.7" | |
| ] | |
| }, | |
| "execution_count": 4, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "def calculate_average(numbers):\n", | |
| " \"\"\"\n", | |
| " Calculates the average of a list of numbers.\n", | |
| " \"\"\"\n", | |
| " total = sum(numbers)\n", | |
| " count = len(numbers)\n", | |
| " return total / count\n", | |
| "\n", | |
| "# get the average\n", | |
| "calculate_average([1,4,3,5,16,3,4,2,6,23])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "id": "bae0d721", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "import pathlib\n", | |
| "import typing\n", | |
| "\n", | |
| "pathlike = typing.Union[str, pathlib.Path]\n", | |
| "\n", | |
| "def parse_ncbiblast_output(outfile: pathlike, stype: str = \"protein\") -> dict:\n", | |
| " \"\"\"\n", | |
| " Parses (some lines of) the BLAST output format file.\n", | |
| "\n", | |
| " :param blastoutfile: (str or pathlib.Path) path to file \n", | |
| " :param stype: (str) sequence type\n", | |
| " :return: (dict) parsed output object\n", | |
| " \"\"\"\n", | |
| " some_dict = {}\n", | |
| " # do something useful...\n", | |
| " return some_dict" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "890832ca", | |
| "metadata": {}, | |
| "source": [ | |
| "### List comprehensions\n", | |
| "A list comprehension can replace for loops used to fill a list." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 6, | |
| "id": "9363b570", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "mylist = [i for i in range(10)]\n", | |
| "print(mylist)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "f91ff94a", | |
| "metadata": {}, | |
| "source": [ | |
| "And because you can use an expression, you can also do some math:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 7, | |
| "id": "dcec5548", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "squares = [x**2 for x in range(10)]\n", | |
| "print(squares)\n", | |
| "# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 8, | |
| "id": "e614da4e", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[0, 4, 16, 36, 64]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "even_squares = [x**2 for x in range(10) if not x % 2]\n", | |
| "print(even_squares)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "81f27a7d", | |
| "metadata": {}, | |
| "source": [ | |
| "We can even use a function" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 9, | |
| "id": "94b80ff1", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "def some_function(a):\n", | |
| " return (a + 5) / 2\n", | |
| " \n", | |
| "my_formula = [some_function(i) for i in range(10)]\n", | |
| "print(my_formula)\n", | |
| "# [2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "04e20fbc", | |
| "metadata": {}, | |
| "source": [ | |
| "### Returning multiple values\n", | |
| "Functions in Python can return more than one variable without the need for a dictionary, a list or a class. It works like this:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 10, | |
| "id": "d17b32ad", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Foo Bar\n", | |
| "01/01/2000\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "def get_user(id):\n", | |
| " # fetch user from database\n", | |
| " name = \"Foo Bar\"\n", | |
| " birthdate = \"01/01/2000\"\n", | |
| " return name, birthdate\n", | |
| "\n", | |
| "name, birthdate = get_user(4)\n", | |
| "print(name)\n", | |
| "print(birthdate)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "e23ff8b2", | |
| "metadata": {}, | |
| "source": [ | |
| "### Merging dictionaries" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 11, | |
| "id": "5914c751", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "{'a': 1, 'b': 3, 'c': 4}\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "dict1 = { 'a': 1, 'b': 2 }\n", | |
| "dict2 = { 'b': 3, 'c': 4 }\n", | |
| "dict1.update(dict2)\n", | |
| "print(dict1)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 12, | |
| "id": "b06b2730", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "{'a': 1, 'b': 3, 'c': 4}\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "dict1 = { 'a': 1, 'b': 2 }\n", | |
| "dict2 = { 'b': 3, 'c': 4 }\n", | |
| "merged = { **dict1, **dict2 }\n", | |
| "print (merged)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 13, | |
| "id": "e98dfd03", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "{'a': 1, 'b': 3, 'c': 4}\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Python >= 3.9 only\n", | |
| "merged = dict1 | dict2\n", | |
| "print (merged)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "ab5b2748", | |
| "metadata": {}, | |
| "source": [ | |
| "### String split and string join" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 14, | |
| "id": "6137b2b1", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "['The', 'quick', 'brown', 'fox']\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "mystring = \"The quick brown fox\"\n", | |
| "mylist = mystring.split(' ')\n", | |
| "print(mylist)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 15, | |
| "id": "50aaf188", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "The quick brown fox\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "mystring = \" \".join(mylist)\n", | |
| "print(mystring)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "d277ba23", | |
| "metadata": {}, | |
| "source": [ | |
| "### String to CamelCase" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 16, | |
| "id": "de28b096", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "The Quick Brown Fox\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print(mystring.title())" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "39a4130e", | |
| "metadata": {}, | |
| "source": [ | |
| "### Data slicing\n", | |
| "The basic syntax of list slicing is `a[start:stop:step]`" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 17, | |
| "id": "2f994ffd", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[1, 2]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "first_two = [1, 2, 3, 4, 5][0:2]\n", | |
| "print(first_two)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 18, | |
| "id": "07420f4c", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[1, 3, 5]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "steps = [1, 2, 3, 4, 5][0:5:2]\n", | |
| "print(steps)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 19, | |
| "id": "2094d138", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "aced it\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "mystring = \"abcdefdn nimt\"[::2]\n", | |
| "print(mystring)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 20, | |
| "id": "8b6f3c86", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "tmin ndfedcba\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "mystring = \"abcdefdn nimt\"[::-1]\n", | |
| "print(mystring)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "3f0fe5eb", | |
| "metadata": {}, | |
| "source": [ | |
| "### Using map()\n", | |
| "One of Python’s built-in functions is called map(). The syntax for map() is:\n", | |
| "\n", | |
| "`map(function, something_iterable)`\n", | |
| "\n", | |
| "So you give it a function to execute, and something to execute on. This can be anything that’s iterable. In the examples below I’ll use a list." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 21, | |
| "id": "cd8b0062", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "['SENTENCE', 'FRAGMENT']\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "def upper(s):\n", | |
| " return s.upper()\n", | |
| " \n", | |
| "mylist = list(map(upper, ['sentence', 'fragment']))\n", | |
| "print(mylist)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 22, | |
| "id": "696aa557", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[1, 2, 3, 4, 5, 6, 7]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "list_of_ints = list(map(int, \"1234567\"))\n", | |
| "print(list_of_ints)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "065cfd5b", | |
| "metadata": {}, | |
| "source": [ | |
| "### Get unique elements from a list or string\n", | |
| "By creating a set with the set() function, you get all the unique elements from a list or list-like object:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 23, | |
| "id": "647d1fcf", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "{1, 2, 3, 4, 5, 6}\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "mylist = [1, 1, 2, 3, 4, 5, 5, 5, 6, 6]\n", | |
| "print (set(mylist))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 24, | |
| "id": "023c55fc", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "['a', 'b', 'c', 'd', 'e', 'f', 'i', 'v']\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print(sorted(set(\"fffaaabbbiiiiccceeeedddeeefffvvveee\")))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "52753581", | |
| "metadata": {}, | |
| "source": [ | |
| "### Find the most frequently occurring value\n", | |
| "To find the most frequently occurring value in a list or string:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 25, | |
| "id": "4c92931d", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "4\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]\n", | |
| "print(max(set(test), key = test.count))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "cce32ac1", | |
| "metadata": {}, | |
| "source": [ | |
| "Counting occurrences using Counter from the collections library" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 26, | |
| "id": "ba577c7f", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Counter({4: 4, 2: 3, 1: 2, 3: 2})\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "from collections import Counter\n", | |
| "\n", | |
| "test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]\n", | |
| "c = Counter(test)\n", | |
| "print(c)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "248ae962", | |
| "metadata": {}, | |
| "source": [ | |
| "### Ternary operator for conditional assignment\n", | |
| "This is another one of those ways to make your code more concise while still keeping it readable:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 27, | |
| "id": "c0fe4173", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Success!\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "x = 2\n", | |
| "y = \"Success!\" if (x == 2) else \"Failed!\"\n", | |
| "print(y)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "118d4b44", | |
| "metadata": {}, | |
| "source": [ | |
| "### Chaining of comparison operators\n", | |
| "You can chain comparison operators in Python, creating more readable and concise code:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 28, | |
| "id": "27f45529", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Yes\n", | |
| "Yes\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "x = 10\n", | |
| "\n", | |
| "# Instead of:\n", | |
| "if x > 5 and x < 15:\n", | |
| " print(\"Yes\")\n", | |
| "\n", | |
| "# You can also write:\n", | |
| "if 5 < x < 15:\n", | |
| " print(\"Yes\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "f4d94222", | |
| "metadata": {}, | |
| "source": [ | |
| "### Dataclass\n", | |
| "Since version 3.7, Python offers data classes. There are several advantages over regular classes or other alternatives like returning multiple values or dictionaries:\n", | |
| "\n", | |
| "- a data class requires a minimal amount of code\n", | |
| "- you can compare data classes because `__eq__` is implemented for you\n", | |
| "- you can easily print a data class for debugging because `__repr__` is implemented as well\n", | |
| "- data classes require type hints, reduced the chances of bugs\n", | |
| "\n", | |
| "Here’s an example of a data class at work:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 29, | |
| "id": "5165cd5f", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Card(rank='Q', suit='hearts')\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "from dataclasses import dataclass\n", | |
| "\n", | |
| "@dataclass\n", | |
| "class Card:\n", | |
| " rank: str\n", | |
| " suit: str\n", | |
| " \n", | |
| "card = Card(\"Q\", \"hearts\")\n", | |
| "print(card)\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 30, | |
| "id": "8cd18195", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Q\n", | |
| "hearts\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print(card.rank)\n", | |
| "print(card.suit)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "f9f8f00a", | |
| "metadata": {}, | |
| "source": [ | |
| "### Defensive programming\n", | |
| "Program defensively, i.e., assume that errors are going to arise, and write code to detect them when they do.\n", | |
| "Put assertions in programs to check their state as they run, and to help readers understand how those programs are supposed to work." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 31, | |
| "id": "a1a89916", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Data should only contain positive values\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "numbers = [1.5, 2.3, 0.7, -0.001, 4.4]\n", | |
| "total = 0.0\n", | |
| "try:\n", | |
| " for num in numbers:\n", | |
| " assert num > 0.0, 'Data should only contain positive values'\n", | |
| " total += num\n", | |
| " print('total is:', total)\n", | |
| "except AssertionError as e:\n", | |
| " print(e)\n", | |
| " # handle this issue appropriately" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "e59d69d7", | |
| "metadata": {}, | |
| "source": [ | |
| "How to retry after an exception?" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 32, | |
| "id": "d52a32e7", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "# break only when the block succeeds\n", | |
| "while True:\n", | |
| " try:\n", | |
| " pass\n", | |
| " # do something\n", | |
| " except SomeSpecificException: \n", | |
| " continue\n", | |
| " break" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "2572b438", | |
| "metadata": {}, | |
| "source": [ | |
| "### Programming paradigms\n", | |
| "- Object-Oriented Programming (OOP): OOP is a programming paradigm that is based on the concept of \"objects\", which have properties (attributes) and methods. \n", | |
| "- Functional Programming (FP): FP is a programming paradigm that is based on the concept of \"functions\" that take input(s) and return output(s) without modifying the state of variables outside the function.\n", | |
| "- Procedural Programming (PP): PP is a programming paradigm that is based on the concept of a \"procedure\", which is a set of instructions that are executed in a specific order to perform a task.\n", | |
| "- Asynchronous Programming (AP): AP is a programming paradigm that allows the programmer to write non-blocking code. It helps to avoid waiting for a specific task and continue to execute other codes." | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "e9f5c106", | |
| "metadata": {}, | |
| "source": [ | |
| "#### Object-Oriented Programming" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 33, | |
| "id": "08e72ca0", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Hello, my name is Alice and I am 30 years old.\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "class Person:\n", | |
| " def __init__(self, name, age):\n", | |
| " self.name = name\n", | |
| " self.age = age\n", | |
| " \n", | |
| " def say_hello(self):\n", | |
| " print(f\"Hello, my name is {self.name} and I am {self.age} years old.\")\n", | |
| "\n", | |
| "p = Person(\"Alice\", 30)\n", | |
| "p.say_hello()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "abb4a60e", | |
| "metadata": {}, | |
| "source": [ | |
| "In the following example we:\n", | |
| "\n", | |
| "- Keep the `__init__` method clean\n", | |
| "- Use `@property` and `@property_name.setter` decorators: These decorators allow you to define methods that are used to get and set the value of a class property, respectively. This allows you to add additional logic to your getters and setters, such as validation, without changing the way that the property is accessed from outside the class." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 34, | |
| "id": "c0828762", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "class MyClass:\n", | |
| " def __init__(self, value):\n", | |
| " self._value = value\n", | |
| " self._private_value = \"This is private\"\n", | |
| " self.initialize_extra_values()\n", | |
| " \n", | |
| " def initialize_extra_values(self):\n", | |
| " self.extra_value = \"extra\"\n", | |
| "\n", | |
| " @property\n", | |
| " def value(self):\n", | |
| " return self._value\n", | |
| "\n", | |
| " @value.setter\n", | |
| " def value(self, new_value):\n", | |
| " if isinstance(new_value, int) and new_value > 0:\n", | |
| " self._value = new_value\n", | |
| " else:\n", | |
| " raise ValueError(\"Value must be a positive integer.\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "a18887a3", | |
| "metadata": {}, | |
| "source": [ | |
| "#### Using inheritance and polymorphism" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 35, | |
| "id": "f1f16592", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "200\n", | |
| "78.5\n", | |
| "375\n", | |
| "200.96\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "class Shape:\n", | |
| " def area(self):\n", | |
| " pass\n", | |
| " \n", | |
| "class Rectangle(Shape):\n", | |
| " def __init__(self, width, height):\n", | |
| " self.width = width\n", | |
| " self.height = height\n", | |
| "\n", | |
| " def area(self):\n", | |
| " return self.width * self.height\n", | |
| " \n", | |
| "class Circle(Shape):\n", | |
| " def __init__(self, radius):\n", | |
| " self.radius = radius\n", | |
| "\n", | |
| " def area(self):\n", | |
| " return 3.14 * self.radius ** 2\n", | |
| "\n", | |
| "shapes = [Rectangle(10,20), Circle(5), Rectangle(15,25), Circle(8)]\n", | |
| "for shape in shapes:\n", | |
| " print(shape.area())\n" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "ce57bf64", | |
| "metadata": {}, | |
| "source": [ | |
| "#### Using descriptor classes" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 36, | |
| "id": "6e7c6484", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "10\n", | |
| "20\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# descriptor class with 'setters and getters'\n", | |
| "class Quantity:\n", | |
| " # method called in the background by Python\n", | |
| " def __set_name__(self, owner, name):\n", | |
| " self.var_name = name\n", | |
| " \n", | |
| " def __set__(self, instance, value):\n", | |
| " instance.__dict__[self.var_name] = value\n", | |
| " \n", | |
| " def __get__(self, instance, owner):\n", | |
| " return instance.__dict__[self.var_name]\n", | |
| " \n", | |
| "class Rectangle:\n", | |
| " width = Quantity()\n", | |
| " height = Quantity()\n", | |
| " \n", | |
| "rect = Rectangle()\n", | |
| "rect.width = 10\n", | |
| "rect.height = 20\n", | |
| "\n", | |
| "print(rect.width)\n", | |
| "print(rect.height)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "2b8ae0f0", | |
| "metadata": {}, | |
| "source": [ | |
| "#### Functional Programming" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 37, | |
| "id": "2c9b361d", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "[4, 16, 36, 64, 100]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n", | |
| "filtered_numbers = filter(lambda x: x % 2 == 0, numbers)\n", | |
| "squared_numbers = map(lambda x: x ** 2, filtered_numbers)\n", | |
| "print(list(squared_numbers)) # prints [4, 16, 36, 64, 100]" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "eacb88fc", | |
| "metadata": {}, | |
| "source": [ | |
| "#### Asynchronous Programming" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 38, | |
| "id": "638e9a72", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Running in foo\n", | |
| "Explicit context to bar\n", | |
| "Explicit context switch to foo again\n", | |
| "Implicit context switch back to bar\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "import asyncio\n", | |
| "\n", | |
| "async def foo():\n", | |
| " print(\"Running in foo\")\n", | |
| " await asyncio.sleep(0)\n", | |
| " print(\"Explicit context switch to foo again\")\n", | |
| "\n", | |
| "async def bar():\n", | |
| " print(\"Explicit context to bar\")\n", | |
| " await asyncio.sleep(0)\n", | |
| " print(\"Implicit context switch back to bar\")\n", | |
| "\n", | |
| "async def main():\n", | |
| " task1 = asyncio.create_task(foo())\n", | |
| " task2 = asyncio.create_task(bar())\n", | |
| " await task1\n", | |
| " await task2\n", | |
| "\n", | |
| "await main()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "f599dd7e", | |
| "metadata": {}, | |
| "source": [ | |
| "### Parsing a FASTA sequence" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "6b2b7925", | |
| "metadata": {}, | |
| "source": [ | |
| "Example sequences:\n", | |
| "```\n", | |
| ">SEQUENCE_1\n", | |
| "MTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKADRLAAEG\n", | |
| "LVSVKVSDDFTIAAMRPSYLSYEDLDMTFVENEYKALVAELEKENEERRRLKDPNKPEHK\n", | |
| "IPQFASRKQLSDAILKEAEEKIKEELKAQGKPEKIWDNIIPGKMNSFIADNSQLDSKLTL\n", | |
| "MGQFYVMDDKKTVEQVIAEKEKEFGGKIKIVEFICFEVGEGLEKKTEDFAAEVAAQL\n", | |
| ">SEQUENCE_2\n", | |
| "SATVSEINSETDFVAKNDQFIALTKDTTAHIQSNSLQSVEELHSSTINGVKFEEYLKSQI\n", | |
| "ATIGENLVVRRFATLKAGANGVVNGYIHTNGRVGVVIAAACDSAEVASKSRDLLRQICMH\n", | |
| "```" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "ee48833c", | |
| "metadata": {}, | |
| "source": [ | |
| "Although FASTA format is not particularly difficult to parse, it is better to use an open source module such as Biopython." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 39, | |
| "id": "0edc8e1f", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "['>SEQUENCE_1\\n', 'MTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKADRLAAEG\\n', 'LVSVKVSDDFTIAAMRPSYLSYEDLDMTFVENEYKALVAELEKENEERRRLKDPNKPEHK\\n', 'IPQFASRKQLSDAILKEAEEKIKEELKAQGKPEKIWDNIIPGKMNSFIADNSQLDSKLTL\\n', 'MGQFYVMDDKKTVEQVIAEKEKEFGGKIKIVEFICFEVGEGLEKKTEDFAAEVAAQL\\n', '>SEQUENCE_2\\n', 'SATVSEINSETDFVAKNDQFIALTKDTTAHIQSNSLQSVEELHSSTINGVKFEEYLKSQI\\n', 'ATIGENLVVRRFATLKAGANGVVNGYIHTNGRVGVVIAAACDSAEVASKSRDLLRQICM\\n']\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "fasta_file = \"test.fasta\"\n", | |
| "\n", | |
| "def parse_fasta(filename):\n", | |
| " contents = []\n", | |
| " with open(filename, \"r\") as filehandle:\n", | |
| " for line in filehandle:\n", | |
| " contents.append(line)\n", | |
| " return contents\n", | |
| "\n", | |
| "fasta = parse_fasta(fasta_file)\n", | |
| "print(fasta)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 40, | |
| "id": "b0d2607f", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "SEQUENCE_1\n", | |
| "MTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKADRLAAEGLVSVKVSDDFTIAAMRPSYLSYEDLDMTFVENEYKALVAELEKENEERRRLKDPNKPEHKIPQFASRKQLSDAILKEAEEKIKEELKAQGKPEKIWDNIIPGKMNSFIADNSQLDSKLTLMGQFYVMDDKKTVEQVIAEKEKEFGGKIKIVEFICFEVGEGLEKKTEDFAAEVAAQL\n", | |
| "237\n", | |
| "SEQUENCE_2\n", | |
| "SATVSEINSETDFVAKNDQFIALTKDTTAHIQSNSLQSVEELHSSTINGVKFEEYLKSQIATIGENLVVRRFATLKAGANGVVNGYIHTNGRVGVVIAAACDSAEVASKSRDLLRQICM\n", | |
| "119\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "from Bio import SeqIO\n", | |
| "\n", | |
| "records = []\n", | |
| "for seq_record in SeqIO.parse(\"test.fasta\", \"fasta\"):\n", | |
| " records.append(seq_record)\n", | |
| " print(seq_record.id)\n", | |
| " print(seq_record.seq)\n", | |
| " print(len(seq_record))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 41, | |
| "id": "1a633c0b", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "ID: SEQUENCE_1\n", | |
| "Name: SEQUENCE_1\n", | |
| "Description: SEQUENCE_1\n", | |
| "Number of features: 0\n", | |
| "Seq('MTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKAD...AQL')\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "print(records[0])" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "b1c92fd3", | |
| "metadata": {}, | |
| "source": [ | |
| "#### Sequence operations" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 42, | |
| "id": "1dfae8ca", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "AGTACACTGGT\n", | |
| "TCATGTGACCA\n", | |
| "ACCAGTGTACT\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "from Bio.Seq import Seq\n", | |
| "my_seq = Seq(\"AGTACACTGGT\")\n", | |
| "print(my_seq)\n", | |
| "print(my_seq.complement())\n", | |
| "print(my_seq.reverse_complement())" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "1c37dd9e", | |
| "metadata": {}, | |
| "source": [ | |
| "### Importing data from a CSV file\n", | |
| "Based on the Python lessons in Software Carpentry:\n", | |
| "https://swcarpentry.github.io/python-novice-inflammation\n", | |
| "\n", | |
| "Data downloaded from:\n", | |
| "https://swcarpentry.github.io/python-novice-inflammation/data/python-novice-inflammation-data.zip" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 43, | |
| "id": "fae0e737", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "--2023-01-11 11:19:44-- https://swcarpentry.github.io/python-novice-inflammation/data/python-novice-inflammation-data.zip\n", | |
| "Resolving swcarpentry.github.io (swcarpentry.github.io)... 185.199.110.153, 185.199.108.153, 185.199.111.153, ...\n", | |
| "Connecting to swcarpentry.github.io (swcarpentry.github.io)|185.199.110.153|:443... connected.\n", | |
| "HTTP request sent, awaiting response... 200 OK\n", | |
| "Length: 22554 (22K) [application/zip]\n", | |
| "Saving to: 'python-novice-inflammation-data.zip'\n", | |
| "\n", | |
| "python-novice-infla 100%[===================>] 22.03K --.-KB/s in 0.003s \n", | |
| "\n", | |
| "2023-01-11 11:19:44 (8.02 MB/s) - 'python-novice-inflammation-data.zip' saved [22554/22554]\n", | |
| "\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "!wget https://swcarpentry.github.io/python-novice-inflammation/data/python-novice-inflammation-data.zip" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 44, | |
| "id": "f2334df0", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Archive: python-novice-inflammation-data.zip\r\n", | |
| " creating: data/\r\n", | |
| " inflating: data/inflammation-01.csv \r\n", | |
| " inflating: data/inflammation-02.csv \r\n", | |
| " inflating: data/inflammation-03.csv \r\n", | |
| " inflating: data/inflammation-04.csv \r\n", | |
| " inflating: data/inflammation-05.csv \r\n", | |
| " inflating: data/inflammation-06.csv \r\n", | |
| " inflating: data/inflammation-07.csv \r\n", | |
| " inflating: data/inflammation-08.csv \r\n", | |
| " inflating: data/inflammation-09.csv \r\n", | |
| " inflating: data/inflammation-10.csv \r\n", | |
| " inflating: data/inflammation-11.csv \r\n", | |
| " inflating: data/inflammation-12.csv \r\n", | |
| " extracting: data/small-01.csv \r\n", | |
| " extracting: data/small-02.csv \r\n", | |
| " extracting: data/small-03.csv \r\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "!unzip python-novice-inflammation-data.zip" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 45, | |
| "id": "aa43c6b9", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "['0', '0', '1']\n", | |
| "['0', '1', '2']\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "with open('data/small-01.csv', 'r') as csvlines:\n", | |
| " for line in csvlines:\n", | |
| " print(line.rstrip('\\n').split(','))" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 46, | |
| "id": "a1aad356", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "['0', '0', '1']\n", | |
| "['0', '1', '2']\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "import csv\n", | |
| "with open('data/small-01.csv', newline='') as csvfile:\n", | |
| " csvreader = csv.reader(csvfile, delimiter=',', quotechar='|')\n", | |
| " for row in csvreader:\n", | |
| " print(row)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 47, | |
| "id": "52a52ea2", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "array([[0., 0., 1., ..., 3., 0., 0.],\n", | |
| " [0., 1., 2., ..., 1., 0., 1.],\n", | |
| " [0., 1., 1., ..., 2., 1., 1.],\n", | |
| " ...,\n", | |
| " [0., 1., 1., ..., 1., 1., 1.],\n", | |
| " [0., 0., 0., ..., 0., 2., 0.],\n", | |
| " [0., 0., 1., ..., 1., 1., 0.]])" | |
| ] | |
| }, | |
| "execution_count": 47, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "import numpy as np \n", | |
| "np.loadtxt(fname='data/inflammation-01.csv', delimiter=',')" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 48, | |
| "id": "54e2428c", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| " 0 0.1 1 3 1.1 2 4 7 8 3.1 ... 4.3 4.4 5.1 7.6 3.4 4.5 \\\n", | |
| "0 0 1 2 1 2 1 3 2 2 6 ... 3 5 4 4 5 5 \n", | |
| "1 0 1 1 3 3 2 6 2 5 9 ... 10 5 4 2 2 3 \n", | |
| "2 0 0 2 0 4 2 2 1 6 7 ... 3 5 6 3 3 4 \n", | |
| "3 0 1 1 3 3 1 3 5 2 4 ... 9 6 3 2 2 4 \n", | |
| "4 0 0 1 2 2 4 2 1 6 4 ... 8 4 7 3 5 4 \n", | |
| "5 0 0 2 2 4 2 2 5 5 8 ... 8 8 4 2 3 5 \n", | |
| "6 0 0 1 2 3 1 2 3 5 3 ... 4 9 3 5 2 5 \n", | |
| "7 0 0 0 3 1 5 6 5 5 8 ... 4 6 4 7 6 3 \n", | |
| "8 0 1 1 2 1 3 5 3 5 8 ... 2 5 4 5 1 4 \n", | |
| "9 0 1 0 0 4 3 3 5 5 4 ... 4 3 4 5 5 3 \n", | |
| "10 0 1 0 0 3 4 2 7 8 5 ... 8 3 5 4 5 5 \n", | |
| "11 0 0 2 1 4 3 6 4 6 7 ... 5 4 7 3 5 4 \n", | |
| "12 0 0 0 0 1 3 1 6 6 5 ... 5 8 7 4 6 4 \n", | |
| "13 0 1 2 1 1 1 4 1 5 2 ... 8 2 5 1 3 4 \n", | |
| "14 0 1 1 0 1 2 4 3 6 4 ... 10 9 5 6 5 3 \n", | |
| "15 0 0 0 0 2 3 6 5 7 4 ... 9 8 7 5 3 1 \n", | |
| "16 0 0 0 1 2 1 4 3 6 7 ... 2 3 6 5 4 2 \n", | |
| "17 0 0 2 1 2 5 4 2 7 8 ... 6 9 2 1 1 2 \n", | |
| "18 0 1 2 0 1 4 3 2 2 7 ... 6 6 6 1 1 2 \n", | |
| "19 0 1 1 3 1 4 4 1 8 2 ... 3 2 4 3 1 5 \n", | |
| "20 0 0 2 3 2 3 2 6 3 8 ... 8 5 6 6 1 4 \n", | |
| "21 0 0 0 3 4 5 1 7 7 8 ... 4 4 8 2 6 5 \n", | |
| "22 0 1 1 1 1 3 3 2 6 3 ... 5 3 5 1 1 4 \n", | |
| "23 0 1 1 1 2 3 5 3 6 3 ... 5 5 6 1 1 1 \n", | |
| "24 0 0 2 1 3 3 2 7 4 4 ... 8 5 7 2 2 4 \n", | |
| "25 0 0 1 2 4 2 2 3 5 7 ... 7 4 8 2 2 1 \n", | |
| "26 0 0 1 1 1 5 1 5 2 2 ... 9 4 5 3 2 5 \n", | |
| "27 0 0 2 2 3 4 6 3 7 6 ... 7 7 8 3 5 4 \n", | |
| "28 0 0 0 1 4 4 6 3 8 6 ... 6 9 5 5 2 5 \n", | |
| "29 0 1 1 0 3 2 4 6 8 6 ... 10 4 2 6 5 5 \n", | |
| "30 0 0 2 3 3 4 5 3 6 7 ... 3 6 6 4 5 2 \n", | |
| "31 0 1 2 2 2 3 6 6 6 7 ... 5 8 5 2 5 5 \n", | |
| "32 0 0 2 1 3 5 6 7 5 8 ... 2 9 7 2 4 2 \n", | |
| "33 0 0 1 2 4 1 5 5 2 3 ... 5 6 6 2 3 5 \n", | |
| "34 0 0 0 3 1 3 6 4 3 4 ... 3 9 5 1 6 5 \n", | |
| "35 0 1 2 2 2 5 5 1 4 6 ... 6 4 5 4 6 3 \n", | |
| "36 0 1 1 2 3 1 5 1 2 2 ... 9 9 5 4 4 2 \n", | |
| "37 0 1 0 3 2 4 1 1 5 9 ... 5 5 2 1 1 1 \n", | |
| "38 0 1 1 3 1 1 5 5 3 7 ... 2 3 6 3 3 5 \n", | |
| "39 0 0 0 2 2 1 3 4 5 5 ... 2 9 6 2 2 5 \n", | |
| "40 0 0 1 3 3 1 2 1 8 9 ... 4 8 2 6 6 4 \n", | |
| "41 0 1 1 3 4 5 2 1 3 7 ... 5 8 5 5 6 1 \n", | |
| "42 0 0 1 3 1 4 3 6 7 8 ... 10 2 5 1 5 4 \n", | |
| "43 0 1 1 3 3 4 4 6 3 4 ... 10 6 8 7 2 5 \n", | |
| "44 0 1 2 2 4 3 1 4 8 9 ... 5 8 4 4 5 2 \n", | |
| "45 0 0 2 3 4 5 4 6 2 9 ... 6 7 6 5 1 3 \n", | |
| "46 0 1 1 3 1 4 6 2 8 2 ... 6 9 5 6 1 1 \n", | |
| "47 0 0 1 3 2 5 1 2 7 6 ... 10 7 6 3 1 5 \n", | |
| "48 0 0 1 2 3 4 5 7 5 4 ... 4 6 2 4 1 4 \n", | |
| "49 0 1 2 1 1 3 5 3 6 3 ... 7 9 3 3 6 3 \n", | |
| "50 0 1 2 2 3 5 2 4 5 6 ... 8 5 4 1 3 2 \n", | |
| "51 0 0 0 2 4 4 5 3 3 3 ... 10 8 7 5 2 2 \n", | |
| "52 0 0 2 1 1 4 4 7 2 9 ... 7 6 5 4 1 4 \n", | |
| "53 0 1 2 1 1 4 5 4 4 5 ... 4 5 5 2 2 5 \n", | |
| "54 0 0 1 3 2 3 6 4 5 7 ... 3 5 3 5 4 5 \n", | |
| "55 0 1 1 2 2 5 1 7 4 2 ... 7 7 5 6 3 4 \n", | |
| "56 0 1 1 1 4 1 6 4 6 3 ... 8 6 6 4 3 5 \n", | |
| "57 0 0 0 1 4 5 6 3 8 7 ... 10 8 8 6 5 5 \n", | |
| "58 0 0 1 0 3 2 5 4 8 2 ... 8 5 3 5 4 1 \n", | |
| "\n", | |
| " 2.1 3.5 0.2 0.3 \n", | |
| "0 1 1 0 1 \n", | |
| "1 2 2 1 1 \n", | |
| "2 2 3 2 1 \n", | |
| "3 2 0 1 1 \n", | |
| "4 4 3 2 1 \n", | |
| "5 4 1 1 1 \n", | |
| "6 3 2 2 1 \n", | |
| "7 2 1 0 0 \n", | |
| "8 1 2 0 0 \n", | |
| "9 3 2 2 1 \n", | |
| "10 4 0 1 1 \n", | |
| "11 2 3 0 1 \n", | |
| "12 1 3 0 0 \n", | |
| "13 2 0 2 0 \n", | |
| "14 4 2 2 0 \n", | |
| "15 4 0 2 1 \n", | |
| "16 3 0 1 0 \n", | |
| "17 2 0 1 0 \n", | |
| "18 4 3 1 1 \n", | |
| "19 4 2 2 0 \n", | |
| "20 3 0 2 0 \n", | |
| "21 1 0 1 0 \n", | |
| "22 4 1 2 0 \n", | |
| "23 1 0 2 1 \n", | |
| "24 1 1 1 0 \n", | |
| "25 3 0 1 1 \n", | |
| "26 4 3 2 1 \n", | |
| "27 1 3 1 0 \n", | |
| "28 2 1 0 1 \n", | |
| "29 2 3 2 1 \n", | |
| "30 2 3 0 0 \n", | |
| "31 2 0 2 1 \n", | |
| "32 1 2 1 1 \n", | |
| "33 2 1 1 1 \n", | |
| "34 4 2 2 0 \n", | |
| "35 4 3 2 1 \n", | |
| "36 1 0 1 0 \n", | |
| "37 1 3 0 1 \n", | |
| "38 4 3 2 1 \n", | |
| "39 3 0 0 1 \n", | |
| "40 2 2 0 0 \n", | |
| "41 2 1 2 0 \n", | |
| "42 2 1 0 1 \n", | |
| "43 4 3 1 1 \n", | |
| "44 4 1 1 0 \n", | |
| "45 1 0 0 0 \n", | |
| "46 2 1 2 1 \n", | |
| "47 4 3 0 0 \n", | |
| "48 2 2 2 1 \n", | |
| "49 4 1 2 0 \n", | |
| "50 1 3 1 0 \n", | |
| "51 4 1 2 1 \n", | |
| "52 2 2 2 1 \n", | |
| "53 1 0 0 1 \n", | |
| "54 3 3 0 1 \n", | |
| "55 2 2 1 1 \n", | |
| "56 2 1 1 1 \n", | |
| "57 2 0 2 0 \n", | |
| "58 3 1 1 0 \n", | |
| "\n", | |
| "[59 rows x 40 columns]\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "import pandas as pd\n", | |
| "\n", | |
| "df = pd.read_csv(r'data/inflammation-01.csv')\n", | |
| "print(df)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 49, | |
| "id": "2223ef6b", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| " 1 2 4 7 8\n", | |
| "0 2 1 3 2 2\n", | |
| "1 1 2 6 2 5\n", | |
| "2 2 2 2 1 6\n", | |
| "3 1 1 3 5 2\n", | |
| "4 1 4 2 1 6\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "ndf = pd.DataFrame(df, columns=['1', '2', '4', '7', '8']).head()\n", | |
| "print(ndf)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 50, | |
| "id": "16e2e180", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "<class 'pandas.core.frame.DataFrame'>\n", | |
| "RangeIndex: 5 entries, 0 to 4\n", | |
| "Data columns (total 5 columns):\n", | |
| " # Column Non-Null Count Dtype\n", | |
| "--- ------ -------------- -----\n", | |
| " 0 1 5 non-null int64\n", | |
| " 1 2 5 non-null int64\n", | |
| " 2 4 5 non-null int64\n", | |
| " 3 7 5 non-null int64\n", | |
| " 4 8 5 non-null int64\n", | |
| "dtypes: int64(5)\n", | |
| "memory usage: 328.0 bytes\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "ndf.info()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 51, | |
| "id": "ae578c3a", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>1</th>\n", | |
| " <th>2</th>\n", | |
| " <th>4</th>\n", | |
| " <th>7</th>\n", | |
| " <th>8</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>count</th>\n", | |
| " <td>5.000000</td>\n", | |
| " <td>5.000000</td>\n", | |
| " <td>5.000000</td>\n", | |
| " <td>5.000000</td>\n", | |
| " <td>5.00000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>mean</th>\n", | |
| " <td>1.400000</td>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>3.200000</td>\n", | |
| " <td>2.200000</td>\n", | |
| " <td>4.20000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>std</th>\n", | |
| " <td>0.547723</td>\n", | |
| " <td>1.224745</td>\n", | |
| " <td>1.643168</td>\n", | |
| " <td>1.643168</td>\n", | |
| " <td>2.04939</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>min</th>\n", | |
| " <td>1.000000</td>\n", | |
| " <td>1.000000</td>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>1.000000</td>\n", | |
| " <td>2.00000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>25%</th>\n", | |
| " <td>1.000000</td>\n", | |
| " <td>1.000000</td>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>1.000000</td>\n", | |
| " <td>2.00000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>50%</th>\n", | |
| " <td>1.000000</td>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>3.000000</td>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>5.00000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>75%</th>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>3.000000</td>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>6.00000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>max</th>\n", | |
| " <td>2.000000</td>\n", | |
| " <td>4.000000</td>\n", | |
| " <td>6.000000</td>\n", | |
| " <td>5.000000</td>\n", | |
| " <td>6.00000</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " 1 2 4 7 8\n", | |
| "count 5.000000 5.000000 5.000000 5.000000 5.00000\n", | |
| "mean 1.400000 2.000000 3.200000 2.200000 4.20000\n", | |
| "std 0.547723 1.224745 1.643168 1.643168 2.04939\n", | |
| "min 1.000000 1.000000 2.000000 1.000000 2.00000\n", | |
| "25% 1.000000 1.000000 2.000000 1.000000 2.00000\n", | |
| "50% 1.000000 2.000000 3.000000 2.000000 5.00000\n", | |
| "75% 2.000000 2.000000 3.000000 2.000000 6.00000\n", | |
| "max 2.000000 4.000000 6.000000 5.000000 6.00000" | |
| ] | |
| }, | |
| "execution_count": 51, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "ndf.describe()" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 52, | |
| "id": "37852d1c", | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [ | |
| "%matplotlib inline" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 53, | |
| "id": "6fc9e710", | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/plain": [ | |
| "<AxesSubplot: >" | |
| ] | |
| }, | |
| "execution_count": 53, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| }, | |
| { | |
| "data": { | |
| "image/png": "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\n", | |
| "text/plain": [ | |
| "<Figure size 432x288 with 1 Axes>" | |
| ] | |
| }, | |
| "metadata": { | |
| "needs_background": "light" | |
| }, | |
| "output_type": "display_data" | |
| } | |
| ], | |
| "source": [ | |
| "ndf.plot()" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python 3 (ipykernel)", | |
| "language": "python", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.9.7" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| >SEQUENCE_1 | |
| MTEITAAMVKELRESTGAGMMDCKNALSETNGDFDKAVQLLREKGLGKAAKKADRLAAEG | |
| LVSVKVSDDFTIAAMRPSYLSYEDLDMTFVENEYKALVAELEKENEERRRLKDPNKPEHK | |
| IPQFASRKQLSDAILKEAEEKIKEELKAQGKPEKIWDNIIPGKMNSFIADNSQLDSKLTL | |
| MGQFYVMDDKKTVEQVIAEKEKEFGGKIKIVEFICFEVGEGLEKKTEDFAAEVAAQL | |
| >SEQUENCE_2 | |
| SATVSEINSETDFVAKNDQFIALTKDTTAHIQSNSLQSVEELHSSTINGVKFEEYLKSQI | |
| ATIGENLVVRRFATLKAGANGVVNGYIHTNGRVGVVIAAACDSAEVASKSRDLLRQICM |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment