Skip to content

Commit d555f8f

Browse files
committed
first commit
0 parents  commit d555f8f

7 files changed

Lines changed: 249 additions & 0 deletions

File tree

.github/workflows/python-tests.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Python Unit Tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v3
16+
17+
- name: Set up Python
18+
uses: actions/setup-python@v4
19+
with:
20+
python-version: '3.11'
21+
22+
- name: Install dependencies
23+
run: |
24+
python3 -m pip install --upgrade pip
25+
26+
- name: Run unit tests
27+
run: |
28+
echo "⚙️ Running Tests..."
29+
python3 -m unittest discover -s tests -p '*_test.py' -v
30+
31+
- name: Check result
32+
if: ${{ failure() }}
33+
run: echo "❌ Some tests failed. Please review the output above."
34+
35+
- name: Check result on success
36+
if: ${{ success() }}
37+
run: echo "✅ All tests passed successfully!"

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
__pycache__/
2+
.venv/

README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Btrust Builders: Python Language Club Week Two Exercises
2+
3+
## Instructions
4+
5+
Welcome! This exercise is designed to help you practice key Python programming skills specifically for Bitcoin development.
6+
Your task is to complete the `TODO` items found in the `main.py` source file.
7+
8+
1. Fork this repository.
9+
2. Go to the `Actions` tab and enable github workflow for your repository by clicking `I understand my ...`
10+
11+
<img src="https://github.com/btrust-builders/python-week-2-exercises/blob/main/enable-github-actions.png" width="700" />
12+
13+
3. Clone your fork to your local computer.
14+
4. **Explore the Code**
15+
- Open the `main.py` file and examine the source code.
16+
- Look for code marked with `TODO`.
17+
5. **Complete the TODOs**
18+
- Implement the missing logic where indicated.
19+
- Ensure your code is readable, idiomatic, and compiles without warnings.
20+
6. **Test Your Code**
21+
- Run the tests using:
22+
```bash
23+
python3 -m unittest discover -s tests -p 'main_test.py' -v
24+
```
25+
7. Commit and push your changes to the `main` branch of your remote fork.
26+
27+
8. Confirm your forked repository has a green check mark.
28+
29+
<img src="https://github.com/btrust-builders/python-week-2-exercises/blob/main/success.png" width="300" />
30+
31+
9. Submit your solution to this form: [Google form](https://forms.gle/5b3ETjSwdhKjePHU9).
32+
33+
PS: You can commit and push as often as you like and GitHub Actions will re-evaluate your code every time.
34+
You will need to look through the auto-grader logs (in the "Actions" tab) to see what exactly you got right or wrong.

enable-github-actions.png

47.8 KB
Loading

main.py

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
def get_tx_count(tx_list):
2+
"""
3+
TODO: Return the number of transactions in the list.
4+
Input: List of transaction IDs (strings)
5+
Output: Integer count
6+
"""
7+
8+
def filter_large_txids(tx_list, min_length):
9+
"""
10+
TODO: Return a list of txids with length greater than or equal to min_length.
11+
Input: List of txids (strings), minimum length (int)
12+
Output: Filtered list of strings
13+
"""
14+
15+
def process_txids(tx_list):
16+
"""
17+
TODO: Iterate over txids and return list of tuples (index, txid)
18+
only for txids that start with 'tx'. Use enumerate, continue as needed.
19+
Input: List of txids (strings)
20+
Output: List of (int, string) tuples
21+
"""
22+
23+
def example_while_loop(limit):
24+
"""
25+
TODO: Using a while loop, build a list of integers from 0 up to limit.
26+
Break the loop if integer reaches 5.
27+
Input: Integer limit
28+
Output: List of integers
29+
"""
30+
31+
def unpack_tuple(block_header):
32+
"""
33+
TODO: Unpack the tuple representing a Bitcoin block header (height, previous hash, timestamp).
34+
Input: Tuple (int, str, int)
35+
Output: Unpacked tuple values
36+
"""
37+
38+
def dict_methods_example(block):
39+
"""
40+
TODO: Given a dict representing a Bitcoin block with keys 'height', 'hash', and 'tx_count',
41+
return three lists: keys, values, and items.
42+
Input: Dict
43+
Output: Tuple of (list, list, list)
44+
"""
45+
46+
def multiple_assignment(a, b):
47+
"""
48+
TODO: Demonstrate multiple assignments and swapping two variables.
49+
Input: two integers
50+
Output: Tuple of two ints (swapped)
51+
"""
52+
53+
def set_example(addresses):
54+
"""
55+
TODO: Given a list of Bitcoin addresses with duplicates,
56+
return a set of unique addresses.
57+
Input: List of strings
58+
Output: Set of strings
59+
"""
60+
61+
62+
class BitcoinTransaction:
63+
def __init__(self, txid, amount):
64+
"""
65+
TODO: Initialize transaction with txid (string) and amount (float).
66+
"""
67+
68+
def __str__(self):
69+
"""
70+
TODO: Return string representation: "Tx {txid} of {amount} BTC"
71+
"""
72+
73+
class Wallet:
74+
def __init__(self):
75+
"""
76+
TODO: Initialize an empty list to hold transactions.
77+
"""
78+
79+
def add_tx(self, tx):
80+
"""
81+
TODO: Add a BitcoinTransaction to the wallet's transaction list.
82+
"""
83+
84+
def total_balance(self):
85+
"""
86+
TODO: Calculate and return the sum of amounts of all transactions.
87+
Output: Float
88+
"""
89+
90+
91+
def txid_generator(tx_list):
92+
"""
93+
TODO: Yield each txid from the list one by one.
94+
Input: List of strings
95+
"""
96+
97+
def filter_txids_gen(tx_list, prefix="tx"):
98+
"""
99+
TODO: Yield txids from list that start with given prefix.
100+
Default prefix is 'tx'.
101+
Input: List of strings, prefix string
102+
"""

success.png

5.85 KB
Loading

tests/main_test.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import unittest
2+
from main import *
3+
4+
class TestBitcoinFunctions(unittest.TestCase):
5+
def test_get_tx_count(self):
6+
self.assertEqual(get_tx_count(["tx1", "tx2"]), 2)
7+
self.assertEqual(get_tx_count([]), 0)
8+
9+
def test_filter_large_txids(self):
10+
txs = ["tx1", "transaction2", "tx3"]
11+
filtered = filter_large_txids(txs, 4)
12+
self.assertEqual(filtered, ["transaction2"])
13+
14+
def test_process_txids(self):
15+
txs = ["tx1", "abc", "tx3"]
16+
result = process_txids(txs)
17+
self.assertEqual(result, [(0, "tx1"), (2, "tx3")])
18+
19+
def test_example_while_loop(self):
20+
self.assertEqual(example_while_loop(3), [0, 1, 2])
21+
self.assertEqual(example_while_loop(10), [0, 1, 2, 3, 4])
22+
23+
def test_unpack_tuple(self):
24+
header = (123456, "0000000000000000000a7b7e", 1623456789)
25+
height, prev_hash, timestamp = unpack_tuple(header)
26+
self.assertEqual(height, 123456)
27+
self.assertTrue(prev_hash.startswith("0000"))
28+
self.assertIsInstance(timestamp, int)
29+
30+
def test_dict_methods_example(self):
31+
block = {
32+
"height": 123456,
33+
"hash": "0000000000000000000a7b7e",
34+
"tx_count": 2500,
35+
}
36+
keys, values, items = dict_methods_example(block)
37+
self.assertIn("height", keys)
38+
self.assertIn(123456, values)
39+
self.assertIn(("tx_count", 2500), items)
40+
41+
def test_multiple_assignment(self):
42+
a, b = multiple_assignment(1, 2)
43+
self.assertEqual((a, b), (2, 1))
44+
45+
def test_set_example(self):
46+
addresses = ["addr1", "addr2", "addr1", "addr3"]
47+
s = set_example(addresses)
48+
self.assertIsInstance(s, set)
49+
self.assertEqual(len(s), 3)
50+
51+
def test_bitcoin_transaction_and_wallet(self):
52+
tx1 = BitcoinTransaction("tx123", 0.5)
53+
tx2 = BitcoinTransaction("tx456", 1.0)
54+
wallet = Wallet()
55+
wallet.add_tx(tx1)
56+
wallet.add_tx(tx2)
57+
self.assertEqual(str(tx1), "Tx tx123 of 0.5 BTC")
58+
self.assertAlmostEqual(wallet.total_balance(), 1.5)
59+
60+
def test_txid_generator(self):
61+
txs = ["tx1", "tx2"]
62+
gen = txid_generator(txs)
63+
self.assertEqual(next(gen), "tx1")
64+
self.assertEqual(next(gen), "tx2")
65+
with self.assertRaises(StopIteration):
66+
next(gen)
67+
68+
def test_filter_txids_gen(self):
69+
txs = ["tx1", "abc", "tx3"]
70+
gen = filter_txids_gen(txs)
71+
self.assertEqual(list(gen), ["tx1", "tx3"])
72+
73+
if __name__ == "__main__":
74+
unittest.main()

0 commit comments

Comments
 (0)