Skip to content

Commit 55f2eab

Browse files
authored
Merge branch 'master' into mandelbrot
2 parents a5a1375 + 8eee00f commit 55f2eab

File tree

23 files changed

+1197
-0
lines changed

23 files changed

+1197
-0
lines changed

python-dice-roll/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# RP Dice Roller
2+
3+
RP Dice Roller is a small Python app that simulates dice rolling events. This code supplements the article [Build a Dice-Rolling Application With Python](https://realpython.com/python-dice-roll/) on realpython.com.
4+
5+
## Running RP Dice Roller
6+
7+
The project's code was tested with Python 3.9.5. However, it should work with any Python versions greater than or equal to 3.6. There are no external dependencies. To run the project's code, execute the following command with the appropriate Python interpreter:
8+
9+
```sh
10+
$ python dice.py
11+
How many dice do you want to roll? [1-6] 5
12+
13+
~~~~~~~~~~~~~~~~~~~~~~~~~ RESULTS ~~~~~~~~~~~~~~~~~~~~~~~~~
14+
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
15+
│ ● ● │ │ ● │ │ ● ● │ │ ● ● │ │ │
16+
│ ● │ │ │ │ ● │ │ ● │ │ ● │
17+
│ ● ● │ │ ● │ │ ● ● │ │ ● ● │ │ │
18+
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
19+
```
20+
21+
The application prompts the user for the number of dice they want to roll and generates a dice faces ASCII diagram with the results.
22+
23+
Each folder in this repository contains the code for the corresponding step in the companion article in a file called `dice.py`.
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
"""Simulate a six-sided dice roll.
2+
3+
Usage:
4+
5+
$ python dice.py
6+
How many dice do you want to roll? [1-6] 5
7+
8+
~~~~~~~~~~~~~~~~~~~~~~~~~ RESULTS ~~~~~~~~~~~~~~~~~~~~~~~~~
9+
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
10+
│ ● ● │ │ ● │ │ ● ● │ │ ● ● │ │ │
11+
│ ● │ │ │ │ ● │ │ ● │ │ ● │
12+
│ ● ● │ │ ● │ │ ● ● │ │ ● ● │ │ │
13+
└─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘
14+
"""
15+
16+
import random
17+
18+
DICE_ART = {
19+
1: (
20+
"┌─────────┐",
21+
"│ │",
22+
"│ ● │",
23+
"│ │",
24+
"└─────────┘",
25+
),
26+
2: (
27+
"┌─────────┐",
28+
"│ ● │",
29+
"│ │",
30+
"│ ● │",
31+
"└─────────┘",
32+
),
33+
3: (
34+
"┌─────────┐",
35+
"│ ● │",
36+
"│ ● │",
37+
"│ ● │",
38+
"└─────────┘",
39+
),
40+
4: (
41+
"┌─────────┐",
42+
"│ ● ● │",
43+
"│ │",
44+
"│ ● ● │",
45+
"└─────────┘",
46+
),
47+
5: (
48+
"┌─────────┐",
49+
"│ ● ● │",
50+
"│ ● │",
51+
"│ ● ● │",
52+
"└─────────┘",
53+
),
54+
6: (
55+
"┌─────────┐",
56+
"│ ● ● │",
57+
"│ ● ● │",
58+
"│ ● ● │",
59+
"└─────────┘",
60+
),
61+
}
62+
DIE_HEIGHT = len(DICE_ART[1])
63+
DIE_WIDTH = len(DICE_ART[1][0])
64+
DIE_FACE_SEPARATOR = " "
65+
66+
67+
def parse_input(input_string):
68+
"""Return `input_string` as an integer between 1 and 6.
69+
70+
Check if `input_string` is an integer number between 1 and 6.
71+
If so, return an integer with the same value. Otherwise, tell
72+
the user to enter a valid number and quit the program.
73+
"""
74+
if input_string.strip() in {"1", "2", "3", "4", "5", "6"}:
75+
return int(input_string)
76+
else:
77+
print("Please enter a number from 1 to 6.")
78+
raise SystemExit(1)
79+
80+
81+
def roll_dice(num_dice):
82+
"""Return a list of integers with length `num_dice`.
83+
84+
Each integer in the returned list is a random number between
85+
1 and 6, inclusive.
86+
"""
87+
roll_results = []
88+
for _ in range(num_dice):
89+
roll = random.randint(1, 6)
90+
roll_results.append(roll)
91+
return roll_results
92+
93+
94+
def generate_dice_faces_diagram(dice_values):
95+
"""Return an ASCII diagram of dice faces from `dice_values`.
96+
97+
The string returned contains an ASCII representation of each die.
98+
For example, if `dice_values = [4, 1, 3, 2]` then the string
99+
returned looks like this:
100+
101+
~~~~~~~~~~~~~~~~~~~ RESULTS ~~~~~~~~~~~~~~~~~~~
102+
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
103+
│ ● ● │ │ │ │ ● │ │ ● │
104+
│ │ │ ● │ │ ● │ │ │
105+
│ ● ● │ │ │ │ ● │ │ ● │
106+
└─────────┘ └─────────┘ └─────────┘ └─────────┘
107+
"""
108+
dice_faces = _get_dice_faces(dice_values)
109+
dice_faces_rows = _generate_dice_faces_rows(dice_faces)
110+
111+
# Generate header with the word "RESULTS" centered
112+
width = len(dice_faces_rows[0])
113+
diagram_header = " RESULTS ".center(width, "~")
114+
115+
dice_faces_diagram = "\n".join([diagram_header] + dice_faces_rows)
116+
return dice_faces_diagram
117+
118+
119+
def _get_dice_faces(dice_values):
120+
dice_faces = []
121+
for value in dice_values:
122+
dice_faces.append(DICE_ART[value])
123+
return dice_faces
124+
125+
126+
def _generate_dice_faces_rows(dice_faces):
127+
dice_faces_rows = []
128+
for row_idx in range(DIE_HEIGHT):
129+
row_components = []
130+
for die in dice_faces:
131+
row_components.append(die[row_idx])
132+
row_string = DIE_FACE_SEPARATOR.join(row_components)
133+
dice_faces_rows.append(row_string)
134+
return dice_faces_rows
135+
136+
137+
# ~~~ App's main code block ~~~
138+
# 1. Get and validate user's input
139+
num_dice_input = input("How many dice do you want to roll? [1-6] ")
140+
num_dice = parse_input(num_dice_input)
141+
# 2. Roll the dice
142+
roll_results = roll_dice(num_dice)
143+
# 3. Generate the ASCII diagram of dice faces
144+
dice_face_diagram = generate_dice_faces_diagram(roll_results)
145+
# 4. Display the diagram
146+
print(f"\n{dice_face_diagram}")
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
def parse_input(input_string):
2+
"""Return `input_string` as an integer between 1 and 6.
3+
4+
Check if `input_string` is an integer number between 1 and 6.
5+
If so, return an integer with the same value. Otherwise, tell
6+
the user to enter a valid number and quit the program.
7+
"""
8+
if input_string.strip() in {"1", "2", "3", "4", "5", "6"}:
9+
return int(input_string)
10+
else:
11+
print("Please enter a number from 1 to 6.")
12+
raise SystemExit(1)
13+
14+
15+
# ~~~ App's main code block ~~~
16+
# 1. Get and validate user's input
17+
num_dice_input = input("How many dice do you want to roll? [1-6] ")
18+
num_dice = parse_input(num_dice_input)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import random
2+
3+
4+
def parse_input(input_string):
5+
"""Return `input_string` as an integer between 1 and 6.
6+
7+
Check if `input_string` is an integer number between 1 and 6.
8+
If so, return an integer with the same value. Otherwise, tell
9+
the user to enter a valid number and quit the program.
10+
"""
11+
if input_string.strip() in {"1", "2", "3", "4", "5", "6"}:
12+
return int(input_string)
13+
else:
14+
print("Please enter a number from 1 to 6.")
15+
raise SystemExit(1)
16+
17+
18+
def roll_dice(num_dice):
19+
"""Return a list of integers with length `num_dice`.
20+
21+
Each integer in the returned list is a random number between
22+
1 and 6, inclusive.
23+
"""
24+
roll_results = []
25+
for _ in range(num_dice):
26+
roll = random.randint(1, 6)
27+
roll_results.append(roll)
28+
return roll_results
29+
30+
31+
# ~~~ App's main code block ~~~
32+
# 1. Get and validate user's input
33+
num_dice_input = input("How many dice do you want to roll? [1-6] ")
34+
num_dice = parse_input(num_dice_input)
35+
# 2. Roll the dice
36+
roll_results = roll_dice(num_dice)
37+
38+
print(roll_results) # Remove this line after testing the app
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import random
2+
3+
DICE_ART = {
4+
1: (
5+
"┌─────────┐",
6+
"│ │",
7+
"│ ● │",
8+
"│ │",
9+
"└─────────┘",
10+
),
11+
2: (
12+
"┌─────────┐",
13+
"│ ● │",
14+
"│ │",
15+
"│ ● │",
16+
"└─────────┘",
17+
),
18+
3: (
19+
"┌─────────┐",
20+
"│ ● │",
21+
"│ ● │",
22+
"│ ● │",
23+
"└─────────┘",
24+
),
25+
4: (
26+
"┌─────────┐",
27+
"│ ● ● │",
28+
"│ │",
29+
"│ ● ● │",
30+
"└─────────┘",
31+
),
32+
5: (
33+
"┌─────────┐",
34+
"│ ● ● │",
35+
"│ ● │",
36+
"│ ● ● │",
37+
"└─────────┘",
38+
),
39+
6: (
40+
"┌─────────┐",
41+
"│ ● ● │",
42+
"│ ● ● │",
43+
"│ ● ● │",
44+
"└─────────┘",
45+
),
46+
}
47+
DIE_HEIGHT = len(DICE_ART[1])
48+
DIE_WIDTH = len(DICE_ART[1][0])
49+
DIE_FACE_SEPARATOR = " "
50+
51+
52+
def parse_input(input_string):
53+
"""Return `input_string` as an integer between 1 and 6.
54+
55+
Check if `input_string` is an integer number between 1 and 6.
56+
If so, return an integer with the same value. Otherwise, tell
57+
the user to enter a valid number and quit the program.
58+
"""
59+
if input_string.strip() in {"1", "2", "3", "4", "5", "6"}:
60+
return int(input_string)
61+
else:
62+
print("Please enter a number from 1 to 6.")
63+
raise SystemExit(1)
64+
65+
66+
def roll_dice(num_dice):
67+
"""Return a list of integers with length `num_dice`.
68+
69+
Each integer in the returned list is a random number between
70+
1 and 6, inclusive.
71+
"""
72+
roll_results = []
73+
for _ in range(num_dice):
74+
roll = random.randint(1, 6)
75+
roll_results.append(roll)
76+
return roll_results
77+
78+
79+
def generate_dice_faces_diagram(dice_values):
80+
"""Return an ASCII diagram of dice faces from `dice_values`.
81+
82+
The string returned contains an ASCII representation of each die.
83+
For example, if `dice_values = [4, 1, 3, 2]` then the string
84+
returned looks like this:
85+
86+
~~~~~~~~~~~~~~~~~~~ RESULTS ~~~~~~~~~~~~~~~~~~~
87+
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
88+
│ ● ● │ │ │ │ ● │ │ ● │
89+
│ │ │ ● │ │ ● │ │ │
90+
│ ● ● │ │ │ │ ● │ │ ● │
91+
└─────────┘ └─────────┘ └─────────┘ └─────────┘
92+
"""
93+
# Generate a list of dice faces from DICE_ART
94+
dice_faces = []
95+
for value in dice_values:
96+
dice_faces.append(DICE_ART[value])
97+
98+
# Generate a list containing the dice faces rows
99+
dice_faces_rows = []
100+
for row_idx in range(DIE_HEIGHT):
101+
row_components = []
102+
for die in dice_faces:
103+
row_components.append(die[row_idx])
104+
row_string = DIE_FACE_SEPARATOR.join(row_components)
105+
dice_faces_rows.append(row_string)
106+
107+
# Generate header with the word "RESULTS" centered
108+
width = len(dice_faces_rows[0])
109+
diagram_header = " RESULTS ".center(width, "~")
110+
111+
dice_faces_diagram = "\n".join([diagram_header] + dice_faces_rows)
112+
return dice_faces_diagram
113+
114+
115+
# ~~~ App's main code block ~~~
116+
# 1. Get and validate user's input
117+
num_dice_input = input("How many dice do you want to roll? [1-6] ")
118+
num_dice = parse_input(num_dice_input)
119+
# 2. Roll the dice
120+
roll_results = roll_dice(num_dice)
121+
# 3. Generate the ASCII diagram of dice faces
122+
dice_face_diagram = generate_dice_faces_diagram(roll_results)
123+
# 4. Display the diagram
124+
print(f"\n{dice_face_diagram}")

0 commit comments

Comments
 (0)