Python: Type annotations

This commit is contained in:
Martin Thoma
2022-04-02 10:06:15 +02:00
parent c8f86531e9
commit ac184fec42
25 changed files with 241 additions and 245 deletions

View File

@@ -50,7 +50,7 @@ def do_quiz() -> None:
print(" NOT BAD.") print(" NOT BAD.")
def ask_player(question, answer): def ask_player(question: str, answer) -> int:
print(question) print(question)
player_answer = float(input()) player_answer = float(input())

View File

@@ -178,7 +178,7 @@ def main() -> None:
# 470 # 470
def get_invalid_letters(user_command): def get_invalid_letters(user_command) -> str:
"""Makes sure player input consists of valid colors for selected game configuration.""" """Makes sure player input consists of valid colors for selected game configuration."""
valid_colors = color_letters[:num_colors] valid_colors = color_letters[:num_colors]
invalid_letters = "" invalid_letters = ""

View File

@@ -41,7 +41,7 @@ class NIM:
return pile, num return pile, num
def _command_integrity(self, num, pile): def _command_integrity(self, num, pile) -> bool:
return pile <= 4 and pile >= 1 and num <= self.piles[pile] return pile <= 4 and pile >= 1 and num <= self.piles[pile]
def print_pegs(self) -> None: def print_pegs(self) -> None:

View File

@@ -89,7 +89,7 @@ def print_instructions() -> str:
return player_name return player_name
def yes_no_prompt(msg): def yes_no_prompt(msg: str) -> bool:
while True: while True:
print(msg) print(msg)
response = input().upper() response = input().upper()
@@ -113,11 +113,11 @@ def print_more_directions(player_name: str) -> None:
print() print()
def calculate_customer_index(x, y): def calculate_customer_index(x: int, y: int) -> int:
return 4 * (y - 1) + x - 1 return 4 * (y - 1) + x - 1
def deliver_to(customer_index, customer_name, player_name): def deliver_to(customer_index, customer_name, player_name) -> bool:
print(f" DRIVER TO {player_name}: WHERE DOES {customer_name} LIVE?") print(f" DRIVER TO {player_name}: WHERE DOES {customer_name} LIVE?")
coords = input() coords = input()
@@ -133,7 +133,7 @@ def deliver_to(customer_index, customer_name, player_name):
return False return False
def play_game(num_turns, player_name): def play_game(num_turns, player_name) -> None:
for _turn in range(num_turns): for _turn in range(num_turns):
x = random.randint(1, 4) x = random.randint(1, 4)
y = random.randint(1, 4) y = random.randint(1, 4)

View File

@@ -96,7 +96,7 @@ def maybe_comma(state: State) -> None:
state.u = 0 state.u = 0
def pick_phrase(state: State): def pick_phrase(state: State) -> None:
state.i = random.randint(0, 4) state.i = random.randint(0, 4)
state.j += 1 state.j += 1
state.k += 1 state.k += 1

View File

