Skip to content

Commit 00962e2

Browse files
committed
Here is the starter program / code for this course. Let's see if we can create this app and record the videos this weekend!
1 parent 1276f7b commit 00962e2

File tree

17 files changed

+816
-0
lines changed

17 files changed

+816
-0
lines changed

src/placeholder.md

Whitespace-only changes.

src/snake_bnb/reqjuirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pymongo
2+
mongoengine
3+
tqdm
4+
colorama
5+
python-dateutil

src/snake_bnb/src/data/readme.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
We'll put some data things in this folder when we start the course.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
active_account = None
2+
3+
4+
def reload_account():
5+
global active_account
6+
if not active_account:
7+
return
8+
9+
# TODO: pull owner account from the database.
10+
pass
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import uuid
2+
from typing import Callable, Any
3+
4+
5+
class switch:
6+
"""
7+
python-switch is a module-level implementation of the switch statement for Python.
8+
See https://github.com/mikeckennedy/python-switch for full details.
9+
Copyright Michael Kennedy (https://twitter.com/mkennedy)
10+
"""
11+
__no_result = uuid.uuid4()
12+
__default = uuid.uuid4()
13+
14+
def __init__(self, value):
15+
self.value = value
16+
self.cases = set()
17+
self._found = False
18+
self.__result = switch.__no_result
19+
self._falling_through = False
20+
self._func_stack = []
21+
22+
def default(self, func: Callable[[], Any]):
23+
"""
24+
Use as option final statement in switch block.
25+
26+
with switch(val) as s:
27+
s.case(...)
28+
s.case(...)
29+
s.default(function)
30+
31+
:param func: Any callable taking no parameters to be executed if this (default) case matches.
32+
:return: None
33+
"""
34+
self.case(switch.__default, func)
35+
36+
def case(self, key, func: Callable[[], Any], fallthrough=False):
37+
"""
38+
Specify a case for the switch block:
39+
40+
with switch(val) as s:
41+
s.case('a', function)
42+
s.case('b', function, fallthrough=True)
43+
s.default(function)
44+
45+
:param key: Key for the case test (if this is a list or range, the items will each be added as a case)
46+
:param func: Any callable taking no parameters to be executed if this case matches.
47+
:param fallthrough: Optionally fall through to the subsequent case (defaults to False)
48+
:return:
49+
"""
50+
if fallthrough is not None:
51+
if self._falling_through:
52+
self._func_stack.append(func)
53+
if not fallthrough:
54+
self._falling_through = False
55+
56+
if isinstance(key, list) or isinstance(key, range):
57+
found = False
58+
for i in key:
59+
if self.case(i, func, fallthrough=None):
60+
found = True
61+
if fallthrough is not None:
62+
self._falling_through = fallthrough
63+
return found
64+
65+
if key in self.cases:
66+
raise ValueError("Duplicate case: {}".format(key))
67+
if not func:
68+
raise ValueError("Action for case cannot be None.")
69+
if not callable(func):
70+
raise ValueError("Func must be callable.")
71+
72+
self.cases.add(key)
73+
if key == self.value or not self._found and key == self.__default:
74+
self._func_stack.append(func)
75+
self._found = True
76+
if fallthrough is not None:
77+
self._falling_through = fallthrough
78+
return True
79+
80+
def __enter__(self):
81+
return self
82+
83+
def __exit__(self, exc_type, exc_val, exc_tb):
84+
if exc_val:
85+
raise exc_val
86+
87+
if not self._func_stack:
88+
raise Exception("Value does not match any case and there "
89+
"is no default case: value {}".format(self.value))
90+
91+
for func in self._func_stack:
92+
# noinspection PyCallingNonCallable
93+
self.__result = func()
94+
95+
@property
96+
def result(self):
97+
if self.__result == switch.__no_result:
98+
raise Exception("No result has been computed (did you access "
99+
"switch.result inside the with block?)")
100+
101+
return self.__result
102+
103+
104+
def closed_range(start: int, stop: int, step=1) -> range:
105+
if start >= stop:
106+
raise ValueError("Start must be less than stop.")
107+
108+
return range(start, stop + step, step)

