Skip to content

Commit 3a1aad0

Browse files
authored
Add files via upload
Minor style edits to bunch of source files.
1 parent f3730fa commit 3a1aad0

16 files changed

+175
-151
lines changed

cardproblems.py

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
from random import choice
1+
from random import Random
22
from itertools import combinations
33

4+
# When using random numbers, hardcode the seed to make results reproducible.
5+
6+
rng = Random(12345)
7+
48
# Define the suits and ranks that a deck of playing cards is made of.
59

610
suits = ['clubs', 'diamonds', 'hearts', 'spades']
@@ -14,13 +18,13 @@ def deal_hand(n, taken=None):
1418
"""Deal a random hand with n cards, without replacement."""
1519
result, taken = [], taken if taken else []
1620
while len(result) < n:
17-
c = choice(deck)
21+
c = rng.choice(deck)
1822
if c not in result and c not in taken:
1923
result.append(c)
2024
return result
2125

2226
# If we don't care about taken, this could be one-liner:
23-
# return random.sample(deck, n)
27+
# return rng.sample(deck, n)
2428

2529

2630
def gin_count_deadwood(hand):
@@ -41,17 +45,17 @@ def blackjack_count_value(hand):
4145
for (rank, suit) in hand:
4246
v = ranks[rank]
4347
if v == 14: # Treat every ace as 11 to begin with
44-
total, soft = total + 11, soft + 1
48+
total, soft = total+11, soft+1
4549
else:
4650
total += min(10, v) # All face cards are treated as tens
4751
if total > 21:
48-
if soft > 0: # Saved by the soft ace
49-
soft, total = soft - 1, total - 10
52+
if soft: # Saved by the soft ace
53+
soft, total = soft-1, total-10
5054
else:
5155
return 'bust'
5256
if total == 21 and len(hand) == 2:
5357
return 'blackjack'
54-
return f"{'soft' if soft > 0 else 'hard'} {total}"
58+
return f"{'soft' if soft else 'hard'} {total}"
5559

5660

5761
def poker_has_flush(hand):
@@ -116,10 +120,10 @@ def poker_has_straight(hand):
116120
return True # AKQJT
117121
return all(rank in hand_ranks for rank in [2, 3, 4, 5]) # A2345
118122
else:
119-
return max_rank - min_rank == 4
123+
return max_rank-min_rank == 4
120124

121125

122-
# Straight flushes complicate the hand rankings a little bit.
126+
# Straight flushes complicate the hand rankings a bit.
123127

124128

125129
def poker_flush(hand):
@@ -167,7 +171,7 @@ def bridge_score(suit, level, vul, dbl, made):
167171
score, bonus = 0, 0
168172

169173
# Add up the values of individual tricks.
170-
for trick in range(1, made + 1):
174+
for trick in range(1, made+1):
171175
# Raw points for this trick.
172176
if suit == 'clubs' or suit == 'diamonds':
173177
pts = 20

comprehensions.py

+8-10
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858

5959
# Squares of the first googol integers.
6060

61-
h = (x * x for x in range(10 ** 100))
61+
h = (x*x for x in range(10 ** 100))
6262

6363
# Notice how we didn't run out of memory. Many functions that operate
6464
# on iterators are smart enough to stop once they know the answer, so
@@ -85,10 +85,10 @@
8585
print(list(five)) # ['hello']
8686

8787
# The Python functions all and any can be used to check if any or
88-
# all elements of a sequence, produced either with comprehension
89-
# or not, have some desired property. (Note that for empty sequence,
90-
# all is trivially true, and any is trivially false, regardless of
91-
# the condition used.)
88+
# all elements of a sequence, produced either with a comprehension
89+
# or something else, have some desired property. (Note that for empty
90+
# sequence, all is trivially true, and any is trivially false,
91+
# regardless of the condition used.)
9292