@@ -5,7 +5,7 @@ import textwrap
NUMCNT = 9 # How many numbers are we playing with? NUMCNT = 9 # How many numbers are we playing with?
def main(): def main() -> None:
print("REVERSE".center(72)) print("REVERSE".center(72))
print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY".center(72)) print("CREATIVE COMPUTING MORRISTOWN, NEW JERSEY".center(72))
print() print()
@@ -14,7 +14,7 @@ def main():
print() print()
if not input("DO YOU WANT THE RULES? (yes/no) ").lower().startswith("n"): if not input("DO YOU WANT THE RULES? (yes/no) ").lower().startswith("n"):
rules() print_rules()
while True: while True:
game_loop() game_loop()
@@ -23,7 +23,7 @@ def main():
return return
def game_loop(): def game_loop() -> None:
"""Play the main game.""" """Play the main game."""
# Make a random list from 1 to NUMCNT # Make a random list from 1 to NUMCNT
numbers = list(range(1, NUMCNT + 1)) numbers = list(range(1, NUMCNT + 1))
@@ -67,12 +67,10 @@ def game_loop():
def print_list(numbers) -> None: def print_list(numbers) -> None:
"""Print out the list"""
print(" ".join(map(str, numbers))) print(" ".join(map(str, numbers)))
def rules(): def print_rules() -> None:
"""Print out the rules"""
help = textwrap.dedent( help = textwrap.dedent(
""" """
THIS IS THE GAME OF "REVERSE". TO WIN, ALL YOU HAVE THIS IS THE GAME OF "REVERSE". TO WIN, ALL YOU HAVE

View File

@@ -6,7 +6,7 @@
import random import random
def play_game(): def play_game() -> None:
"""Play one round of the game""" """Play one round of the game"""
while True: while True:

View File

@@ -93,7 +93,7 @@ def query_bets() -> Tuple[List[int], List[int]]:
return bet_ids, bet_values return bet_ids, bet_values
def bet_results(bet_ids: List[int], bet_values: List[int], result): def bet_results(bet_ids: List[int], bet_values: List[int], result) -> int:
"""Computes the results, prints them, and returns the total net winnings""" """Computes the results, prints them, and returns the total net winnings"""
total_winnings = 0 total_winnings = 0

View File

@@ -7,17 +7,17 @@ medals = {
} }
def ask(question): def ask(question: str) -> str:
print(question, end="? ") print(question, end="? ")
return input().upper() return input().upper()
def ask_int(question): def ask_int(question: str) -> int:
reply = ask(question) reply = ask(question)
return int(reply) if reply.isnumeric() else -1 return int(reply) if reply.isnumeric() else -1
def pre_run(gates, max_speeds): def pre_run(gates, max_speeds) -> None:
print('\nType "INS" for instructions') print('\nType "INS" for instructions')
print('Type "MAX" for approximate maximum speeds') print('Type "MAX" for approximate maximum speeds')
print('Type "RUN" for the beginning of the race') print('Type "RUN" for the beginning of the race')
@@ -50,10 +50,10 @@ def pre_run(gates, max_speeds):
cmd = ask(f'"{cmd}" is an illegal command--Retry') cmd = ask(f'"{cmd}" is an illegal command--Retry')
def run(gates, lvl, max_speeds): def run(gates, lvl, max_speeds) -> None:
global medals global medals
print("The starter counts down...5...4...3...2...1...Go!") print("The starter counts down...5...4...3...2...1...Go!")
time = 0 time: float = 0
speed = int(random() * (18 - 9) + 9) speed = int(random() * (18 - 9) + 9)
print("You're off") print("You're off")
for i in range(0, gates): for i in range(0, gates):

View File

@@ -34,9 +34,10 @@
import sys import sys
from collections import Counter from collections import Counter
from random import choices from random import choices
from typing import List
def initial_message(): def initial_message() -> None:
print(" " * 30 + "Slots") print(" " * 30 + "Slots")
print(" " * 15 + "Creative Computing Morrison, New Jersey") print(" " * 15 + "Creative Computing Morrison, New Jersey")
print("\n" * 3) print("\n" * 3)
@@ -45,7 +46,7 @@ def initial_message():
print("To pull the arm, punch the return key after making your bet.") print("To pull the arm, punch the return key after making your bet.")
def input_betting(): def input_betting() -> int:
print("\n") print("\n")
b = -1 b = -1
while b < 1 or b > 100: while b < 1 or b > 100:
@@ -61,7 +62,7 @@ def input_betting():
return int(b) return int(b)
def beeping(): def beeping() -> None:
# Function to produce a beep sound. # Function to produce a beep sound.
# In the original program is the subroutine at line 1270 # In the original program is the subroutine at line 1270
for _ in range(5): for _ in range(5):
@@ -69,7 +70,7 @@ def beeping():
sys.stdout.flush() sys.stdout.flush()
def spin_wheels(): def spin_wheels() -> List[str]:
possible_fruits = ["Bar", "Bell", "Orange", "Lemon", "Plum", "Cherry"] possible_fruits = ["Bar", "Bell", "Orange", "Lemon", "Plum", "Cherry"]
wheel = choices(possible_fruits, k=3) wheel = choices(possible_fruits, k=3)
@@ -79,7 +80,7 @@ def spin_wheels():
return wheel return wheel
def adjust_profits(wheel, m, profits): def adjust_profits(wheel: List[str], m: int, profits: int) -> int:
# we remove the duplicates # we remove the duplicates
s = set(wheel) s = set(wheel)
@@ -117,7 +118,7 @@ def adjust_profits(wheel, m, profits):
return profits return profits
def final_message(profits) -> None: def final_message(profits: int) -> None:
if profits < 0: if profits < 0:
print("Pay up! Please leave your money on the terminal") print("Pay up! Please leave your money on the terminal")
elif profits == 0: elif profits == 0:
@@ -140,7 +141,7 @@ def main() -> None:
answer = input("Again?") answer = input("Again?")
try: try:
if not answer[0].lower() == "y": if answer[0].lower() != "y":
keep_betting = False keep_betting = False
except IndexError: except IndexError:
keep_betting = False keep_betting = False

View File

@@ -24,22 +24,22 @@ Ported in 2021 by Jonas Nockert / @lemonad
""" """
from math import sqrt from math import sqrt
from random import choice, random, uniform from random import choice, random, uniform
from typing import List from typing import List, Tuple
PAGE_WIDTH = 72 PAGE_WIDTH = 72
def numeric_input(question, default=0): def numeric_input(question, default=0) -> float:
"""Ask user for a numeric value.""" """Ask user for a numeric value."""
while True: while True:
answer = input(f"{question} [{default}]: ").strip() or default answer_str = input(f"{question} [{default}]: ").strip() or default
try: try:
return float(answer) return float(answer_str)
except ValueError: except ValueError:
pass pass
def yes_no_input(question, default="YES"): def yes_no_input(question: str, default="YES") -> bool:
"""Ask user a yes/no question and returns True if yes, otherwise False.""" """Ask user a yes/no question and returns True if yes, otherwise False."""
answer = input(f"{question} (YES OR NO) [{default}]: ").strip() or default answer = input(f"{question} (YES OR NO) [{default}]: ").strip() or default
while answer.lower() not in ["n", "no", "y", "yes"]: while answer.lower() not in ["n", "no", "y", "yes"]:
@@ -47,7 +47,7 @@ def yes_no_input(question, default="YES"):
return answer.lower() in ["y", "yes"] return answer.lower() in ["y", "yes"]
def get_terminal_velocity(): def get_terminal_velocity() -> float:
"""Terminal velocity by user or picked by computer.""" """Terminal velocity by user or picked by computer."""
if yes_no_input("SELECT YOUR OWN TERMINAL VELOCITY", default="NO"): if yes_no_input("SELECT YOUR OWN TERMINAL VELOCITY", default="NO"):
v1 = numeric_input("WHAT TERMINAL VELOCITY (MI/HR)", default=100) v1 = numeric_input("WHAT TERMINAL VELOCITY (MI/HR)", default=100)
@@ -60,7 +60,7 @@ def get_terminal_velocity():
return v1 * (5280 / 3600) return v1 * (5280 / 3600)
def get_acceleration(): def get_acceleration() -> float:
"""Acceleration due to gravity by user or picked by computer.""" """Acceleration due to gravity by user or picked by computer."""
if yes_no_input("WANT TO SELECT ACCELERATION DUE TO GRAVITY", default="NO"): if yes_no_input("WANT TO SELECT ACCELERATION DUE TO GRAVITY", default="NO"):
a2 = numeric_input("WHAT ACCELERATION (FT/SEC/SEC)", default=32.16) a2 = numeric_input("WHAT ACCELERATION (FT/SEC/SEC)", default=32.16)
@@ -70,14 +70,14 @@ def get_acceleration():
return a2 return a2
def get_freefall_time(): def get_freefall_time() -> float:
"""User-guessed freefall time. """User-guessed freefall time.
The idea of the game is to pick a freefall time, given initial The idea of the game is to pick a freefall time, given initial
altitude, terminal velocity and acceleration, so the parachute altitude, terminal velocity and acceleration, so the parachute
as close to the ground as possible without going splat. as close to the ground as possible without going splat.
""" """
t_freefall = 0 t_freefall: float = 0
# A zero or negative freefall time is not handled by the motion # A zero or negative freefall time is not handled by the motion
# equations during the jump. # equations during the jump.
while t_freefall <= 0: while t_freefall <= 0:
@@ -85,13 +85,13 @@ def get_freefall_time():
return t_freefall return t_freefall
def jump(): def jump() -> float:
"""Simulate a jump and returns the altitude where the chute opened. """Simulate a jump and returns the altitude where the chute opened.
The idea is to open the chute as late as possible -- but not too late. The idea is to open the chute as late as possible -- but not too late.
""" """
v = 0 # Terminal velocity. v: float = 0 # Terminal velocity.
a = 0 # Acceleration. a: float = 0 # Acceleration.
initial_altitude = int(9001 * random() + 1000) initial_altitude = int(9001 * random() + 1000)
v1 = get_terminal_velocity() v1 = get_terminal_velocity()
@@ -181,9 +181,9 @@ def jump():
return altitude return altitude
def pick_random_celestial_body(): def pick_random_celestial_body() -> Tuple[str, float]:
"""Pick a random planet, the moon, or the sun with associated gravity.""" """Pick a random planet, the moon, or the sun with associated gravity."""
body, gravity = choice( return choice(
[ [
("MERCURY", 12.2), ("MERCURY", 12.2),
("VENUS", 28.3), ("VENUS", 28.3),
@@ -197,10 +197,9 @@ def pick_random_celestial_body():
("THE SUN", 896.0), ("THE SUN", 896.0),
] ]
) )
return body, gravity
def jump_stats(previous_jumps, chute_altitude): def jump_stats(previous_jumps, chute_altitude) -> Tuple[int, int]:
"""Compare altitude when chute opened with previous successful jumps. """Compare altitude when chute opened with previous successful jumps.
Return the number of previous jumps and the number of times Return the number of previous jumps and the number of times

View File

@@ -47,14 +47,12 @@ def print_stars(secret_number, guess) -> None:
print(stars) print(stars)
def get_guess(): def get_guess(prompt: str) -> int:
valid_response = False while True:
while not valid_response: guess_str = input(prompt)
guess = input("Your guess? ") if guess_str.isdigit():
if guess.isdigit(): guess = int(guess_str)
valid_response = True return guess
guess = int(guess)
return guess
def main() -> None: def main() -> None:
@@ -81,7 +79,7 @@ def main() -> None:
while (guess_number < MAX_GUESSES) and not player_has_won: while (guess_number < MAX_GUESSES) and not player_has_won:
print() print()
guess = get_guess() guess = get_guess("Your guess? ")
guess_number += 1 guess_number += 1
if guess == secret_number: if guess == secret_number:

View File

@@ -1,10 +1,9 @@
import random import random
from typing import Any, Dict, List
# Stock_Market
class Stock_Market: class Stock_Market:
def __init__(self): def __init__(self) -> None:
# Hard Coded Names # Hard Coded Names
short_names = ["IBM", "RCA", "LBJ", "ABC", "CBS"] short_names = ["IBM", "RCA", "LBJ", "ABC", "CBS"]
full_names = [ full_names = [
@@ -16,7 +15,7 @@ class Stock_Market:
] ]
# Initializing Dictionary to hold all the information systematically # Initializing Dictionary to hold all the information systematically
self.data = {} self.data: Dict[str, Any] = {}
for sn, fn in zip(short_names, full_names): for sn, fn in zip(short_names, full_names):
# A dictionary for each stock # A dictionary for each stock
temp = {"Name": fn, "Price": None, "Holdings": 0} temp = {"Name": fn, "Price": None, "Holdings": 0}
@@ -31,20 +30,17 @@ class Stock_Market:
self.cash_assets = 10000 self.cash_assets = 10000
self.stock_assets = 0 self.stock_assets = 0
def total_assets(self): def total_assets(self) -> float:
return self.cash_assets + self.stock_assets return self.cash_assets + self.stock_assets
def _generate_day_change(self): def _generate_day_change(self) -> None:
self.changes = [] self.changes = []
for _ in range(len(self.data)): for _ in range(len(self.data)):
self.changes.append( self.changes.append(
round(random.uniform(-5, 5), 2) round(random.uniform(-5, 5), 2)
) # Random % Change b/w -5 and 5 ) # Random % Change b/w -5 and 5
def update_prices(self): def update_prices(self) -> None:
self._generate_day_change() self._generate_day_change()
for stock, change in zip(self.data.values(), self.changes): for stock, change in zip(self.data.values(), self.changes):
stock["Price"] = round(stock["Price"] + (change / 100) * stock["Price"], 2) stock["Price"] = round(stock["Price"] + (change / 100) * stock["Price"], 2)
@@ -57,9 +53,8 @@ class Stock_Market:
print(f"\nNEW YORK STOCK EXCHANGE AVERAGE: ${sum / 5:.2f}") print(f"\nNEW YORK STOCK EXCHANGE AVERAGE: ${sum / 5:.2f}")
def get_average_change(self): def get_average_change(self) -> float:
sum: float = 0
sum = 0
for change in self.changes: for change in self.changes:
sum += change sum += change
@@ -77,8 +72,7 @@ class Stock_Market:
self.print_exchange_average() self.print_exchange_average()
self.print_assets() self.print_assets()
def take_inputs(self): def take_inputs(self) -> List[str]:
print("\nWHAT IS YOUR TRANSACTION IN") print("\nWHAT IS YOUR TRANSACTION IN")
flag = False flag = False
while not flag: while not flag:
@@ -92,7 +86,7 @@ class Stock_Market:
if len(new_holdings) == 5: if len(new_holdings) == 5:
flag = self._check_transaction(new_holdings) flag = self._check_transaction(new_holdings)
return new_holdings return new_holdings # type: ignore
def print_trading_day(self) -> None: def print_trading_day(self) -> None:
@@ -107,8 +101,7 @@ class Stock_Market:
) )
) )
def update_cash_assets(self, new_holdings): def update_cash_assets(self, new_holdings) -> None:
sell = 0 sell = 0
buy = 0 buy = 0
for stock, holding in zip(self.data.values(), new_holdings): for stock, holding in zip(self.data.values(), new_holdings):
@@ -120,8 +113,7 @@ class Stock_Market:
self.cash_assets = self.cash_assets + sell - buy self.cash_assets = self.cash_assets + sell - buy
def update_stock_assets(self): def update_stock_assets(self) -> None:
sum = 0 sum = 0
for data in self.data.values(): for data in self.data.values():
sum += data["Price"] * data["Holdings"] sum += data["Price"] * data["Holdings"]
@@ -129,13 +121,11 @@ class Stock_Market:
self.stock_assets = round(sum, 2) self.stock_assets = round(sum, 2)
def print_assets(self) -> None: def print_assets(self) -> None:
print(f"\nTOTAL STOCK ASSETS ARE: ${self.stock_assets:.2f}") print(f"\nTOTAL STOCK ASSETS ARE: ${self.stock_assets:.2f}")
print(f"TOTAL CASH ASSETS ARE: ${self.cash_assets:.2f}") print(f"TOTAL CASH ASSETS ARE: ${self.cash_assets:.2f}")
print(f"TOTAL ASSETS ARE: ${self.total_assets():.2f}") print(f"TOTAL ASSETS ARE: ${self.total_assets():.2f}")
def _check_transaction(self, new_holdings): def _check_transaction(self, new_holdings) -> bool:
sum = 0 sum = 0
for stock, holding in zip(self.data.values(), new_holdings): for stock, holding in zip(self.data.values(), new_holdings):
if holding > 0: if holding > 0:
@@ -156,8 +146,7 @@ class Stock_Market:
return True return True
def update_holdings(self, new_holdings): def update_holdings(self, new_holdings) -> None:
for stock, new_holding in zip(self.data.values(), new_holdings): for stock, new_holding in zip(self.data.values(), new_holdings):
stock["Holdings"] += new_holding stock["Holdings"] += new_holding
@@ -186,7 +175,7 @@ HAVE $10,000 TO INVEST. USE INTEGERS FOR ALL YOUR INPUTS.
) )
def main(): def main() -> None:
print("\t\t STOCK MARKET") print("\t\t STOCK MARKET")
help = input("\nDO YOU WANT INSTRUCTIONS(YES OR NO)? ") help = input("\nDO YOU WANT INSTRUCTIONS(YES OR NO)? ")