src/snake_bnb/src/program.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from colorama import Fore
2+
import program_guests
3+
import program_hosts
4+
5+
6+
def main():
7+
# TODO: Setup mongoengine global values
8+
9+
print_header()
10+
11+
try:
12+
while True:
13+
if find_user_intent() == 'book':
14+
program_guests.run()
15+
else:
16+
program_hosts.run()
17+
except KeyboardInterrupt:
18+
return
19+
20+
21+
def print_header():
22+
snake = \
23+
"""
24+
~8I?? OM
25+
M..I?Z 7O?M
26+
? ?8 ?I8
27+
MOM???I?ZO??IZ
28+
M:??O??????MII
29+
OIIII$NI7??I$
30+
IIID?IIZ
31+
+$ ,IM ,~7??I7$
32+
I? MM ?:::?7$
33+
?? 7,::?778+=~+??8
34+
??Z ?,:,:I7$I??????+~~+
35+
??D N==7,::,I77??????????=~$
36+
~??? I~~I?,::,77$Z?????????????
37+
???+~M $+~+???? :::II7$II777II??????N
38+
OI??????????I$$M=,:+7??I$7I???????????
39+
N$$$ZDI =++:$???????????II78
40+
=~~:~~7II777$$Z
41+
~ZMM~ """
42+
43+
print(Fore.WHITE + '**************** SNAKE BnB ****************')
44+
print(Fore.GREEN + snake)
45+
print(Fore.WHITE + '*********************************************')
46+
print()
47+
print("Welcome to Snake BnB!")
48+
print("Why are you here?")
49+
print()
50+
51+
52+
def find_user_intent():
53+
print("[g] Book a cage for your snake")
54+
print("[h] Offer extra cage space")
55+
print()
56+
choice = input("Are you a [g]uest or [h]ost? ")
57+
if choice == 'h':
58+
return 'offer'
59+
60+
return 'book'
61+
62+
63+
if __name__ == '__main__':
64+
main()

src/snake_bnb/src/program_guests.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
from infrastructure.switchlang import switch
2+
import program_hosts as hosts
3+
from program_hosts import success_msg, error_msg
4+
import infrastructure.state as state
5+
6+
7+
def run():
8+
print(' ****************** Welcome guest **************** ')
9+
print()
10+
11+
show_commands()
12+
13+
while True:
14+
action = hosts.get_action()
15+
16+
with switch(action) as s:
17+
s.case('c', hosts.create_account)
18+
s.case('l', hosts.log_into_account)
19+
20+
s.case('a', add_a_snake)
21+
s.case('y', view_your_snakes)
22+
s.case('b', book_a_cage)
23+
s.case('v', view_bookings)
24+
s.case('m', lambda: 'change_mode')
25+
26+
s.case('?', show_commands)
27+
s.case('', lambda: None)
28+
s.case(['x', 'bye', 'exit', 'exit()'], hosts.exit_app)
29+
30+
s.default(hosts.unknown_command)
31+
32+
state.reload_account()
33+
34+
if action:
35+
print()
36+
37+
if s.result == 'change_mode':
38+
return
39+
40+
41+
def show_commands():
42+
print('What action would you like to take:')
43+
print('[C]reate an account')
44+
print('[L]ogin to your account')
45+
print('[B]ook a cage')
46+
print('[A]dd a snake')
47+
print('View [y]our snakes')
48+
print('[V]iew your bookings')
49+
print('[M]ain menu')
50+
print('e[X]it app')
51+
print('[?] Help (this info)')
52+
print()
53+
54+
55+
def add_a_snake():
56+
print(' ****************** Add a snake **************** ')
57+
# TODO: Require an account
58+
# TODO: Get snake info from user
59+
# TODO: Create the snake in the DB.
60+
61+
print(" -------- NOT IMPLEMENTED -------- ")
62+
63+
64+
def view_your_snakes():
65+
print(' ****************** Your snakes **************** ')
66+
67+
# TODO: Require an account
68+
# TODO: Get snakes from DB, show details list
69+
70+
print(" -------- NOT IMPLEMENTED -------- ")
71+
72+
73+
def book_a_cage():
74+
print(' ****************** Book a cage **************** ')
75+
# TODO: Require an account
76+
# TODO: Verify they have a snake
77+
# TODO: Get dates and select snake
78+
# TODO: Find cages available across date range
79+
# TODO: Let user select cage to book.
80+
81+
print(" -------- NOT IMPLEMENTED -------- ")
82+
83+
84+
def view_bookings():
85+
print(' ****************** Your bookings **************** ')
86+
# TODO: Require an account
87+
# TODO: List booking info along with snake info
88+
89+
print(" -------- NOT IMPLEMENTED -------- ")

0 commit comments

Comments
 (0)