9393
print(f"Is the number 29 a prime number? {not any(g1)}")
9494
print(f"Is the number 45 a prime number? {not any (g2)}")
@@ -100,20 +100,18 @@
100100
# An inner comprehension can be nested inside the evaluation of an outer
101101
# comprehension, to produce a sequence whose elements are sequences.
102102

103-
u1 = [[x for x in range(n + 1)] for n in range(10)]
103+
u1 = [[x for x in range(n+1)] for n in range(10)]
104104
print(u1)
105105

106106
# This technique allows us to partition a sequence into another sequence
107107
# of its consecutive elements, either overlapping or not.
108108

109109
# Overlapping sequences of 3 consecutive elements by having the range
110110
# of n skip by default 1.
111-
u2 = [" ".join([words[x] for x in range(n, n + 3)])
112-
for n in range(len(words) - 2)]
111+
u2 = [" ".join([words[x] for x in range(n, n+3)]) for n in range(len(words)-2)]
113112
print(u2)
114113

115114
# Non-overlapping sequences of 3 consecutive elements by having the
116115
# range of n skip by 3.
117-
u3 = [" ".join([words[x] for x in range(n, n + 3)])
118-
for n in range(0, len(words) - 2, 3)]
116+
u3 = [" ".join([words[x] for x in range(n, n+3)]) for n in range(0, len(words)-2, 3)]
119117
print(u3)

conditions.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,17 @@ def is_leap_year_with_logic(y):
7272
return y % 4 == 0 and (y % 100 != 0 or y % 400 == 0)
7373

7474

75+
# Sneak preview of for-loops to iterate through the elements of the given
76+
# sequence. Verify that all three functions for leap year testing give the
77+
# same answer to all years ranging between those mentioned in the famous
78+
# song "In the year 2525" by Zager & Evans.
79+
7580
def test_leap_year():
7681
for y in range(2525, 9596):
7782
a1 = is_leap_year(y)
7883
a2 = is_leap_year_another_way(y)
7984
a3 = is_leap_year_with_logic(y)
80-
# Chaining comparison operators works also for equality.
85+
# Chaining comparison operators works for equality just as well.
8186
if not (a1 == a2 == a3): # a1 != a2 or a2 != a3:
82-
return False # Tear it down and start again.
83-
return True # I am pleased where man has been.
87+
return False # "Tear it down and start again."
88+
return True # "I am pleased where man has been."

countries.py

+2-6
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
total_pop += pop
1515

1616
print('\nThe total population in each continent:')
17-
for continent in sorted(continental_pops,
18-
key=lambda c: continental_pops[c],
19-
reverse=True):
17+
for continent in sorted(continental_pops, key=lambda c: continental_pops[c], reverse=True):
2018
print(f"{continent} has a total of {continental_pops[continent]} people.")
2119
print(f'That gives a total of {total_pop} people on Earth.')
2220

@@ -26,9 +24,7 @@
2624
hazard_table[hazard] = hazard_table.get(hazard, 0) + 1
2725

2826
print('\nHere are the natural hazards found around the world.')
29-
for hazard in sorted(hazard_table,
30-
key=lambda h: (hazard_table[h], h),
31-
reverse=True):
27+
for hazard in sorted(hazard_table, key=lambda h: (hazard_table[h], h), reverse=True):
3228
title = hazard[0].upper() + hazard[1:]
3329
haz_count = hazard_table[hazard]
3430
print(f"{title} is a hazard in {haz_count} countries.")

defdemo.py

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from itertools import accumulate
22
from math import log
3-
import random
3+
from random import Random
44

55
# When we are building complex programs, or just a library of
66
# useful code for other programmers to use as part of their
@@ -9,6 +9,11 @@
99
# expects, followed by a code block telling what you do with
1010
# those parameters.
1111

12+
# When using random numbers, hardcode the seed to make results reproducible.
13+
14+
rng = Random(12345)
15+
16+
1217
# Factorial of n is the product of positive integers up to n.
1318

1419