View File

@@ -53,7 +53,7 @@ def print_right() -> None:
print(random.choice(right_words)) print(random.choice(right_words))
def ask_question(question_number): def ask_question(question_number: int) -> None:
words = synonym_words[question_number] words = synonym_words[question_number]
clues = words[:] clues = words[:]
base_word = clues.pop(0) base_word = clues.pop(0)

View File

@@ -8,6 +8,7 @@ Ported by Dave LeCompte
import math import math
import random import random
from typing import List
PAGE_WIDTH = 64 PAGE_WIDTH = 64
@@ -41,7 +42,7 @@ def print_instructions() -> None:
print() print()
def prompt(): def prompt() -> List[float]:
while True: while True:
response = input("INPUT ANGLE DEVIATION FROM X, DEVIATION FROM Z, DISTANCE? ") response = input("INPUT ANGLE DEVIATION FROM X, DEVIATION FROM Z, DISTANCE? ")
if "," not in response: if "," not in response:
@@ -54,14 +55,14 @@ def prompt():
return [float(t) for t in terms] return [float(t) for t in terms]
def next_target(): def next_target() -> None:
for _ in range(5): for _ in range(5):
print() print()
print("NEXT TARGET...") print("NEXT TARGET...")
print() print()
def describe_miss(x, y, z, x1, y1, z1, d): def describe_miss(x, y, z, x1, y1, z1, d) -> None:
x2 = x1 - x x2 = x1 - x
y2 = y1 - y y2 = y1 - y
z2 = z1 - z z2 = z1 - z
@@ -88,7 +89,7 @@ def describe_miss(x, y, z, x1, y1, z1, d):
print() print()
def do_shot_loop(p1, x, y, z): def do_shot_loop(p1, x, y, z) -> None:
shot_count = 0 shot_count = 0
while True: while True:
shot_count += 1 shot_count += 1
@@ -137,11 +138,11 @@ def do_shot_loop(p1, x, y, z):
describe_miss(x, y, z, x1, y1, z1, distance) describe_miss(x, y, z, x1, y1, z1, distance)
def show_radians(a, b): def show_radians(a, b) -> None:
print(f"RADIANS FROM X AXIS = {a:.4f} FROM Z AXIS = {b:.4f}") print(f"RADIANS FROM X AXIS = {a:.4f} FROM Z AXIS = {b:.4f}")
def play_game(): def play_game() -> None:
while True: while True:
a = random.uniform(0, 2 * math.pi) # random angle a = random.uniform(0, 2 * math.pi) # random angle
b = random.uniform(0, 2 * math.pi) # random angle b = random.uniform(0, 2 * math.pi) # random angle

