Skip to content

Commit 2b164c5

Browse files
committed
Chapter 16
1 parent aa09947 commit 2b164c5

3 files changed

Lines changed: 225 additions & 0 deletions

File tree

Ch16/collatz_aiter.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import asyncio
2+
from aioconsole import ainput
3+
4+
BOUND = 10**5
5+
6+
7+
class Collatz:
8+
9+
def __init__(self):
10+
self.start = 2
11+
12+
async def count_steps(self, start_value):
13+
steps = 0
14+
n = start_value
15+
while n > 1:
16+
if n % 2:
17+
n = n * 3 + 1
18+
else:
19+
n = n // 2
20+
steps += 1
21+
return steps
22+
23+
def __aiter__(self):
24+
return self
25+
26+
async def __anext__(self):
27+
steps = await self.count_steps(self.start)
28+
self.start += 1
29+
if self.start == BOUND:
30+
raise StopAsyncIteration
31+
return steps
32+
33+
34+
async def length_counter(target):
35+
count = 0
36+
# iter = Collatz().__aiter__()
37+
# running = True
38+
# while running:
39+
# try:
40+
# steps = await iter.__anext__()
41+
# except StopAsyncIteration:
42+
# running = False
43+
# else:
44+
# if steps == target:
45+
# count += 1
46+
47+
async for steps in Collatz():
48+
if steps == target:
49+
count += 1
50+
return count
51+
52+
53+
async def get_input(prompt):
54+
while True:
55+
n = await ainput(prompt)
56+
try:
57+
n = int(n)
58+
except ValueError:
59+
print("Value must be an integer.")
60+
continue
61+
62+
if n <= 0:
63+
print("Value must be positive.")
64+
else:
65+
return n
66+
67+
68+
async def main():
69+
print("Collatz Sequence Counter")
70+
71+
target = await get_input("Collatz sequence length to search for: ")
72+
print(f"Searching in range 1-{BOUND}...")
73+
74+
# length_counter_task = asyncio.create_task(length_counter(target))
75+
# guess_task = asyncio.create_task(
76+
# get_input("How many times do you think it will appear? ")
77+
# )
78+
79+
# count = await length_counter_task
80+
# guess = await guess_task
81+
82+
(guess, count) = await asyncio.gather(
83+
get_input("How many times do you think it will appear? "),
84+
length_counter(target)
85+
)
86+
87+
if guess == count:
88+
print("Exactly right! I'm amazed.")
89+
elif abs(guess - count) < 100:
90+
print(f"You're close! It was {count}.")
91+
else:
92+
print(f"Nope. It was {count}.")
93+
94+
95+
if __name__ == "__main__":
96+
# loop = asyncio.get_event_loop()
97+
# loop.run_until_complete(main())
98+
asyncio.run(main())

Ch16/collatz_async.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import asyncio
2+
from aioconsole import ainput
3+
4+
BOUND = 10**5
5+
6+
7+
def collatz(n):
8+
steps = 0
9+
while n > 1:
10+
if n % 2:
11+
n = n * 3 + 1
12+
else:
13+
n = n / 2
14+
steps += 1
15+
return steps
16+
17+
18+
async def length_counter(target):
19+
count = 0
20+
for i in range(2, BOUND):
21+
if collatz(i) == target:
22+
count += 1
23+
await asyncio.sleep(0)
24+
return count
25+
26+
27+
async def get_input(prompt):
28+
while True:
29+
n = await ainput(prompt)
30+
try:
31+
n = int(n)
32+
except ValueError:
33+
print("Value must be an integer.")
34+
continue
35+
36+
if n <= 0:
37+
print("Value must be positive.")
38+
else:
39+
return n
40+
41+
42+
async def main():
43+
print("Collatz Sequence Counter")
44+
45+
target = await get_input("Collatz sequence length to search for: ")
46+
print(f"Searching in range 1-{BOUND}...")
47+
48+
# length_counter_task = asyncio.create_task(length_counter(target))
49+
# guess_task = asyncio.create_task(
50+
# get_input("How many times do you think it will appear? ")
51+
# )
52+
53+
# count = await length_counter_task
54+
# guess = await guess_task
55+
56+
(guess, count) = await asyncio.gather(
57+
get_input("How many times do you think it will appear? "),
58+
length_counter(target)
59+
)
60+
61+
if guess == count:
62+
print("Exactly right! I'm amazed.")
63+
elif abs(guess - count) < 100:
64+
print(f"You're close! It was {count}.")
65+
else:
66+
print(f"Nope. It was {count}.")
67+
68+
69+
if __name__ == "__main__":
70+
# loop = asyncio.get_event_loop()
71+
# loop.run_until_complete(main())
72+
asyncio.run(main())

Ch16/collatz_sync.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
BOUND = 10**5
2+
3+
4+
def collatz(n):
5+
steps = 0
6+
while n > 1:
7+
if n % 2:
8+
n = n * 3 + 1
9+
else:
10+
n = n / 2
11+
steps += 1
12+
return steps
13+
14+
15+
def length_counter(target):
16+
count = 0
17+
for i in range(2, BOUND):
18+
if collatz(i) == target:
19+
count += 1
20+
return count
21+
22+
23+
def get_input(prompt):
24+
while True:
25+
n = input(prompt)
26+
try:
27+
n = int(n)
28+
except ValueError:
29+
print("Value must be an integer.")
30+
continue
31+
32+
if n <= 0:
33+
print("Value must be positive.")
34+
else:
35+
return n
36+
37+
38+
def main():
39+
print("Collatz Sequence Counter")
40+
41+
target = get_input("Collatz sequence length to search for: ")
42+
print(f"Searching in range 1-{BOUND}...")
43+
count = length_counter(target)
44+
guess = get_input("How many times do you think it will appear? ")
45+
46+
if guess == count:
47+
print("Exactly right! I'm amazed.")
48+
elif abs(guess - count) < 100:
49+
print(f"You're close! It was {count}.")
50+
else:
51+
print(f"Nope. It was {count}.")
52+
53+
54+
if __name__ == "__main__":
55+
main()

0 commit comments

Comments
 (0)