@@ -17,7 +22,7 @@ def factorial(n):
1722
n -- The positive integer whose factorial is computed.
1823
"""
1924
total = 1
20-
for i in range(2, n + 1):
25+
for i in range(2, n+1):
2126
total *= i
2227
return total
2328

@@ -28,9 +33,9 @@ def factorial(n):
2833
# had been extended to have the factorial function:
2934

3035

31-
print(factorial(5))
32-
print(factorial(10))
33-
print(factorial(100))
36+
print(f"Factorial of 5 equals {factorial(5)}")
37+
print(f"Factorial of 20 equals {factorial(20)}")
38+
print(f"Factorial of 100 equals {factorial(100)}")
3439

3540
# docstring is automatically placed in object under name __doc__
3641
print(factorial.__doc__)
@@ -43,12 +48,11 @@ def factorial(n):
4348
# assigned to point some place else.
4449

4550
f = factorial # copy a reference to the function object
46-
factorial_30 = f(30) # make an actual function call
47-
print(factorial_30) # 265252859812191058636308480000000
51+
print(f"Factorial of 30 equals {f(30)}")
4852

4953
# All right, that out of the way, let's write some more functions that
5054
# operate on lists. First, find the largest element in the list. We do
51-
# this by iterating over the elements of the list
55+
# this first by explicitly iterating over the elements of the list.
5256

5357

5458
def maximum(seq):
@@ -115,7 +119,7 @@ def select_upsteps(seq):
115119
def leading_digit_list(n):
116120
prod = 1 # The current factorial
117121
digits = [0] * 10 # Create a list full of zeros
118-
for i in range(1, n + 1):
122+
for i in range(1, n+1):
119123
lead = int(str(prod)[0]) # Extract highest order digit
120124
digits[lead] += 1
121125
prod = prod * i # Next factorial, from the current one
@@ -188,7 +192,7 @@ def roll_dice(rolls, faces=6):
188192
"""
189193
total = 0
190194
for x in range(rolls):
191-
total += random.randint(1, faces)
195+
total += rng.randint(1, faces)
192196
return total
193197

194198

dissociated.py

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import random
1+
from random import Random
22
from itertools import islice
33

44

55
# Read through the text and build a dictionary that, for each found
66
# pattern up to length n, gives the string of letters that follow that
77
# pattern in the original text.
88

9-
def build_table(text, n=3, mlen=100):
9+
def build_table(text, n=3, max_len=100):
1010
result = {}
1111
for i in range(len(text) - n - 1):
1212
# The n-character string starting at position i.
@@ -16,23 +16,25 @@ def build_table(text, n=3, mlen=100):
1616
# Update the dictionary for each suffix of the current pattern.
1717
for j in range(n):
1818
follow = result.get(pattern[j:], "")
19-
# Store only the first mlen occurrences of each pattern.
20-
if len(follow) < mlen:
19+
# Store only the first max_len occurrences of each pattern.
20+
if len(follow) < max_len:
2121
result[pattern[j:]] = follow + next_char
2222
return result
2323

2424

2525
# Aided by such table, generate random text one character at the time.
2626

27-
def dissociated_press(table, start, maxpat=3):
27+
def dissociated_press(table, start, maxpat=3, rng=None):
28+
if not rng:
29+
rng = Random(12345)
2830
yield from start
2931
pattern = start[-maxpat:]
3032
while pattern not in table:
3133
pattern = pattern[1:]
3234
while True:
3335
follow = table[pattern]
3436
# Choose a random continuation for pattern and result.
35-
c = random.choice(follow)
37+
c = rng.choice(follow)
3638
yield c
3739
# Update the pattern also, shortening if necessary.
3840
pattern += c

generators.py

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import random
1+
from random import Random
22
from fractions import Fraction
33

44
# For the Aronson sequence below
@@ -8,8 +8,7 @@
88
# The itertools module defines tons of handy functions to perform
99
# computations on existing iterators, to be combined arbitrarily.
1010