View File

@@ -5,6 +5,7 @@
# The code originated from Dartmouth College # The code originated from Dartmouth College
from enum import Enum from enum import Enum
from typing import Optional, Tuple, Union
class Move(Enum): class Move(Enum):
@@ -31,8 +32,7 @@ class Player(Enum):
class TicTacToe3D: class TicTacToe3D:
"""The game logic for 3D Tic Tac Toe and the machine opponent""" """The game logic for 3D Tic Tac Toe and the machine opponent"""
def __init__(self): def __init__(self) -> None:
# 4x4x4 board keeps track of which player occupies each place # 4x4x4 board keeps track of which player occupies each place
# and used by machine to work out its strategy # and used by machine to work out its strategy
self.board = [0] * 64 self.board = [0] * 64
@@ -120,7 +120,7 @@ class TicTacToe3D:
[12, 25, 38, 51], [12, 25, 38, 51],
] ]
def get(self, x, y, z): def get(self, x, y, z) -> Player:
m = self.board[4 * (4 * z + y) + x] m = self.board[4 * (4 * z + y) + x]
if m == 40: if m == 40:
return Player.MACHINE return Player.MACHINE
@@ -129,11 +129,11 @@ class TicTacToe3D:
else: else:
return Player.EMPTY return Player.EMPTY
def move3D(self, x, y, z, player): def move_3d(self, x, y, z, player) -> bool:
m = 4 * (4 * z + y) + x m = 4 * (4 * z + y) + x
return self.move(m, player) return self.move(m, player)
def move(self, m, player): def move(self, m, player) -> bool:
if self.board[m] > 1: if self.board[m] > 1:
return False return False
@@ -143,13 +143,13 @@ class TicTacToe3D:
self.board[m] = 8 self.board[m] = 8
return True return True
def get3DPosition(self, m): def get_3d_position(self, m) -> Tuple[int, int, int]:
x = m % 4 x = m % 4
y = (m // 4) % 4 y = (m // 4) % 4
z = m // 16 z = m // 16
return x, y, z return x, y, z
def evaluateLines(self): def evaluate_lines(self) -> None:
self.lineValues = [0] * 76 self.lineValues = [0] * 76
for j in range(76): for j in range(76):
value = 0 value = 0
@@ -157,18 +157,18 @@ class TicTacToe3D:
value += self.board[self.lines[j][k]] value += self.board[self.lines[j][k]]
self.lineValues[j] = value self.lineValues[j] = value
def strategyMarkLine(self, i): def strategy_mark_line(self, i) -> None:
for j in range(4): for j in range(4):
m = self.lines[i][j] m = self.lines[i][j]
if self.board[m] == 0: if self.board[m] == 0:
self.board[m] = 1 self.board[m] = 1
def clearStrategyMarks(self): def clear_strategy_marks(self) -> None:
for i in range(64): for i in range(64):
if self.board[i] == 1: if self.board[i] == 1:
self.board[i] = 0 self.board[i] = 0
def markAndMove(self, vlow, vhigh, vmove): def mark_and_move(self, vlow, vhigh, vmove) -> Optional[Tuple[Move, int]]:
""" """
mark lines that can potentially win the game for the human mark lines that can potentially win the game for the human
or the machine and choose best place to play or the machine and choose best place to play
@@ -180,37 +180,37 @@ class TicTacToe3D:
self.lineValues[i] = value self.lineValues[i] = value
if vlow <= value < vhigh: if vlow <= value < vhigh:
if value > vlow: if value > vlow:
return self.moveTriple(i) return self.move_triple(i)
self.strategyMarkLine(i) self.strategy_mark_line(i)
self.evaluateLines() self.evaluate_lines()
for i in range(76): for i in range(76):
value = self.lineValues[i] value = self.lineValues[i]
if value == 4 or value == vmove: if value == 4 or value == vmove:
return self.moveDiagonals(i, 1) return self.move_diagonals(i, 1)
return None return None
def machineMove(self): def machine_move(self) -> Union[None, Tuple[Move, int], Tuple[Move, int, int]]:
"""machine works out what move to play""" """machine works out what move to play"""
self.clearStrategyMarks() self.clear_strategy_marks()
self.evaluateLines() self.evaluate_lines()
for value, event in [ for value, event in [
(32, self.humanWin), (32, self.human_win),
(120, self.machineWin), (120, self.machine_win),
(24, self.blockHumanWin), (24, self.block_human_win),
]: ]:
for i in range(76): for i in range(76):
if self.lineValues[i] == value: if self.lineValues[i] == value:
return event(i) return event(i)
m = self.markAndMove(80, 88, 43) m = self.mark_and_move(80, 88, 43)
if m is not None: if m is not None:
return m return m
self.clearStrategyMarks() self.clear_strategy_marks()
m = self.markAndMove(16, 24, 11) m = self.mark_and_move(16, 24, 11)
if m is not None: if m is not None:
return m return m
@@ -222,11 +222,11 @@ class TicTacToe3D:
if (32 <= value < 40) or (72 <= value < 80): if (32 <= value < 40) or (72 <= value < 80):
for s in [1, 0]: for s in [1, 0]:
for i in range(4 * k, 4 * k + 4): for i in range(4 * k, 4 * k + 4):
m = self.moveDiagonals(i, s) m = self.move_diagonals(i, s)
if m is not None: if m is not None:
return m return m
self.clearStrategyMarks() self.clear_strategy_marks()
for y in self.corners: for y in self.corners:
if self.board[y] == 0: if self.board[y] == 0:
@@ -238,24 +238,24 @@ class TicTacToe3D:
return (Move.DRAW, -1) return (Move.DRAW, -1)
def humanWin(self, i): def human_win(self, i) -> Tuple[Move, int, int]:
return (Move.HUMAN_WIN, -1, i) return (Move.HUMAN_WIN, -1, i)
def machineWin(self, i): def machine_win(self, i) -> Optional[Tuple[Move, int, int]]:
for j in range(4): for j in range(4):
m = self.lines[i][j] m = self.lines[i][j]
if self.board[m] == 0: if self.board[m] == 0:
return (Move.MACHINE_WIN, m, i) return (Move.MACHINE_WIN, m, i)
return None return None
def blockHumanWin(self, i): def block_human_win(self, i) -> Optional[Tuple[Move, int]]:
for j in range(4): for j in range(4):
m = self.lines[i][j] m = self.lines[i][j]
if self.board[m] == 0: if self.board[m] == 0:
return (Move.NICE_TRY, m) return (Move.NICE_TRY, m)
return None return None
def moveTriple(self, i): def move_triple(self, i) -> Tuple[Move, int]:
"""make two lines-of-3 or prevent human from doing this""" """make two lines-of-3 or prevent human from doing this"""
for j in range(4): for j in range(4):
m = self.lines[i][j] m = self.lines[i][j]
@@ -267,7 +267,7 @@ class TicTacToe3D:
return (Move.CONCEDES, -1) return (Move.CONCEDES, -1)
# choose move in corners or center boxes of square 4x4 # choose move in corners or center boxes of square 4x4
def moveDiagonals(self, i, s): def move_diagonals(self, i, s) -> Optional[Tuple[Move, int]]:
if 0 < (i % 4) < 3: if 0 < (i % 4) < 3:
jrange = [1, 2] jrange = [1, 2]
else: else:
@@ -280,15 +280,15 @@ class TicTacToe3D:
class Qubit: class Qubit:
def moveCode(self, board, m): def move_code(self, board, m) -> str:
x, y, z = board.get3DPosition(m) x, y, z = board.get3DPosition(m)
return f"{z + 1:d}{y + 1:d}{x + 1:d}" return f"{z + 1:d}{y + 1:d}{x + 1:d}"
def showWin(self, board, i): def show_win(self, board, i) -> None:
for m in board.lines[i]: for m in board.lines[i]:
print(self.moveCode(board, m)) print(self.move_code(board, m))
def showBoard(self, board): def show_board(self, board) -> None:
c = " YM" c = " YM"
for z in range(4): for z in range(4):
for y in range(4): for y in range(4):
@@ -299,7 +299,7 @@ class Qubit:
print("\n") print("\n")
print("\n") print("\n")
def humanMove(self, board): def human_move(self, board) -> bool:
print() print()
c = "1234" c = "1234"
while True: while True:
@@ -307,7 +307,7 @@ class Qubit:
if h == "1": if h == "1":
return False return False
if h == "0": if h == "0":
self.showBoard(board) self.show_board(board)
continue continue
if (len(h) == 3) and (h[0] in c) and (h[1] in c) and (h[2] in c): if (len(h) == 3) and (h[0] in c) and (h[1] in c) and (h[2] in c):
x = c.find(h[2]) x = c.find(h[2])
@@ -322,7 +322,7 @@ class Qubit:
return True return True
def play(self): def play(self) -> None:
print("Qubic\n") print("Qubic\n")
print("Create Computing Morristown, New Jersey\n\n\n") print("Create Computing Morristown, New Jersey\n\n\n")
while True: while True:
@@ -368,22 +368,23 @@ class Qubit:
] ]
while True: while True:
if not skipHuman and not self.humanMove(board): if not skipHuman and not self.human_move(board):
break break
skipHuman = False skipHuman = False
m = board.machineMove() m = board.machine_move()
assert m is not None
if m[0] == Move.HUMAN_WIN: if m[0] == Move.HUMAN_WIN:
print("You win as follows,") print("You win as follows,")
self.showWin(board, m[2]) self.show_win(board, m[2]) # type: ignore
break break
elif m[0] == Move.MACHINE_WIN: elif m[0] == Move.MACHINE_WIN:
print( print(
"Machine moves to {}, and wins as follows".format( "Machine moves to {}, and wins as follows".format(
self.moveCode(board, m[1]) self.move_code(board, m[1])
) )
) )
self.showWin(board, m[2]) self.show_win(board, m[2]) # type: ignore
break break
elif m[0] == Move.DRAW: elif m[0] == Move.DRAW:
print("The game is a draw.") print("The game is a draw.")
@@ -393,10 +394,10 @@ class Qubit:
break break
else: else:
print(move_text[m[0].value - Move.MOVES.value]) print(move_text[m[0].value - Move.MOVES.value])
print(self.moveCode(board, m[1])) print(self.move_code(board, m[1]))
board.move(m[1], Player.MACHINE) board.move(m[1], Player.MACHINE)
self.showBoard(board) self.show_board(board)
print(" ") print(" ")
while True: while True:

