Don't use a try/except clause for checking for a key/value pair and providing a default. Python has .get
builtin for this purpose:
# no
try:
session['activities_arr']
except:
session['activities_arr'] = []
# yes
activities_array = session.get('activities_arr', [])
Also use the .format
method for formating strings:
# no
'You earned ' + str(farm_capital) + ' from the farm! ' + date
# yes
'You earned {} from the farm! {}'.format(farm_capital, date)
You're repeating yourself a lot in your server.py. If you ever see yourself repeating the same code more than once, stop and see if there's a different way you can do it without repeating yourself. You also have a many-branched if/else. If you ever start to have more than a few branches in an if/else, see if you can do some kind of mapping instead. Your function is also over 50 lines long, which should be a red flag. Functions should only do One Thing.
Also, comment your code more, may seem unnecessary/annoying but get in the habit, you'll appreciate it later when you start building large projects because you won't be able to remember why you wrote old code.
Don't just copy paste this code into your repo. Read it carefully, and see how it is different from your code, and how it addresses each concern mentioned above. If you don't understand anything, even if it seems like a little thing, please ask me about it.
def generate_number(action):
"""
Returns a random number between 10 and 20. If the action is a 'casino',
the number may be negative instead
"""
random_number = random.randrange(10, 20)
if action == 'casino' and random.randint(0, 1):
return -1 * random_number
else:
return random_number
def build_message(action, capital):
""" Build message for activities_arr """
date = datetime.now().strftime('(%Y/%m/%d %r)')
earned_lost = 'earned' if capital > 0 else 'lost'
if action == 'casino' and capital > 0:
optional_message = 'BALL OUT! '
elif capital < 0:
optional_message = 'HANG YOUR HEAD IN SHAME! '
else:
optional_message = ''
return 'You {} {} from the {}! {} {}'.format(earned_lost,
capital,
action,
optional_message,
date)
@app.route('/')
def init_root():
if not session.get('gold'):
session['gold'] = 0
return render_template('index.html')
@app.route('/money_machine', methods=['POST'])
def process():
""" Calculate new gold amount, add message to message array """
activities_array = session.get('activities_arr', [])
action = request.form.get('action')
capital = generate_number(action)
message = build_message(action, capital)
activities_array.insert(0, message)
session['gold'] += capital
session['activities_arr'] = activities_array
return redirect('/')
Use soft tabs, set your sublime text default to be soft
(10, 20)
not (10,20)
When you have functions that aren't class methods, put two lines between them:
# no
return render_template('index.html')
@app.route('/money_machine', methods=['POST'])
# yes
return render_template('index.html')
@app.route('/money_machine', methods=['POST'])
Also, do you have GitGutter installed on your sublime text yet?
Yes you're right about how
.format
worksas to
.get
:y = x.get('happy', 5)
is the same as:So get takes 2 arguments, the first is the key to the dictionary, and the second is a default value in case the dictionary doesn't have that key. Further reading on format and get
The python docs are your new home for the next couple decades. Get cozy
GitGutter