11-
from itertools import takewhile, islice, permutations,\
12-
combinations, combinations_with_replacement
11+
from itertools import takewhile, islice, permutations, combinations, combinations_with_replacement
1312

1413
# The "double-ended queue" or "deque" allows efficient push
1514
# and pop operations from both ends of the queue, whereas a
@@ -73,7 +72,7 @@ def collatz(start):
7372
start = 3 * start + 1
7473

7574

76-
# A generator that produces random integers with an ever increasing
75+
# A generator that produces random integers with an ever-increasing
7776
# scale. Handy for generating random test cases in tester.py that
7877
# produce test cases from all scales so that the first test cases
7978
# are guaranteed to be small. The scale determines how wide range
@@ -85,7 +84,7 @@ def collatz(start):
8584

8685
def scale_random(seed, scale, skip):
8786
# The seed value determines the future random sequence.
88-
rng = random.Random(seed)
87+
rng = Random(seed)
8988
curr, count, orig = 1, 0, scale
9089
while True:
9190
curr += rng.randint(1, scale)
@@ -130,18 +129,18 @@ def theons_ladder(n=2, a=1, b=1):
130129
# Let the Fraction class simplify these numbers.
131130
a, b = f.numerator, f.denominator
132131
# Original Theon's ladder was just n = 2.
133-
a, b = a + n * b, a + b
132+
a, b = a + n * b, a+b
134133

135134

136135
# The next technique comes handy sometimes. Iterate through all integer
137136
# pairs of the form (a, b) where a and b are nonnegative integers so
138137
# that every such pair is visited exactly once.
139138

140139
def all_pairs():
141-
s = 0 # In each antidiagonal of the infinite 2D grid, a + b == s.
140+
s = 0 # In each anti-diagonal of the infinite 2D grid, a+b == s.
142141
while True:
143142
for a in range(0, s + 1):
144-
yield a, s - a
143+
yield a, s-a
145144
s += 1
146145

147146
# That one is handy when you need to loop through the infinite
@@ -166,7 +165,7 @@ def kolakoski(n=2):
166165
while True:
167166
v = q.popleft()
168167
yield v
169-
prev = prev + 1 if prev < n else 1
168+
prev = prev+1 if prev < n else 1
170169
for i in range(v):
171170
q.append(prev)
172171

@@ -177,7 +176,7 @@ def aronson(letter='t'):
177176
n, tees, curr = 1, [], f'Letter {letter} is in positions '
178177
while True:
179178
yield from curr
180-
tees.extend([i + n for (i, c) in enumerate(curr) if c == letter])
179+
tees.extend([i+n for (i, c) in enumerate(curr) if c == letter])
181180
n += len(curr)
182181
curr, tees = int_to_english(tees[0]) + ', ', tees[1:]
183182

@@ -213,7 +212,7 @@ def __demo():
213212
print("Collatz sequence starting from 12345 is:")
214213
print(list(every_kth(stutter(collatz(12345), 3), 3)))
215214

216-
# Take primes until they become greater than thousand.
215+
# Take primes until they become greater than one thousand.
217216
print("Here is every seventh prime number up to one thousand:")
218217
print(list(takewhile((lambda x: x <= 1000), every_kth(primes(), 7))))
219218

listproblems.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from math import sqrt
21
from fractions import Fraction
32
import heapq
43

@@ -43,8 +42,8 @@ def partition_in_place(s, pred):
4342
# Elements from position i to j, inclusive, can be anything.
4443
# Anything to left of i is acceptable, anything to the right
4544
# of j is unacceptable. When i == j, all is well.
46-
i, j = 0, len(s) - 1
47-
# Each round, one of the indices takes a step towards other.
45+
i, j = 0, len(s)-1
46+
# Each round, one of the indices takes a step towards the other.
4847
while i < j:
4948
# If s[i1] satisfies the predicate, leave it be...
5049
if pred(s[i]):

0 commit comments

Comments
 (0)