View File

@@ -1,15 +1,18 @@
from typing import List, Tuple, Union
class TicTacToe: class TicTacToe:
def __init__(self, pick, sz=3): def __init__(self, pick, sz=3) -> None:
self.pick = pick self.pick = pick
self.dim_sz = sz self.dim_sz = sz
self.board = self.clear_board() self.board = self.clear_board()
def clear_board(self): def clear_board(self) -> List[List[str]]:
board = [["blur" for i in range(self.dim_sz)] for j in range(self.dim_sz)] board = [["blur" for i in range(self.dim_sz)] for j in range(self.dim_sz)]
# made a 3x3 by-default board # made a 3x3 by-default board
return board return board
def move_record(self, r, c): def move_record(self, r, c) -> Union[str, bool]:
if r > self.dim_sz or c > self.dim_sz: if r > self.dim_sz or c > self.dim_sz:
return "Out of Bounds" return "Out of Bounds"
if self.board[r][c] != "blur": if self.board[r][c] != "blur":
@@ -17,7 +20,7 @@ class TicTacToe:
self.board[r][c] = self.pick self.board[r][c] = self.pick
return True return True
def check_win(self): # 1 you won, 0 computer won, -1 tie def check_win(self) -> int: # 1 you won, 0 computer won, -1 tie
# Flag syntax -> first player no. , # Flag syntax -> first player no. ,
# User is Player#1 ; # User is Player#1 ;
# Check set 1 -> row and '\' diagonal & Check set 2 -> col and '/' diagonal # Check set 1 -> row and '\' diagonal & Check set 2 -> col and '/' diagonal
@@ -88,7 +91,7 @@ class TicTacToe:
return -1 return -1
def next_move(self): def next_move(self) -> Union[Tuple[int, int], Tuple[List[int], List[int]]]:
available_moves = [] # will carry all available moves available_moves = [] # will carry all available moves
player_win_spot = [] # if player (user Wins) player_win_spot = [] # if player (user Wins)
comp_pick = "O" comp_pick = "O"
@@ -113,7 +116,6 @@ class TicTacToe:
if len(player_win_spot) != 0: if len(player_win_spot) != 0:
self.board[player_win_spot[0][0]][player_win_spot[0][1]] = comp_pick self.board[player_win_spot[0][0]][player_win_spot[0][1]] = comp_pick
return player_win_spot[0][0], player_win_spot[0][1] return player_win_spot[0][0], player_win_spot[0][1]
# print(AvailableMoves)
if len(available_moves) == 1: if len(available_moves) == 1:
self.board[available_moves[0][0]][available_moves[0][1]] = comp_pick self.board[available_moves[0][0]][available_moves[0][1]] = comp_pick
return [available_moves[0][0]], [available_moves[0][1]] return [available_moves[0][0]], [available_moves[0][1]]
@@ -121,7 +123,6 @@ class TicTacToe:
return -1, -1 return -1, -1
c1, c2 = self.dim_sz // 2, self.dim_sz // 2 c1, c2 = self.dim_sz // 2, self.dim_sz // 2
# print(c1,c2,self.dim_sz)
if (c1, c2) in available_moves: # CENTER if (c1, c2) in available_moves: # CENTER
self.board[c1][c2] = comp_pick self.board[c1][c2] = comp_pick
return c1, c2 return c1, c2
@@ -163,34 +164,33 @@ class TicTacToe:
) in available_moves: # RIGHT TOP TO RIGHT BOTTOM ) in available_moves: # RIGHT TOP TO RIGHT BOTTOM
self.board[c1 - gap + i][c2 + gap] = comp_pick self.board[c1 - gap + i][c2 + gap] = comp_pick
return c1 - gap + i, c2 + gap return c1 - gap + i, c2 + gap
raise RuntimeError("No moves available")
def display(Game: TicTacToe) -> None: def display(game: TicTacToe) -> None:
line1 = "" line1 = ""
for i in range(0, Game.dim_sz): for i in range(0, game.dim_sz):
for j in range(0, Game.dim_sz - 1): for j in range(0, game.dim_sz - 1):
if Game.board[i][j] == "blur": if game.board[i][j] == "blur":
line1 = line1 + " |" line1 = line1 + " |"
else: else:
line1 = line1 + " " + Game.board[i][j] + " |" line1 = line1 + " " + game.board[i][j] + " |"
if Game.board[i][Game.dim_sz - 1] == "blur": if game.board[i][game.dim_sz - 1] == "blur":
line1 = line1 + " \n" line1 = line1 + " \n"
else: else:
line1 = line1 + " " + Game.board[i][Game.dim_sz - 1] + " \n" line1 = line1 + " " + game.board[i][game.dim_sz - 1] + " \n"
# line1 = line1 + " " + Game.board[i][Game.dim_sz-1] + "\n"
print(line1, "\n\n") print(line1, "\n\n")
def main() -> None: def main() -> None:
Pick = input("Pick 'X' or 'O' ").strip().upper() pick = input("Pick 'X' or 'O' ").strip().upper()
if Pick == "O": if pick == "O":
Game = TicTacToe("O") game = TicTacToe("O")
else: else:
Game = TicTacToe("X") game = TicTacToe("X")
display(Game=Game) display(game=game)
while True: while True:
# Display(Game) temp: Union[bool, str] = False
temp = False
while not temp: while not temp:
move = list( move = list(
map( map(
@@ -198,24 +198,24 @@ def main() -> None:
input("Make A Move in Grid System from (0,0) to (2,2) ").split(), input("Make A Move in Grid System from (0,0) to (2,2) ").split(),
) )
) )
temp = Game.move_record(move[0], move[1]) temp = game.move_record(move[0], move[1])
if not temp: if not temp:
print(temp) print(temp)
if Game.check_win() == 1: if game.check_win() == 1:
print("You Won!") print("You Won!")
break break
print("Your Move:- ") print("Your Move:- ")
display(Game) display(game)
C1, C2 = Game.next_move() C1, C2 = game.next_move()
if C1 == -1 and C2 == -1: if C1 == -1 and C2 == -1:
print("Game Tie!") print("Game Tie!")
break break
if Game.check_win() == 0: if game.check_win() == 0:
print("You lost!") print("You lost!")
break break
print("Computer's Move :-") print("Computer's Move :-")
display(Game) display(game)
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -191,7 +191,7 @@ def prompt_player(board):
return move return move
def main(): def main() -> None:
print(" " * 30 + "TIC-TAC-TOE") print(" " * 30 + "TIC-TAC-TOE")
print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY") print(" " * 15 + "CREATIVE COMPUTING MORRISTOWN, NEW JERSEY")
print("\n\n") print("\n\n")

