|
| 1 | +# Telephone |
| 2 | + |
| 3 | +Perhaps you remember the game of "Telephone" where a message is secretly passed through a series of intermediaries and then the result at the end of the chain is compared with how it started? This is like that, only we're going to take some`text` (from the command line or a file) and mutate it by some percentage `-m|--mutations` (a number between 0 and 1, default `0.1` or 10%) and then print out the resulting text. |
| 4 | + |
| 5 | +Each mutation to the text should be chosen using the `random` module, so your program will also need to accept a `-s|--seed` option to pass to the `random.seed` function for testing purposes. Print the resulting text after making the appropriate number of mutations. |
| 6 | + |
| 7 | +```` |
| 8 | +$ ./telephone.py |
| 9 | +usage: telephone.py [-h] [-s str] [-m float] str |
| 10 | +telephone.py: error: the following arguments are required: str |
| 11 | +$ ./telephone.py -h |
| 12 | +usage: telephone.py [-h] [-s str] [-m float] str |
| 13 | +
|
| 14 | +Telephone |
| 15 | +
|
| 16 | +positional arguments: |
| 17 | + str Input text or file |
| 18 | +
|
| 19 | +optional arguments: |
| 20 | + -h, --help show this help message and exit |
| 21 | + -s str, --seed str Random seed (default: None) |
| 22 | + -m float, --mutations float |
| 23 | + Percent mutations (default: 0.1) |
| 24 | +```` |
| 25 | + |
| 26 | +The program should not accept a bad `--mutations` argument: |
| 27 | + |
| 28 | +```` |
| 29 | +$ ./telephone.py -m 10 foo |
| 30 | +usage: telephone.py [-h] [-s str] [-m float] str |
| 31 | +telephone.py: error: --mutations "10.0" must be b/w 0 and 1 |
| 32 | +```` |
| 33 | + |
| 34 | +It can be interesting to watch the accumulation of mutations: |
| 35 | + |
| 36 | +```` |
| 37 | +$ ./telephone.py -s 1 ../inputs/fox.txt |
| 38 | +Tho quick brown foa jumps oWer*the lazy dog. |
| 39 | +$ ./telephone.py -s 1 -m .5 ../inputs/fox.txt |
| 40 | +Thakqkrck&brow- fo[ jumps#oWe,*L/C lxdy dogos |
| 41 | +```` |
| 42 | + |
| 43 | +## Mutations in DNA |
| 44 | + |
| 45 | +For what it's worth, this is how DNA changes over time. The machinery to copy DNA makes mistakes, and mutations randomly occur. Many times the change is in a part of the DNA that doesn't affect the organism or is a "synonymous" change that doesn't end up affecting the function of the DNA. Our example will only change characters to other characters, what are called "point mutations" or "single nucleotide variations" (SNV) or "single nucleotide polymorphisms" (SNP) in biology. We could write a version that would also randomly delete or insert new characters which are called them "in-dels" (insertion-deletions) in biology. |
| 46 | + |
| 47 | +Mutations (that don't result in the demise of the organism) occur at a fairly standard rate, so counting the number of point mutations (AKA ) between a conserved region of any two organisms, we can estimate how long ago they diverged from a common ancestor! |
| 48 | + |
| 49 | +We can revisit the output of this program later by using the Hamming distance to find how many changes we'd need to make to the output to regain the input. |
| 50 | + |
| 51 | +## Hints |
| 52 | + |
| 53 | +To create a combined error/usage statement for the `--mutations` error, look at `parser.error` in `argparse`. |
| 54 | + |
| 55 | +To select a character position to change, I suggest using `random.choice` and a `range` from length of the incoming text. With that, you'll need to alter the character at that position, but you'll find that strings in Python are *immutable*. For instance, if I wanted to change "candle" into "handle": |
| 56 | + |
| 57 | +```` |
| 58 | +>>> s = 'candle' |
| 59 | +>>> s[0] = 'h' |
| 60 | +Traceback (most recent call last): |
| 61 | + File "<stdin>", line 1, in <module> |
| 62 | +TypeError: 'str' object does not support item assignment |
| 63 | +```` |
| 64 | + |
| 65 | +So, I need to create a *new string* that has `h` joined to the rest of the string `s` after the zeroth position. How could you do that? |
| 66 | + |
| 67 | +For the replacement value, you should use `random.choice` from the union of the `string` class's `ascii_letters` and `punctuation`: |
| 68 | + |
| 69 | +```` |
| 70 | +>>> import string |
| 71 | +>>> string.ascii_letters |
| 72 | +'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' |
| 73 | +>>> string.punctuation |
| 74 | +'!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~' |
| 75 | +```` |
0 commit comments