{ "cells": [ { "cell_type": "markdown", "id": "9965f1b0", "metadata": { "nbgrader": { "grade": false, "grade_id": "cell-3b587ecf818e3119", "locked": true, "schema_version": 3, "solution": false, "task": false } }, "source": [ "# Exercises\n", "\n", "Each exercise carries the difficulty level indication:\n", "- [*] Easy\n", "- [**] Moderate\n", "- [***] Advanced\n", "\n", "The highest difficulty level is meant for students who wish to challenge themselves and/or have previous experience in programming." ] }, { "cell_type": "markdown", "id": "d04ec513", "metadata": {}, "source": [ "````{exercise} [*] Boolean logic\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Johan/01_Checkpoint_enzyme.py>`\n", "\n", "**Note**: this exercise contains an introduction, which is absent from the downloadable exercise (`.py`) file.\n", "\n", "```{admonition} Introduction\n", ":class: note, dropdown\n", "\n", "**Boolean logic**\n", "\n", "Boolean logic is a fundamental underlying technique for computers. It works based on two values - true and false.\n", "In the computer, this is represented as 1 and 0, respectively. In Python, these are the `bool` types (`True` and `False`).\n", "\n", "There are a number of basic operations (Boolean operators):\n", "* AND\n", "* OR\n", "* NOT\n", "\n", "We'll go through each one individually first.\n", "\n", "**The basic operators:**\n", "\n", "AND returns true (1) if and only if both of the given values are true.\n", "The AND operator is represented in Python by the keyword `and`.\n", "\n", "OR returns true if either of the inputs are true. This also means that if both inputs are true,\n", "it will also return true. The OR operator is represented in Python by the keyword `or`.\n", "\n", "NOT returns the opposite of the given value.\n", "For instance, if you have the value `a = True`, `not a` will return `False`.\n", "The NOT operator is given in Python by `not`.\n", "\n", "\n", "**Combinations of operators**\n", "\n", "The basic operators can be combined to produce more advanced behaviors. For instance, if you need three values to all be true for something to happen, then it may be combined in a statement something like `(a and b) and c`.\n", "It may look clunky, but it does work.\n", " \n", "In a more real-world example, say you are modelling a cell dividing.\n", "To divide, it needs to check that a number of things are correct:\n", "* Has the DNA been copied successfully?\n", "* Is there any cell damage?\n", "* Is there enough space to divide?\n", "This can be checked by combining everything into one large `and` statement.\n", "\n", "**Truth tables**\n", "\n", "[Truth tables](https://en.wikipedia.org/wiki/Truth_table) are a tool that presents in an organized way the outcome of a statement depending on the inputs.\n", "It is a useful way for organizing or figuring out the result of many inputs into a complex statement\n", "```\n", "\n", "In this set of exercises, we will combine basic Boolean operators to define \n", "when certain biological events are allowed to take place.\n", "\n", "**Exercise A**: Cell cycle G1 checkpoint\n", "\n", "Define three variables - `DNA_damaged`, `E2F_present`, and `not_touching` - and assign \n", "Boolean values to them. The statement `can_pass_g1` should be true if there is \n", "enough space, no DNA damage, and no E2F proteins. You can try to assign \n", "different values to the three variables and see how these affect the outcome\n", "(`can_pass_g1`).\n", "\n", "Use this as a guideline:\n", "* `DNA_damaged` - true if damaged\n", "* `E2F_present` - true if present\n", "* `not_touching` - true if it is not overcrowded\n", "\n", "```\n", "# Your code here\n", "\n", "can_pass_g1 = # Your code here\n", "```\n", "\n", "**Exercise B**: Cell cycle G2-M checkpoint\n", "\n", "Define two variables - `DNA_damaged` and `cyclinB_present` - and assign Boolean values\n", "to them. The statement `can_pass_g2m` should read true if there is no DNA damage \n", "and if cyclinB is present. You can try to assign different values to the two \n", "variables and see how these affect the outcome (is the cell allowed to pass the \n", "cell cycle checkpoint).\n", "\n", "Use this as a guideline:\n", "* `DNA_damaged` - true if damaged\n", "* `cyclinB_present` - true if present\n", "\n", "```\n", "# Your code here\n", "\n", "can_pass_g2m = # Your code here\n", "```\n", "\n", "**Exercise C**: Enzyme production\n", "\n", "Define two Boolean variables - `MetA_present` and `MetB_present` - and assign value to\n", "them. Based on these variables, define `make_enzyme`. The cell should start \n", "to produce the enzyme if metabolite A or metabolite B is present, but not both.\n", "How does changing the values of `MetA_present` or `MetB_present` affect the outcome?\n", "\n", "Use this as a guideline:\n", "* `MetA_present` - true if present\n", "* `MetB_present` - true if present\n", "\n", "```\n", "# Your code here\n", "\n", "make_enzyme = # Your code here\n", "```\n", "\n", "**Exercise D**: (Optional) Cancer\n", "\n", "Rewrite Exercise A so that the behaviour would imitate that of cancer.\n", "\n", "```\n", "# Your code here\n", "```\n", "\n", "````" ] }, { "cell_type": "markdown", "id": "f6be32b0", "metadata": {}, "source": [ "`````{exercise} [*] Logical statements: debugging \n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Johan/02_Logical_statements.py>`\n", "\n", "**Note**: this exercise contains an introduction, which is absent from the downloadable exercise (`.py`) file.\n", "\n", "````{admonition} Introduction\n", ":class: note, dropdown\n", "\n", "**Logical statements**\n", "\n", "In the previous exercise, we covered Boolean logic - combining true and false statements to generate logic.\n", "The next logical question is then: \"how to generate these true-false statements?\"\n", "This is done using logical statements.\n", "\n", "\n", "**Numerical/value comparison**\n", "\n", "This type of logical statements is the simplest one, where we essentially compare a value (the variable containing that value) to another one.\n", "There are the following operators:\n", "* `==` - Equals (*note the double equal*)\n", "* `>` - Greater than\n", "* `<` - Less than\n", "* `!=` - Is not equal to. `!` often acts as a NOT operator in programming\n", "* `>=` - Greater or equal to\n", "* `<=` - Less than or equal to\n", "\n", "With Python, it is possible to add a lot of things to the comparison.\n", "For instance, doing simply:\n", "\n", "```\n", "str_a = \"this is a test\"\n", "str_b = \"this is a test\"\n", "\n", "is_the_same = (str_a == str_b)\n", "```\n", "\n", "will result in `is_the_same` being `True`.\n", "\n", "You will use these types of comparisons in most of your coding.\n", "\n", "\n", "**Other ways to generate True/False**\n", "\n", "Boolean True/False may also be given by some other things:\n", "\n", "* Non-Boolean variables can by themselves be interpreted as Booleans, e.g., numerics (`float`, `int`) if they are equal to 0 are interepreted as `False`.\n", "\n", "* `in` checks if an item is contained within a set-like Python type, e.g., `x in array_y` tests if the value of `x` is in `array_y` and returns `True` if it is. It also works for strings.\n", "\n", "* A command or function can itself return `True` or `False`, which may be useful for catching errors or exceptions.\n", "\n", "````\n", "\n", "**Exercise A**: Predict True or False\n", "\n", "For the three pieces of code below, predict whether they will return True or False\n", "without running the code. To check whether your prediction is correct, run the\n", "code with the needed `print()` statements.\n", "\n", "````\n", "# Code 1\n", "gfp_prot_seq = \"\"\n", "pred1 = bool(gfp_prot_seq)\n", "# Your prediction for pred1 = True or False?\n", "\n", "\n", "# Code 2\n", "gfp_prot_seq = \"MSKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKFICTTGKLPVPWPTLVTTFSYGVQCFSRYPDHMKQHDFFKSAMPEGYVQERTIFFKDDGNYKTRAEVKFEGDTLVNRIELKGIDFKEDGNILGHKLEYNYNSHNVYIMADKQKNGIKVNFKIRHNIEDGSVQLADHYQQNTPIGDGPVLLPDNHYLSTQSALSKDPNEKRDHMVLLEFVTAAGITHGMDELYK\"\n", "pred2 = bool(gfp_prot_seq)\n", "# Your prediction for pred2 = True or False?\n", "\n", "\n", "# Code 3\n", "animal = \"rabbit\"\n", "mammals = [\"giraffe\", \"elephant\", \"lion\", \"rabbit\", \"guinea pig\", \"vole\", \"shrew\", \"human\", \"cat\", \"dog\"]\n", "reptiles = [\"crocodile\", \"iguana\", \"alligator\", \"boa\", \"cobra\", \"python\", \"anole\", \"turtle\", \"tortoise\", \"tuatara\"]\n", "pred3 = animal in mammals\n", "# Your prediction for pred3 = True or False?\n", "````\n", "\n", "**Exercise B**: Code debugging\n", "\n", "The statements in each of the three pieces of code below should be true. Understand why\n", "they are not, and fix the code.\n", "\n", "````\n", "# Code 1\n", "x = 1.4 * 1.5\n", "print(f\"Is x = 2.1? {bool(x == 2.1)}\")\n", "\n", "\n", "# Code 2\n", "y = 'a' + 7\n", "test_ar = ['a', 'b', 'c', 'd', 'e', 'f', 'g']\n", "print(f\"Is y in the test_ar? {bool(y in test_ar)}\")\n", "\n", "\n", "# Code 3\n", "test_ar = ['a', 'b', 'c', 'd', 'e', 'f', 'g']\n", "z = 7\n", "print(f\"Is z longer than the test array? {bool(z > len(test_ar))}\")\n", "````\n", "\n", "`````" ] }, { "cell_type": "markdown", "id": "39924389", "metadata": {}, "source": [ "`````{exercise} [**] Lamp: debugging\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Nina/08_Lamp.zip>`\n", "\n", "The code below is the implementation of the following algorithm:\n", "\n", "```{figure} ../images/chapter1/Algorithm_example.png\n", "---\n", "height: 300px\n", "name: alg_lamp\n", "---\n", "```\n", "\n", "However, both logical and syntax bugs are introduced into the code. Try to fix them all and make a functional code implementation of the outlined algorithm.\n", "\n", "Hint: there are six bugs.\n", "\n", "```\n", "lamp_working = \"yes\"\n", "plugged_in = \"no\"\n", "burned_bulb = \"yes\"\n", "\n", "if lamp_works == no:\n", " if plugged_in == \"no\":\n", " print(\"Plug it in!\")\n", " else:\n", " if burned_bulb = \"yes\":\n", " print(\"Buy a new lamp :(\")\n", " else:\n", " print(\"Replace the light bulb!)\n", " else:\n", " print(\"All is good :)\")\n", "```\n", "\n", "`````" ] }, { "cell_type": "markdown", "id": "6674a475", "metadata": {}, "source": [ "`````{exercise} [*] DNA sequence and if/else/elif \n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Johan/03_DNA_sequence.py>`\n", "\n", "**Note**: this exercise contains an introduction, which is absent from the downloadable exercise (`.py`) file.\n", "\n", "````{admonition} Introduction\n", ":class: note, dropdown\n", "\n", "**The `if` statement**\n", "\n", "The `if` statement is the most basic flow control statement; it indicates that if something is true, then the program should do something.\n", "\n", "```\n", "a = True\n", "\n", "if a:\n", "\tprint(\"a is true\")\n", "```\n", "\n", "The part immediately following `if` is a logical statement.\n", "Any code that is **indented** will be run if the logical statement is true. If not, it will be skipped.\n", "\n", "Some additional notes on what can be put in as a logical statements:\n", "* A single Boolean value can be put in without comparison to `True` or `False`.\n", "* Lists, strings, and tuples can also be put into an `if` statement. They are interpreted as `False` if they are empty, `True` if they are not.\n", "* Any numeric value (`int`, `float`, etc.) equal to 0 is also interpreted as `False`.\n", "\n", "\n", "**The `else` statement**\n", "\n", "Sometimes you want the computer to do something else in the case the original `if` statement is not true.\n", "This is where `else` is used.\n", "\n", "```\n", "if a is True:\n", "\tprint(\"a is true\")\n", "else:\n", "\tprint(\"a is false\")\n", "```\n", "In this example, it will printed that a is false if a is not true.\n", "\n", "Note that this code:\n", "\n", "```\n", "test_var = True\n", "if test_var:\n", " print(\"The test variable is true\")\n", "else:\n", " print(\"The test variable is false\")\n", "```\n", "\n", "will behave differently than this one:\n", "\n", "```\n", "test_var = True\n", "if test_var:\n", " print(\"The test variable is true\")\n", "print(\"The test variable is false\")\n", "```\n", "\n", "In the latter case, the computer does not \"know\" that the second `print` line should be exclusive with the first `print`.\n", "\n", "\n", "\n", "**The `elif` statement**\n", "\n", "Sometimes, the computer needs to make more than one decision at a time.\n", "\n", "This can be written:\n", "```\n", "if a is True:\n", "\t# do something\n", "else:\n", "\tif b is True:\n", "\t\t# do something else\n", "\telse:\n", "\t\tif: c is True\n", "\t\t\t# do a different thing\n", "\t\telse:\n", "\t\t\t# do another thing\n", "```\n", "This uses a lot of indentation and generally, is not very pretty.\n", "`elif` combines the `else` and `if` into a single keyword and keeps everything on the same indent.\n", "It makes things much neater, and a chain of decisions can be made.\n", "\n", "The above example, for instance, becomes:\n", "\n", "```\n", "if a is True:\n", "\t# do something\n", "elif b is True:\n", "\t# do something else\n", "elif c is True:\n", "\t# do a different thing\n", "else:\n", "\t# do another thing\n", "\n", "```\n", "\n", "\n", "**(Advanced reading) Match Case**\n", "\n", "In some cases, you may want to check that a single variable is one of many values.\n", "\n", "Say, for example, you want the program to behave differently depending on the `cell_type`.\n", "This can be done like this, with a lot of `if`/`elif` statements:\n", "\n", "```\n", "cell_type = \"\"\n", "\n", "if cell_type is \"neuron\":\n", "\t# do neuron things\n", "elif cell_type is \"skin\":\n", "\t# do skin things\n", "elif cell_type is \"muscle\":\n", "\t# do muscle things\n", "elif cell_type is \"stomach\":\n", "\t# do stomach things\n", "```\n", "\n", "`match case` allows you to check all of these cases in a neater way:\n", "\n", "```\n", "match cell_type:\n", "\tcase \"neuron\":\n", "\t\t# do neuron things\n", "\tcase \"skin\":\n", "\t\t# do skin things\n", "\tcase \"muscle\":\n", "\t\t# do muscle things\n", "\tcase \"stomach\":\n", "\t\t# do stomach things\n", "\tcase _:\n", "\t\t# do nothing\n", "```\n", "\n", "Note the last `case _:` - the underscore will catch anything that does not match any earlier cases.\n", "It is the default, and typically used for some error or unexpected input.\n", "\n", "The `match case` also lets you do more advanced pattern matching, which is beyond the scope of this book.\n", "\n", "````\n", "\n", "This set of exercises is meant as practice on using `if`, `else`, and\n", "`elif` in Python.\n", " \n", "These will be done on DNA sequences, or rather strings that represent DNA\n", "sequences. This may be helpful in the future in bioinformatics.\n", "\n", "**Exercise: Pseudocode**\n", "\n", " For each of the exercises below, start by writing pseudocode on a piece of paper. Only once you're done with pseudocode should you start working on Python code in VS Code.\n", "\n", "**Exercise A**: DNA subsequence\n", "\n", "Write an `if` statement to check if a DNA subsequence is in a longer sequence.\n", "Store the outcome in the Boolean variable `in_seq` and print the value of `in_seq`. \n", "You do not need to use any loops.\n", "\n", "You can define `DNA_subsequence` on your own. Check that your code works both\n", "for subsequences that are and are not contained in the sequence.\n", "\n", "````\n", "DNA = \"GGGACATATGCTCCGATTAAAGCGCATGATAGCCCGATAGGTAGATAGGGGTTCACGACG\"\n", "DNA_subsequence = # Your code here\n", "\n", "# Your code here\n", "````\n", "\n", "**Exercise B**: DNA subsequence II\n", "\n", "Repeat the above, but also use an `else` statement to set `in_seq` to false if the \n", "DNA subsequence is not contained in the sequence. \n", "You do not need to use any loops.\n", "\n", "You can define `DNA_subsequence` on your own. Check that your code works both\n", "for subsequences that are and are not contained in the sequence.\n", "\n", "````\n", "DNA = \"GGGACATATGCTCCGATTAAAGCGCATGATAGCCCGATAGGTAGATAGGGGTTCACGACG\"\n", "DNA_subsequence = # Your code here\n", "\n", "# Your code here\n", "````\n", "\n", "**Exercise C**: Handling multiple sequences\n", "\n", "What if we want to check for presence of two different subsequences in our DNA \n", "sequence? Write code that informs the user through `print` statements whether \n", "`subsequence_1`, `subsequence_2`, none, or both of them are present in the DNA \n", "sequence. You do not need to use any loops.\n", "\n", "````\n", "DNA = \"GGGACATATGCTCCGATTAAAGCGCATGATAGCCCGATAGGTAGATAGGGGTTCACGACG\"\n", "DNA_subsequence_1 = \"ATGCTCCG\"\n", "DNA_subsequence_2 = \"TAGGTAGATATGGGTTC\"\n", "\n", "# Your code here\n", "````\n", "\n", "`````\n" ] }, { "cell_type": "markdown", "id": "21f4408e", "metadata": {}, "source": [ "````{exercise} [**] DNA and RNA \n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Johan/04_DNA_RNA.py>`\n", "\n", "\n", "According to the central dogma in molecular biology, genetic information in \n", "biological systems flows from DNA to RNA to protein. DNA is a double-stranded\n", "molecule containing two complementary strands. To make mRNA, a part of a \n", "DNA strand is transcribed, and the resulting mRNA has nucleotides complementary to \n", "the DNA template (note: RNA contains uracil instead of thymine). To produce \n", "a protein, ribosomes then use codons (sets of three nucleotides) on mRNA, which are \n", "matched with their complementary anticodones on aminoacid-carrying tRNAs. \n", "\n", "**Exercise: Pseudocode**\n", "\n", " For each of the exercises below, start by writing pseudocode on a piece of paper. Only once you're done with pseudocode should you start working on Python code in VS Code.\n", "\n", "**Exercise A**: DNA strands\n", "\n", "Find the strand complementary to the given DNA strand.\n", "Note that the input DNA string may *not* be only made of A, T, G, and C.\n", "The program should be able to handle this: represent a failed match as X.\n", "\n", "Store the output string in `DNA_complement` variable.\n", "\n", "```\n", "DNA = \"GPAGAGATTTYGTGACAGCATABGACGAGATTTTAGATACCCGATATATAGAHCG\"\n", "\n", "# Your code here\n", "```\n", "\n", "\n", "**Exercise B**: Transcription\n", "\n", "Transcribe the given DNA sequence into an mRNA sequence.\n", "Note that the input DNA string may *not* be only made of A, T, G, and C.\n", "The program should be able to handle this: represent a failed match as X.\n", "\n", "Store the output string in mRNA variable.\n", "\n", "```\n", "DNA = \"GPAGAGATTTYGTGACAGCATABGACGAGATTTTAGATACCCGATATATAGAHCG\"\n", "\n", "# Your code here\n", "```\n", "\n", "\n", "**Exercise C** (Bonus): Match case\n", "\n", "Do the same as in Exercise B, but use `match case`.\n", "\n", "```\n", "DNA = \"GPAGAGATTTYGTGACAGCATABGACGAGATTTTAGATACCCGATATATAGAHCG\"\n", "\n", "# Your code here\n", "```\n", "\n", "````" ] }, { "cell_type": "markdown", "id": "cba79339", "metadata": {}, "source": [ "`````{exercise} [**] Green fluorescent protein (GFP)\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Johan/05_GFP.py>`\n", "\n", "**Note**: this exercise contains an introduction, which is absent from the downloadable exercise (`.py`) file.\n", "\n", "````{admonition} Introduction\n", ":class: note, dropdown\n", "\n", "**`for` loop**\n", "\n", "Very often one needs to do something multiple times, or to multiple objects.\n", "This is where [loops](../chapter6/loops.ipynb) become useful.\n", "There are two types within Python - `for` and `while`. \n", "We will work with `for` loops first.\n", "\n", "`for` loops work on a fixed number of iterations: they take some variable and run it over the same block of code multiple times.\n", "Very often the variable is also changed in between runs (iterated over).\n", "\n", "**Iteration with `range()`**\n", "\n", "A standard `for` loop may look like the following:\n", "\n", "```\n", "for x in range(n):\n", "\tprint(x)\n", "```\n", "\n", "`range()` defines the range over which `x` will \"run\" (here *n* times, from 0 to *n*-1).\n", "`x` will increase by 1 each iteration.\n", "`range()` can also be given more arguements to define other behaviors, such as starting from a given\n", "value and using a certain step size.\n", "For more info, see [here](https://docs.python.org/3.12/library/functions.html#func-range).\n", "\n", "\n", "**`for` loops with iterables**\n", "\n", "Certain objects, like lists and strings, are able to be looped over\n", "without using `range()`.\n", "The `for` loop then becomes something like the following:\n", "\n", "```\n", "for item in list:\n", "\tdo something with item\n", "```\n", "\n", "Every time the loop is run, the next item in the list is being used compared to the previous loop run.\n", "\n", "This is generally considered better style-wise than doing:\n", "\n", "```\n", "for i in range(len(list)):\n", "\tdo something with list[i]\n", "```\n", "\n", "which is functionally the same.\n", "\n", "**Looping over multiple things**\n", "\n", "One may ask \"what if I want to loop over two things at the same time?\", which is a very valid question.\n", "A loop for that may be written as follows:\n", "\n", "```\n", "for a, b in zip(list_a, list_b):\n", "\tdo stuff with a and b\n", "```\n", "\n", "This will iterate over `list_a` and `list_b` in parallel, stopping when the end of the shortest is reached.\n", "More finely tuned behavior can be achieved, such as running until both `list_a` and `list_b`\n", "are exhausted or requiring that the two lists are the same length.\n", "\n", "\n", "**Nested `for` loops**\n", "\n", "Nested `for` loops are like the name implies - a `for` loop within another `for` loop.\n", "These are useful if one is working with multidimensional data (i.e., a 2D list)\n", "or combinations of two different variables (say all possible values of $x^2$ + $y^2$ for $x$ and $y$ between 0 and 10).\n", "\n", "While useful, do keep in mind that it tends to be regarded as somewhat inelegant, and in some cases there are ways\n", "of avoiding excessive nesting (e.g., vectorization or built-in functions that work on large chunks).\n", "\n", "````\n", "\n", "\n", "According to the central dogma in molecular biology, genetic information in \n", "biological systems flows from DNA to RNA to protein. To make mRNA, a part of a \n", "DNA strand is transcribed. The resulting mRNA has nucleotides complementary to \n", "the DNA template (note: RNA contains uracil instead of thymine). To produce \n", "a protein, ribosomes then use codons (sets of three nucleotides) on mRNA, which are \n", "matched with their complementary anticodones on aminoacid-carrying tRNAs. \n", "\n", "Let's go through the process of a) transcription, b) translation, and c) checking \n", "for mutations in GFP, everyone's favourite marker protein.\n", "\n", "**Pseudocode**\n", "\n", " For each of the exercises below, start by writing pseudocode on a piece of paper. Only once you're done with the pseudocode should you start working on Python code in VS Code.\n", " \n", "**Exercise A**: GFP transcription\n", "\n", "Write a for loop that will take the string `GFP_DNA` and convert it to the \n", "complementary RNA sequence. Put it into a string called `GFP_RNA`.\n", "You do not have to worry about reversing the order.\n", "You may assume the input is all capital letters and contains only A, T, C, \n", "and G. Return the `GFP_RNA` string as capital letters as well.\n", "\n", "````\n", "GFP_DNA = \"TATTTACGATGAGCAAAGGCGAAGAACTGTTTACCGGCGTGGTGCCGATTCTGGTGGAACTGGATGGC\\\n", " GATGTGAACGGCCATAAATTTAGCGTGAGCGGCGAAGGCGAAGGCGATGCGACCTATGGC\\\n", " AAACTGACCCTGAAATTTATTTGCACCACCGGCAAACTGCCGGTGCCGATGCCGACCCTG\\\n", " GTGACCACCTTTAGCTATGGCGTGCAGTGCTTTAGCCGCTATCCGGATCATGCGAAACAG\\\n", " CATGATTTTTTTAAAAGCGCGATGCCGGAAGGCTATGTGCAGGAACGCACCATTTTTTTT\\\n", " AAAGATGATGGCAACTATAAAACCCGCGCGGAAGTGAAATTTGAAGGCGATACCCTGGTG\\\n", " AACCGCATTGAACTGAAAGGCATTGATTTTAAAGAAGATGGCAACATTCTGGGCCATAAA\\\n", " CTGGAATATAACTATAACAGCCATAACGTGTATATTATGGCGGATAAACTGAAAAACGGC\\\n", " ATTAAAGTGAACTTTAAAATTCGCCATAACATTGAAGATGGCAGCGTGCAGCTGGCGGAT\\\n", " CATTATCAGCAGAACACCCCGATTGGCGATGGCCCGGTGCTGCTGCCGGATAACCATTAT\\\n", " CTGAGCACCCAGAGCGCGCTGAGCAAAGATCCGAACGAAAAACGCGATCATATGGTGCTG\\\n", " CTGGAATTTGTGACCGCGGCGGGCATTACCCATGGCATGGATGAACTGATTAAA\"\n", "\n", "# Your code here\n", "````\n", "\n", "\n", "**Exercise B**: GFP translation\n", "\n", "Write a for loop that will take the output string `GFP_RNA` from Exercise A and\n", "return the protein code `GFP_protein` (as capitalized one-letter amino acid codes).\n", "You *cannot* assume that the coding sequence is aligned with the start of your \n", "sequence (i.e., there may be nucleotides in the RNA sequence before the start codon).\n", "\n", "Use standard RNA codon table from:\n", "https://en.wikipedia.org/wiki/DNA_and_RNA_codon_tables\n", "\n", "````\n", "# Your code here\n", "````\n", "\n", "\n", "**Exercise C**: GFP mutations\n", "\n", "After trying to grow the cells with the protein you just translated, the cells \n", "were yellow. It turns out the colleagues who gave us the GFP actually gave us a \n", "GFP variant with 4 mutations.\n", "\n", "Write a code that gives a list of the amino acid mutations written as XNY, \n", "where X is the original amino acid, N is the position of the mutation, and \n", "Y is the new amino acid.\n", "Example: A mutation of K to G at position 55 is written as **K55G**.\n", "\n", "As input you have:\n", "* `GFP_protein` - your sequence from the previous section\n", "* `GFP_reference` - a reference sequence\n", "\n", "You may assume the sequences are the same length.\n", "\n", "````\n", "GFP_reference = \"MSKGEELFTGVVPILVELDGDVNGHKFSVSGEGEGDATYGKLTLKFICTTGKLPVPWPTL\\\n", " VTTFSYGVQCFSRYPDHMKQHDFFKSAMPEGYVQERTIFFKDDGNYKTRAEVKFEGDTLV\\\n", " NRIELKGIDFKEDGNILGHKLEYNYNSHNVYIMADKQKNGIKVNFKIRHNIEDGSVQLAD\\\n", " HYQQNTPIGDGPVLLPDNHYLSTQSALSKDPNEKRDHMVLLEFVTAAGITHGMDELYK\"\n", "\n", "# Your code here\n", "````\n", "\n", "`````" ] }, { "cell_type": "markdown", "id": "9d66d420", "metadata": {}, "source": [ "`````{exercise} [**] Bacterial population modelling\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Johan/06_Bacterial_population.py>`\n", "\n", "**Note**: this exercise contains an introduction, which is absent from the downloadable exercise (`.py`) file.\n", "\n", "````{admonition} Introduction\n", ":class: note, dropdown\n", "\n", "**`while` loops**\n", "\n", "The `while` loop is another way to repeat an action multiple times and\n", "is especially useful when you do not know how many times you need to loop over a function: `while` will simply repeat forever while the condition inside is true.\n", "\n", "A typical construction is the following:\n", "\n", "```\n", "while error >= 0.0001:\n", "\t# do some calculation\n", "```\n", "\n", "This calculation will continue until the desired (low enough) error is reached.\n", "\n", "An infinite loop can be created in the following way:\n", "\n", "```\n", "while True:\n", "\tprint(\"This while loop will continue forever\")\n", "```\n", "\n", "You should try it - it's a chance to explore how to stop code from continuing to run in VS Code.\n", "Also, accidentally creating infinite loops happens to everyone, so don't panic if it happens to you :)\n", "\n", "A good practice to prevent this from happening excessively is to add a counter in the `while` loop, which will force\n", "the condition to become false if the loop has been running for too long. \n", "This is an example code with counter `i`:\n", "\n", "```\n", "some_condition = true\n", "i = 0\n", "while (some_condition and i <= 10000):\n", "\tprint(\"This while loop will exit after 10000 times\")\n", "\ti += 1 # Increase counter for 1\n", "```\n", "\n", "\n", "**`break` and `continue`**\n", "\n", "The `break` and `continue` statements can be used to further control `for` and `while` loops.\n", "\n", "`break` will leave the innermost loop that it is in, skipping the rest of the loop.\n", "This might be useful for things like error cases, or places where you don't care about the results from some loop.\n", "\n", "`continue` will move to the next iteration of the loop, skipping whatever is below it.\n", "\n", "\n", "For additional information on control flow, see [here](https://docs.python.org/3/tutorial/controlflow.html).\n", "\n", "````\n", "\n", "You are using different types of bacterial populations to potentially use for\n", "pharmaceutical synthesis. You want to find out which population is growing the \n", "fastest. You have decided that the best way to find out is by doing some \n", "simulations of the growth.\n", "\n", "Note: `break` and `continue` are not necessarily required to solve the two exercises.\n", "\n", "**Pseudocode**\n", "\n", " For each of the exercises below, start by writing pseudocode on a piece of paper. Only once you're done with pseudocode should you start working on Python code in VS Code.\n", "\n", "**Exercise A:** Which strain grows faster?\n", "\n", "Write code in which you follow the growth of two bacterial populations, A and B.\n", "\n", "We use the following information:\n", "`initial_population` - initial population of cells \n", "`division_t` - division time in minutes\n", "\n", "If the population of B ever becomes greater than population of A,\n", "set `is_B_faster` to 'True'. If not, set `is_B_faster` to 'False'.\n", "\n", "The maximum time (`max_time`) you have to simulate is 7 days.\n", "\n", "```\n", "initial_population_A = 120000 # cells \n", "initial_population_B = 241000 # cells \n", "division_t_A = 45 # min\n", "division_t_B = 35 # min\n", "\n", "# Your code here\n", "```\n", "\n", "**Exercise B**: Delayed division start\n", "\n", "Do the same as in Exercise A (you can reuse the code you just wrote),\n", "but this time also account for the time before the cells start dividing (`start_t`),\n", "which is different for the two bacterial populations.\n", "\n", "```\n", "start_t_A = 700 # min\n", "start_t_B = 1200 # min\n", "\n", "# Your code here\n", "```\n", "\n", "\n", "**Exercise C**: Race to 1 million cells\n", "\n", "Repeat the same idea as in Exercise B, trying to find the fastest-growing strain.\n", "This time, however, you are given tuples corresponding to bacterial strains. \n", "Each tuple consists of the following: (initial_population, division_t, start_t).\n", "\n", "Return the name of the fastest growing strain in `best_strain`, which is \n", "defined as the quickest strain to reach 1,000,000 cells.\n", "\n", "```\t\n", "strain_A = (100000, 30, 1000) \n", "strain_B = (120000, 40, 800) \n", "strain_C = (90000, 35, 500) \n", "\n", "# Your code here\n", "```\n", "\n", "`````" ] }, { "cell_type": "markdown", "id": "c80d30d8", "metadata": {}, "source": [ "````{exercise} [**] Number guess game\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Margreet/03_Number_guess.py>`\n", "\n", "Imagine a number guessing game, where one person chooses a number (let's say 31) and the other tries to guess it:\n", "\n", "Question: \"Is it 25?\" \\\n", "Answer: \"No, it is higher.\" \\\n", "Question: \"Is it 37? \\\n", "Answer: \"No, it is lower.\" \\\n", "Question: \"Is it 33?\"\n", "\n", "Let's implement this game in Python:\n", "* Define a number between 1 and 100.\n", "* Ask the user to guess it via the `input()` function. \n", "* After each guess, you have to say whether the answer is correct, or higher or lower than the guess.\n", "* The game finishes when the guess is correct.\n", "\n", "```\n", "# Your code here\n", "```\n", "\n", "`````" ] }, { "cell_type": "markdown", "id": "0f438469", "metadata": {}, "source": [ "`````{exercise} [**] CRISPR implementation\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Johan/08_CRISPR.py>`\n", "\n", "In this exercise you will implement a basic version of CRISPR-Cas9.\n", "\n", "```{figure} ../images/chapter6/Cas9.png\n", "---\n", "height: 250px\n", "name: crispr\n", "---\n", "CRISPR-Cas9 ([figure source](https://en.wikipedia.org/wiki/CRISPR_gene_editing), figure license CC BY-SA 4.0).\n", "```\n", "\n", "Cas9 protein contains a small piece of RNA called guide RNA (gRNA).\n", "This gRNA is used to scan a DNA sequence. If DNA sequence complementary to gRNA is found AND \n", "if there is a small protospace adjacent motif (PAM) immediately following the matched sequence, \n", "Cas9 will cleave the DNA four nucleotides before the PAM.\n", "\n", "Replicate this behavior in Python code.\n", "\n", "We will assume that the PAM sequence is NGG, where N stands for any nucleotide (A, C, T, or G). \n", "The last two nucleotides are G (guanine).\n", "\n", "**Inputs**:\n", " - The DNA sequence to examine\n", " - The gRNA sequence to match against the DNA\n", " \n", "Both sequences will be given in the 5' to 3' direction, the RNA is the complement to the DNA.\n", "\n", "**Output**:\n", " - A list containing the sequence after it has been examined by Cas9\n", "\n", "E.g., if a sequence was originally 'ATTGGCC' and cleaved after ATT, the list looks like this: ['ATT', 'GGCC'].\n", "\n", "**Hints**:\n", "- Start by writing pseudocode on a piece of paper. Only once you're done with pseudocode should you start working on Python code in VS Code.\n", "- The input sequence may have more than one cleavage site, or no sites.\n", "- The input sequence and guide RNA are reverse complements.\n", "- There may be matches with the guide RNA, but not containing the PAM. These should not be cleaved.\n", "- You may find it useful to comment out the given DNA and RNA inputs and use your own \"toy examples\" while working on the code to test whether pieces of your code work.\n", "- The `replace` function may be useful (see more [here](https://www.w3schools.com/python/ref_string_replace.asp)).\n", " \n", "```\n", "DNA_seq = \"CTTTACGACAAGAGGTACGCTTTGTGAGCGCGCTCCGCCGGCCCTCGCGGACCCTTGCTACAAGCTCGACAGGATGTCTCCTCAGCATGTCCTACGTTGGAGGACCGCAACAGCGCCTGGCGGTGCGCACACAGCGGTCGACCGATTTGCGGAGTCCCAGGCCCGGCCGATCCCGTCCCGTACCCTGGTGGACCGTCTAGGGGTCACCTGCCCCTCCGCGATGATTAGATTGCCAGCCCGTAGCGTTTGCGGGTCGCCTACGCGGTCTCTCGGCTGCGCCGGGGATTCGAGCTAGGCCTTTGTAGGCCTGCCGCTGCACAAGGGCCAAAACTCTAACCCTCCCGTTAGCGGGGCGTACCTGGGAGAGGCCATGCCCACGAATGCGCGCCCCGCGGTTGCCTTTTGGGGGCGGGGTCGGCCCTCACGCCGGGGCCCCGTCGGCGCGTCTCTGCGACAAAGGACACCGCGCTGAGCCAAAAGGCTGGCGAGGAACCCGGGAAAAGGGCCCTGGCCCGGTACAGCCCGGGGCGGGGGCTACCCGGGCCTGGAGACCAAATTCGACCACGACCTAGGCCCGACGCGCGGGGCCCATGGCGTAAGCCACAGCAGCTAGAACGCCTTCTCGATAGGCCCACGAATCTGATCGTTGCTATAATAGACGACCTGGCCACCTGGGGAGAATTGAGTTGTTCATGCGCCCCCGGGAAAAGGGCCCTGGCCGTGTACACTCCGTCTAGCCCGAACCGCGAGCCCCACACCCGACCTCGACATGGCCTGGTTGGGTGGGCGGGCGACGGGCGTAGGCCGACCACCGCCGTGGCTGAGACGGCCCCAGAAGAACGTCGCGGGTCAGGCGTTTGAGTGTAACGAGGAACGCTCTTGGTCCACTTGGGGGTTCCCAACAGGTCCAGCGCCCGAGGTGTCGAGATACTGGGGCGCGCGTGGTTGCGGCTACTGGTATATGGATGCACTGGGAGTCCTCTTTGGCCCGGAATGGCTGCACAGCTAACTGGGGGCTCTTGCCCCCATCGGAGCGCGGGAACGCGCCACCGCTGGCA\"\n", "\n", "gRNA_seq = \"GGGCCCUUUUCCCGGG\"\n", "\n", "# Your code here\n", "```\n", "\n", "`````" ] }, { "cell_type": "markdown", "id": "5c9997a6", "metadata": {}, "source": [ "`````{exercise} [**] Nanobots\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Margreet/04_Nanobots.py>`\n", "\n", "Simulate the growth of a population of nanobots in a Petri dish. It starts with an initial population of nanobots which have a specific growth rate (e.g., 1.5 per generation). The simulation runs for the select number of generations, and at each generation, the simulation calculates the new population size by multiplying the current population by the growth rate. It then prints the current generation number and the population size. When the simulation is done, print \"Nanobot population simulation complete.\".\n", "\n", "Implement also the overpopulation condition for the Petri dish: if the population reaches 1 million, all nanobots die. Print a warning at which generation this happened.\n", "\n", "If the starting population is zero or below, print a warning.\n", "\n", "Try to experiment with different initial parameters.\n", "\n", "```\n", "# Initial population of nanobots\n", "population = 10\n", "\n", "# Growth rate (per generation)\n", "growth_rate = 1.5\n", "\n", "# Number of generations\n", "generations = 5\n", "\n", "# Your code here\n", "```\n", "\n", "`````\n" ] }, { "cell_type": "markdown", "id": "8a1e5e9b", "metadata": {}, "source": [ "`````{exercise} [***] Rock paper scissors (lizard, Spock)\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Margreet/01_Rock_paper_scissors.py>`\n", "\n", "**Exercise A**\n", "\n", "Write an interactive Python implementation of the [\"Rock paper scissors\" game](https://en.wikipedia.org/wiki/Rock_paper_scissors):\n", "- Ask the user for their choice (rock, paper, or scissors). Make sure that the user makes a valid choice.\n", "- Compare user input with the random computer choice.\n", "- Notify the participant whether they won or lost.\n", "\n", "Hint: Python's `random` package and `random.choice()` function may come in handy.\n", "\n", "```\n", "# Your code here\n", "```\n", "\n", "**Exercise B**\n", "\n", "Include \"lizard\" and \"Spock\" into the game (see the rules [here](https://www.instructables.com/How-to-Play-Rock-Paper-Scissors-Lizard-Spock/)).\n", "\n", "```\n", "# Your code here\n", "```\n", "\n", "`````" ] }, { "cell_type": "markdown", "id": "e7d6f7e0", "metadata": {}, "source": [ "`````{exercise} [***] Roman numerals\n", ":class: dropdown\n", "{download}`Download this exercise.<../Coding_exercises/Week_2/Margreet/02_Roman_numerals.py>`\n", "\n", "Write Python code which transfers decimal numerals into Roman numerals:\n", "\n", "I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000\n", "\n", "In Roman numerals, it is not allowed to have four identical characters consecutively. For example, if we want to convert 41 into Roman numerals, XXXXI is wrong, and XLI is right (think of XLI as 50-10+1).\n", "\n", "**Exercise A**\n", "\n", "Use a random user input between 1 and 4000 and automatically rewrite it into Roman numerals. \n", "In this part of the exercise, 1249 = MCCXXXXVIIII is allowed, so it is OK to have four consecutive identical characters.\n", "\n", "```\n", "# Your code here\n", "```\n", "\n", "**Exercise B**\n", "\n", "Adapt the code in order to check for four consecutive identical characters and correct the number, such that, e.g., 1209 becomes MCCIX.\n", "The largest number is 3999, corresponding to MMMCMXCIX.\n", "\n", "```\n", "# Your code here\n", "```\n", "\n", "`````" ] } ], "metadata": { "jupytext": { "formats": "ipynb,md" }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 5 }