View File

@@ -1,11 +1,12 @@
import sys import sys
from typing import List, Optional
class Disk: class Disk:
def __init__(self, size): def __init__(self, size: int) -> None:
self.__size = size self.__size = size
def size(self): def size(self) -> int:
return self.__size return self.__size
def print(self) -> None: def print(self) -> None:
@@ -13,28 +14,29 @@ class Disk:
class Tower: class Tower:
def __init__(self): def __init__(self) -> None:
self.__disks = [] self.__disks: List[Disk] = []
def empty(self): def empty(self) -> bool:
return len(self.__disks) == 0 return len(self.__disks) == 0
def top(self): def top(self) -> Optional[Disk]:
if self.empty(): if self.empty():
return None return None
else: else:
return self.__disks[-1] return self.__disks[-1]
def add(self, disk): def add(self, disk: Disk) -> None:
if not self.empty(): if not self.empty():
t = self.top() t = self.top()
assert t is not None # cannot happen as it's not empty
if disk.size() > t.size(): if disk.size() > t.size():
raise Exception( raise Exception(
"YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE, IT MIGHT CRUSH IT!" "YOU CAN'T PLACE A LARGER DISK ON TOP OF A SMALLER ONE, IT MIGHT CRUSH IT!"
) )
self.__disks.append(disk) self.__disks.append(disk)
def pop(self): def pop(self) -> Disk:
if self.empty(): if self.empty():
raise Exception("empty pop") raise Exception("empty pop")
return self.__disks.pop() return self.__disks.pop()
@@ -45,7 +47,7 @@ class Tower:
class Game: class Game:
def __init__(self): def __init__(self) -> None:
# use fewer sizes to make debugging easier # use fewer sizes to make debugging easier
# self.__sizes = [3, 5, 7] # ,9,11,13,15] # self.__sizes = [3, 5, 7] # ,9,11,13,15]
self.__sizes = [3, 5, 7, 9, 11, 13, 15] self.__sizes = [3, 5, 7, 9, 11, 13, 15]
@@ -60,23 +62,23 @@ class Game:
disk = Disk(size) disk = Disk(size)
self.__towers[0].add(disk) self.__towers[0].add(disk)
def winner(self): def winner(self) -> bool:
return self.__towers[0].empty() and self.__towers[1].empty() return self.__towers[0].empty() and self.__towers[1].empty()
def print(self) -> None: def print(self) -> None:
for t in self.__towers: for t in self.__towers:
t.print() t.print()
def moves(self): def moves(self) -> int:
return self.__moves return self.__moves
def which_disk(self): def which_disk(self) -> int:
w = int(input("WHICH DISK WOULD YOU LIKE TO MOVE\n")) w = int(input("WHICH DISK WOULD YOU LIKE TO MOVE\n"))
if w in self.__sizes: if w in self.__sizes:
return w return w
raise Exception() raise Exception()
def pick_disk(self): def pick_disk(self) -> Optional[Tower]:
which = None which = None
while which is None: while which is None:
try: try:
@@ -93,7 +95,7 @@ class Game:
assert valids[0].top().size() == which assert valids[0].top().size() == which
return valids[0] return valids[0]
def which_tower(self): def which_tower(self) -> Optional[Tower]:
try: try:
needle = int(input("PLACE DISK ON WHICH NEEDLE\n")) needle = int(input("PLACE DISK ON WHICH NEEDLE\n"))
tower = self.__towers[needle - 1] tower = self.__towers[needle - 1]
@@ -105,7 +107,7 @@ class Game:
else: else:
return tower return tower
def take_turn(self): def take_turn(self) -> None:
from_tower = None from_tower = None
while from_tower is None: while from_tower is None:
from_tower = self.pick_disk() from_tower = self.pick_disk()

