Skip to content

Commit 2a409a1

Browse files
committed
extras
1 parent 4e997d5 commit 2a409a1

File tree

10 files changed

+354
-0
lines changed

10 files changed

+354
-0
lines changed

extra/03_dna/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.PHONY: test pdf
2+
3+
pdf:
4+
asciidoctor-pdf -o README.pdf README.adoc
5+
6+
test:
7+
pytest -xv test.py

extra/03_dna/README.adoc

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
= Counting DNA Nucleotides
2+
3+
In this exercise, we'll count the frequency of the four nucleotide bases in a given string of DNA as described on the http://rosalind.info/problems/dna/[Rosalind.info site]footnote:[This is a website with various bioinformatics coding challenges. It's named after Rosalind Franklin who should have gotten a Nobel Prize for her work on discovering the double-helix structure of DNA. Instead, she died early with little recognition of her contributions, but she did get this website named after her.]
4+
Write a Python program called `dna.py` that will accept a single, required, positional argument that is a string of `dna` and print the number of times you see each of the bases A, C, G, and T (in that order) separated by spaces.
5+
6+
The program should print a brief usage when run with no input:
7+
8+
----
9+
$ ./dna.py
10+
usage: dna.py [-h] str
11+
dna.py: error: the following arguments are required: str
12+
----
13+
14+
Or a longer usage for the `-h` or `--help` flags:
15+
16+
----
17+
$ ./dna.py -h
18+
usage: dna.py [-h] str
19+
20+
Count DNA nucleotides
21+
22+
positional arguments:
23+
str DNA
24+
25+
optional arguments:
26+
-h, --help show this help message and exit
27+
----
28+
29+
Examples of running:
30+
31+
----
32+
$ ./dna.py A
33+
1 0 0 0
34+
$ ./dna.py C
35+
0 1 0 0
36+
$ ./dna.py G
37+
0 0 1 0
38+
$ ./dna.py T
39+
0 0 0 1
40+
$ ./dna.py AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATTAAAAAAAGAGTGTCTGATAGCAGC
41+
20 12 17 21
42+
----
43+
44+
A passing test suite looks like this:
45+
46+
----
47+
$ make test
48+
pytest -xv test.py
49+
============================= test session starts ==============================
50+
...
51+
collected 11 items
52+
53+
test.py::test_exists PASSED [ 9%]
54+
test.py::test_no_arg_and_usage PASSED [ 18%]
55+
test.py::test_a_upper PASSED [ 27%]
56+
test.py::test_a_lower PASSED [ 36%]
57+
test.py::test_c_upper PASSED [ 45%]
58+
test.py::test_c_lower PASSED [ 54%]
59+
test.py::test_g_upper PASSED [ 63%]
60+
test.py::test_g_lower PASSED [ 72%]
61+
test.py::test_t_upper PASSED [ 81%]
62+
test.py::test_t_lower PASSED [ 90%]
63+
test.py::test_rosalind_example PASSED [100%]
64+
65+
============================== 11 passed in 0.61s ==============================
66+
----
67+
68+
NOTE: Solve this problem using only the skills you've learned up to chapter 3 -- that is, only using Python `str` methods.

extra/03_dna/README.pdf

51.9 KB
Binary file not shown.

extra/03_dna/test.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#!/usr/bin/env python3
2+
"""tests for dna.py"""
3+
4+
import os
5+
import random
6+
import re
7+
import string
8+
from subprocess import getstatusoutput, getoutput
9+
10+
prg = './dna.py'
11+
12+
13+
# --------------------------------------------------
14+
def test_exists():
15+
"""exists"""
16+
17+
assert os.path.isfile(prg)
18+
19+
20+
# --------------------------------------------------
21+
def test_no_arg_and_usage():
22+
"""usage"""
23+
24+
for flag in ['', '-h', '--help']:
25+
out = getoutput(f'{prg} {flag}')
26+
assert out.lower().startswith('usage')
27+
28+
29+
# --------------------------------------------------
30+
def run_single(base):
31+
"""Run a single base test"""
32+
33+
num = random.randint(1, 10)
34+
given = base * num
35+
rv, out = getstatusoutput(f'{prg} {given}')
36+
assert rv == 0
37+
cmp = base.upper()
38+
expected = f'{num} 0 0 0' if cmp == 'A' else \
39+
f'0 {num} 0 0' if cmp == 'C' else \
40+
f'0 0 {num} 0' if cmp == 'G' else \
41+
f'0 0 0 {num}'
42+
assert out == expected
43+
44+
45+
# --------------------------------------------------
46+
def test_a_upper():
47+
"""A"""
48+
49+
run_single('A')
50+
51+
52+
# --------------------------------------------------
53+
def test_a_lower():
54+
"""a"""
55+
56+
run_single('a')
57+
58+
59+
# --------------------------------------------------
60+
def test_c_upper():
61+
"""C"""
62+
63+
run_single('C')
64+
65+
66+
# --------------------------------------------------
67+
def test_c_lower():
68+
"""c"""
69+
70+
run_single('c')
71+
72+
73+
# --------------------------------------------------
74+
def test_g_upper():
75+
"""G"""
76+
77+
run_single('G')
78+
79+
80+
# --------------------------------------------------
81+
def test_g_lower():
82+
"""g"""
83+
84+
run_single('g')
85+
86+
87+
# --------------------------------------------------
88+
def test_t_upper():
89+
"""T"""
90+
91+
run_single('T')
92+
93+
94+
# --------------------------------------------------
95+
def test_t_lower():
96+
"""t"""
97+
98+
run_single('t')
99+
100+
# --------------------------------------------------
101+
def test_rosalind_example():
102+
"""From http://rosalind.info/problems/dna/"""
103+
104+
dna = ('AGCTTTTCATTCTGACTGCAACGGGCAATATGTCTCTGTGTGGATT'
105+
'AAAAAAAGAGTGTCTGATAGCAGC')
106+
107+
rv, out = getstatusoutput(f'{prg} {dna}')
108+
assert rv == 0
109+
assert out == '20 12 17 21'