View File

@@ -6,14 +6,14 @@
import random import random
def play_game(): def play_game() -> None:
"""Play one round of the game""" """Play one round of the game"""
car_speed = random.randint(40, 65) car_speed = random.randint(40, 65)
time_difference = random.randint(5, 20) time_difference = random.randint(5, 20)
train_speed = random.randint(20, 39) train_speed = random.randint(20, 39)
print("\nA car travelling", car_speed, "MPH can make a certain trip in") print("\nA car travelling", car_speed, "MPH can make a certain trip in")
print(time_difference, "hours less than a train travelling at", train_speed, "MPH") print(time_difference, "hours less than a train travelling at", train_speed, "MPH")
time_answer = 0 time_answer: float = 0
while time_answer == 0: while time_answer == 0:
try: try:
time_answer = float(input("How long does the trip take by car ")) time_answer = float(input("How long does the trip take by car "))

View File

@@ -10,7 +10,7 @@ number_max = 100
guess_max = 6 guess_max = 6
def play_game(): def play_game() -> None:
"""Play one round of the game""" """Play one round of the game"""
number_computer = random.randint(1, number_max) number_computer = random.randint(1, number_max)

View File

@@ -6,7 +6,7 @@
import random import random
def play_game(): def play_game() -> None:
"""Play one round of the game""" """Play one round of the game"""
matches = 23 matches = 23

54
94_War/python/cards.json Normal file
View File

@@ -0,0 +1,54 @@
[
"S-2",
"H-2",
"C-2",
"D-2",
"S-3",
"H-3",
"C-3",
"D-3",
"S-4",
"H-4",
"C-4",
"D-4",
"S-5",
"H-5",
"C-5",
"D-5",
"S-6",
"H-6",
"C-6",
"D-6",
"S-7",
"H-7",
"C-7",
"D-7",
"S-8",
"H-8",
"C-8",
"D-8",
"S-9",
"H-9",
"C-9",
"D-9",
"S-10",
"H-10",
"C-10",
"D-10",
"S-J",
"H-J",
"C-J",
"D-J",
"S-Q",
"H-Q",
"C-Q",
"D-Q",
"S-K",
"H-K",
"C-K",
"D-K",
"S-A",
"H-A",
"C-A",
"D-A"
]

View File

@@ -1,75 +1,27 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# WAR
#
# Converted from BASIC to Python by Trevor Hobson
"""
WAR
Converted from BASIC to Python by Trevor Hobson
"""
import json
import random import random
from pathlib import Path
from typing import List
def card_value(input): def card_value(input: str) -> int:
return ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"].index( return ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"].index(
input.split("-")[1] input.split("-")[1]
) )
cards = [ def play_game() -> None:
"S-2",
"H-2",
"C-2",
"D-2",
"S-3",
"H-3",
"C-3",
"D-3",
"S-4",
"H-4",
"C-4",
"D-4",
"S-5",
"H-5",
"C-5",
"D-5",
"S-6",
"H-6",
"C-6",
"D-6",
"S-7",
"H-7",
"C-7",
"D-7",
"S-8",
"H-8",
"C-8",
"D-8",
"S-9",
"H-9",
"C-9",
"D-9",
"S-10",
"H-10",
"C-10",
"D-10",
"S-J",
"H-J",
"C-J",
"D-J",
"S-Q",
"H-Q",
"C-Q",
"D-Q",
"S-K",
"H-K",
"C-K",
"D-K",
"S-A",
"H-A",
"C-A",
"D-A",
]
def play_game():
"""Play one round of the game""" """Play one round of the game"""
with open(Path(__file__).parent / "cards.json") as f:
cards: List[str] = json.load(f)
random.shuffle(cards) random.shuffle(cards)
score_you = 0 score_you = 0

View File

@@ -12,27 +12,28 @@ Ported by Dave LeCompte.
""" """
import datetime import datetime
from typing import Tuple
GET_TODAY_FROM_SYSTEM = True GET_TODAY_FROM_SYSTEM = True
def get_date_from_user(prompt: str): def get_date_from_user(prompt: str) -> Tuple[int, int, int]:
while True: while True:
print(prompt) print(prompt)
date_str = input() date_str = input()
try: try:
month_num, day_num, year_num = (int(x) for x in date_str.split(",")) month_num, day_num, year_num = (int(x) for x in date_str.split(","))
return month_num, day_num, year_num
except Exception: except Exception:
print("I COULDN'T UNDERSTAND THAT. TRY AGAIN.") print("I COULDN'T UNDERSTAND THAT. TRY AGAIN.")
return month_num, day_num, year_num
def get_date_from_system(): def get_date_from_system() -> Tuple[int, int, int]:
dt = datetime.datetime.today() dt = datetime.datetime.today()
return dt.month, dt.day, dt.year return dt.month, dt.day, dt.year
def get_day_of_week(weekday_index, day): def get_day_of_week(weekday_index, day) -> str:
day_names = { day_names = {
1: "SUNDAY", 1: "SUNDAY",
2: "MONDAY", 2: "MONDAY",
@@ -48,7 +49,7 @@ def get_day_of_week(weekday_index, day):
return day_names[weekday_index] return day_names[weekday_index]
def previous_day(b): def previous_day(b) -> int:
if b == 0: if b == 0:
b = 6 b = 6
return b - 1 return b - 1
@@ -133,7 +134,7 @@ def calculate_day_of_week(year, month, day):
return b return b
def end(): def end() -> None:
for _ in range(5): for _ in range(5):
print() print()