extra/03_strings/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.PHONY: test pdf
2+
3+
pdf:
4+
asciidoctor-pdf -o README.pdf README.adoc
5+
6+
test:
7+
pytest -xv test.py

extra/03_strings/README.adoc

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
= Text Classifier
2+
3+
Write a Python program called `classify.py` that will report if a given input is:
4+
5+
* uppercase, e.g., "HELLO"
6+
* lowercase, e.g., "hello"
7+
* title case, e.g., "Hello"
8+
* a digit, e.g., "10"
9+
* a space, e.g., " " or the tab character "\t"
10+
* none of the above, e.g., "1.2"
11+
12+
The program should work like so:
13+
14+
----
15+
$ ./classify.py HELLO
16+
HELLO is uppercase.
17+
$ ./classify.py hello
18+
hello is lowercase.
19+
$ ./classify.py Hello
20+
Hello is title case.
21+
$ ./classify.py 10
22+
10 is a digit.
23+
$ ./classify.py " "
24+
input is space.
25+
$ ./classify.py "1.2"
26+
1.2 is unclassified.
27+
----
28+
29+
It should print a brief usage if provided with no arguments:
30+
31+
----
32+
$ ./classify.py
33+
usage: classify.py [-h] str
34+
classify.py: error: the following arguments are required: str
35+
----
36+
37+
And a longer usage for the `-h` or `--help` flags:
38+
39+
----
40+
$ ./classify.py -h
41+
usage: classify.py [-h] str
42+
43+
Classify a given string
44+
45+
positional arguments:
46+
str Some text
47+
48+
optional arguments:
49+
-h, --help show this help message and exit
50+
----
51+
52+
It should pass all the tests:
53+
54+
----
55+
$ make test
56+
pytest -xv test.py
57+
============================= test session starts ==============================
58+
...
59+
collected 8 items
60+
61+
test.py::test_exists PASSED [ 12%]
62+
test.py::test_usage PASSED [ 25%]
63+
test.py::test_upper PASSED [ 37%]
64+
test.py::test_lower PASSED [ 50%]
65+
test.py::test_title PASSED [ 62%]
66+
test.py::test_digit PASSED [ 75%]
67+
test.py::test_space PASSED [ 87%]
68+
test.py::test_unclassified PASSED [100%]
69+
70+
============================== 8 passed in 0.44s ===============================
71+
----

extra/03_strings/README.pdf

40.8 KB
Binary file not shown.

extra/03_strings/test.py

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#!/usr/bin/env python3
2+
"""tests for classify.py"""
3+
4+
import os
5+
import random
6+
import re
7+
import string
8+
from subprocess import getstatusoutput
9+
10+
prg = './classify.py'
11+
12+
13+
# --------------------------------------------------
14+
def test_exists():
15+
"""exists"""
16+
17+
assert os.path.isfile(prg)
18+
19+
20+
# --------------------------------------------------
21+
def test_usage():
22+
"""usage"""
23+
24+
for flag in ['-h', '--help']:
25+
rv, out = getstatusoutput(f'{prg} {flag}')
26+
assert rv == 0
27+
assert out.lower().startswith('usage')
28+
29+
30+
# --------------------------------------------------
31+
def test_upper():
32+
"""upper"""
33+
34+
word = random.choice('APPLE BANANA CHERRY'.split())
35+
rv, out = getstatusoutput(f'{prg} {word}')
36+
assert rv == 0
37+
assert out == f'{word} is uppercase.'
38+
39+
40+
# --------------------------------------------------
41+
def test_lower():
42+
"""lower"""
43+
44+
word = random.choice('apple banana cherry'.split())
45+
rv, out = getstatusoutput(f'{prg} {word}')
46+
assert rv == 0
47+
assert out == f'{word} is lowercase.'
48+
49+
50+
# --------------------------------------------------
51+
def test_title():
52+
"""title"""
53+
54+
word = random.choice('Apple Banana Cherry'.split())
55+
rv, out = getstatusoutput(f'{prg} {word}')
56+
assert rv == 0
57+
assert out == f'{word} is title case.'
58+
59+
60+
# --------------------------------------------------
61+
def test_digit():
62+
"""digit"""
63+
64+
word = random.choice('1 2 3'.split())
65+
rv, out = getstatusoutput(f'{prg} {word}')
66+
assert rv == 0
67+
assert out == f'{word} is a digit.'
68+
69+
70+
# --------------------------------------------------
71+
def test_space():
72+
"""space"""
73+
74+
word = random.choice([' ', '\t'])
75+
rv, out = getstatusoutput(f'{prg} "{word}"')
76+
assert rv == 0
77+
assert out == f'input is space.'
78+
79+
80+
# --------------------------------------------------
81+
def test_unclassified():
82+
"""unclassified"""
83+
84+
word = random.choice('1.2 3.04 40.5'.split())
85+
rv, out = getstatusoutput(f'{prg} "{word}"')
86+
assert rv == 0
87+
assert out == f'{word} is unclassified.'

extra/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
clean:
2+
find . -name __pycache__ -o -name .pytest_cache -o -name .mypy_cache -exec rm -rf {} \;

extra/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Extras
2+
3+
These are additional coding challenges for which I will not provide solutions, only tests. Good luck!

0 commit comments

Comments
 (0)