Skip to content

Commit

Permalink
Merge branch 'main' into fix-race-condish
Browse files Browse the repository at this point in the history
  • Loading branch information
jpelay authored Sep 26, 2023
2 parents f78ef74 + f9bb172 commit 11051e1
Show file tree
Hide file tree
Showing 251 changed files with 8,278 additions and 6,975 deletions.
Binary file modified all_snippet_hashes.pkl
Binary file not shown.
65 changes: 39 additions & 26 deletions app.py
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,7 @@ def echo_session_vars_main():


@app.route('/parse', methods=['POST'])
@querylog.timed_as('parse_handler')
def parse():
body = request.json
if not body:
Expand All @@ -483,17 +484,13 @@ def parse():
return "body.level must be a string", 400
if 'adventure_name' in body and not isinstance(body['adventure_name'], str):
return "if present, body.adventure_name must be a string", 400
# TODO: Once we figure out whats wrong with the skip faulty code, we need to reinstantiate this
# if 'skip_faulty' not in body:
# return "body.skip_faulty must be a boolean", 400

error_check = False
if 'error_check' in body:
error_check = True

code = body['code']
level = int(body['level'])
skip_faulty = False # bool(body['skip_faulty'])

# Language should come principally from the request body,
# but we'll fall back to browser default if it's missing for whatever
Expand All @@ -514,7 +511,7 @@ def parse():
keyword_lang = current_keyword_language()["lang"]
with querylog.log_time('transpile'):
try:
transpile_result = transpile_add_stats(code, level, lang, skip_faulty)
transpile_result = transpile_add_stats(code, level, lang)
if username and not body.get('tutorial'):
DATABASE.increase_user_run_count(username)
ACHIEVEMENTS.increase_count("run")
Expand All @@ -534,18 +531,18 @@ def parse():

try:
response['Code'] = transpile_result.code
# source_map_result = transpile_result.source_map.get_result()

# for i, mapping in source_map_result.items():
# if mapping['error'] is not None:
# source_map_result[i]['error'] = translate_error(
# source_map_result[i]['error'].error_code,
# source_map_result[i]['error'].arguments,
# keyword_lang
# )

# response['source_map'] = source_map_result
response['source_map'] = transpile_result.source_map.get_result()
source_map_result = transpile_result.source_map.get_result()

for i, mapping in source_map_result.items():
if mapping['error'] is not None:
source_map_result[i]['error'] = translate_error(
source_map_result[i]['error'].error_code,
source_map_result[i]['error'].arguments,
keyword_lang
)

response['source_map'] = source_map_result

if transpile_result.has_pygame:
response['has_pygame'] = True

Expand All @@ -554,10 +551,12 @@ def parse():
except Exception:
pass

try:
response['has_sleep'] = 'sleep' in hedy.all_commands(code, level, lang)
except BaseException:
pass
with querylog.log_time('detect_sleep'):
try:
response['has_sleep'] = 'sleep' in hedy.all_commands(code, level, lang)
except BaseException:
pass

try:
if username and not body.get('tutorial') and ACHIEVEMENTS.verify_run_achievements(
username, code, level, response):
Expand Down Expand Up @@ -713,11 +712,11 @@ def remove_file(response):
return send_file("machine_files/" + filename + "." + extension, as_attachment=True)


def transpile_add_stats(code, level, lang_, skip_faulty):
def transpile_add_stats(code, level, lang_):
username = current_user()['username'] or None
number_of_lines = code.count('\n')
try:
result = hedy.transpile(code, level, lang_, skip_faulty)
result = hedy.transpile(code, level, lang_)
statistics.add(
username, lambda id_: DATABASE.add_program_stats(id_, level, number_of_lines, None))
return result
Expand Down Expand Up @@ -1607,6 +1606,11 @@ def main_page():
current_page='start', content=content)


@app.route('/subscribe')
def subscribe():
return render_template('subscribe.html', current_page='subscribe')


@app.route('/learn-more')
def learn_more():
learn_more_translations = hedyweb.PageTranslations('learn-more').get_page_translations(g.lang)
Expand Down Expand Up @@ -1669,12 +1673,16 @@ def explore():
achievement = ACHIEVEMENTS.add_single_achievement(
current_user()['username'], "indiana_jones")

programs = normalize_public_programs(DATABASE.get_public_programs(
programs = DATABASE.get_public_programs(
limit=40,
level_filter=level,
language_filter=language,
adventure_filter=adventure))
favourite_programs = normalize_public_programs(DATABASE.get_hedy_choices())
adventure_filter=adventure)
favourite_programs = DATABASE.get_hedy_choices()

# Do 'normalize_public_programs' on both sets at once, to save database calls
normalized = normalize_public_programs(list(programs) + list(favourite_programs.records))
programs, favourite_programs = split_at(len(programs), normalized)

adventures_names = hedy_content.Adventures(session['lang']).get_adventure_names()

Expand Down Expand Up @@ -2272,6 +2280,11 @@ def analyze_memory_snapshot(start_snapshot, end_snapshot):
print("Total allocated size: %.1f KiB" % (total / 1024))


def split_at(n, xs):
"""Split a collection at an index."""
return xs[:n], xs[n:]


if __name__ == '__main__':
# Start the server on a developer machine. Flask is initialized in DEBUG mode, so it
# hot-reloads files. We also flip our own internal "debug mode" flag to True, so our
Expand Down
51 changes: 29 additions & 22 deletions build-tools/heroku/generate-static-babel-content
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,37 @@ from os import path
import os
import iso3166
from babel import Locale, languages, UnknownLocaleError
import json


def main():
root_dir = path.abspath(path.join(path.dirname(__file__), '..', '..'))
filename = path.join(root_dir, 'static_babel_content.py')

translated_languages = [lang for lang in os.listdir(path.join(root_dir, 'translations')) if path.isdir(
path.join(root_dir, 'translations', lang, 'LC_MESSAGES'))]

with open(filename, 'w', encoding='utf-8') as f:
f.write('# coding=utf-8\n')
f.write('# flake8: noqa\n')
f.write('###################################################\n')
f.write('#\n')
f.write('# !!! THIS FILE HAS BEEN GENERATED. DO NOT EDIT !!!\n')
f.write('#\n')
f.write('# Run build-tools/heroku/generate-static-babel-content to regenerate.\n')
f.write('#\n')
f.write('###################################################\n')
f.write('\n')
f.write('COUNTRIES = %r\n' % countries())
f.write('LANGUAGE_NAMES = %r\n' % language_names(translated_languages))
f.write('TEXT_DIRECTIONS = %r\n' % text_directions(translated_languages))
print('Wrote', filename)
root_dir = path.abspath(path.join(path.dirname(__file__), "..", ".."))
filename = path.join(root_dir, "static_babel_content.json")

translated_languages = [
lang
for lang in os.listdir(path.join(root_dir, "translations"))
if path.isdir(path.join(root_dir, "translations", lang, "LC_MESSAGES"))
]

with open(filename, "w", encoding="utf-8") as f:
json.dump(
{
"000 __ help": (
"!!! THIS FILE HAS BEEN GENERATED. DO NOT EDIT !!! "
"Run build-tools/heroku/generate-static-babel-content to regenerate.",
),
"COUNTRIES": countries(),
"LANGUAGE_NAMES": language_names(translated_languages),
"TEXT_DIRECTIONS": text_directions(translated_languages),
},
f,
sort_keys=True,
indent=4,
)
f.write("\n")

print("Wrote", filename)


def countries():
Expand Down Expand Up @@ -86,5 +93,5 @@ def locale(lang):
pass


if __name__ == '__main__':
if __name__ == "__main__":
main()
19 changes: 14 additions & 5 deletions content/adventures/ar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -845,10 +845,6 @@ adventures:
example_code: "```\n{print} Hi there, programmer!\n{print} Welcome to Hedy!\n```\n"
example_code_2: "```\n_ Hello!\n```\n"
start_code: "{print} Welcome to Hedy!\n"
17:
start_code: "{for} i {in} {range} 1 {to} 10:\n {print} i\n{print} 'Ready or not, here I come!'"
story_text: "Now we are going to change indentation a little bit. Every time that we need an indentation, we need `:` at the line before the indentation.\n"
example_code: "```\n{for} i {in} {range} 1 {to} 10:\n {print} i\n{print} 'Ready or not, here I come!'\n```\n"
18:
start_code: "name = 'Hedy'\n{print}('My name is ', name)"
story_text: "We arrived at real Python code! That means we need to use parentheses with `{print}` and `{range}` from now on.\nIt also means you can use Hedy code from this level in any Python environment as long as you use the English commands. If you haven't until now, you can switch the toggle in the commands menu to do so."
Expand All @@ -870,7 +866,7 @@ adventures:
1:
story_text: "## The ask command\nNow that you can use the `{print}` command, you are ready to learn the next command: `{ask}`. With the `{ask}` command, you can ask a question. Check it out:\n"
example_code: "```\n{print} Hello!\n{ask} What is your name?\n```\n"
story_text_2: "## The echo command\nIf you want the computer to repeat the answer back to you, you can use the `{echo}` command. Mind that the answer is echoed back at the end of the sentence, so it this example after hello.\n"
story_text_2: "## The echo command\nIf you want the computer to repeat the answer, you can use the `{echo}` command. The answer will then be echoed back at the end of the sentence, so in this example after hello.\n"
story_text_3: "### Exercise\nTry out the `{ask}` and `{echo}` commands. Firstly, fill in the blanks to make this program work.\nThen ask 2 more questions using the `{ask}` command, after each `{ask}` use an `{echo}` to print the answer on the screen.\n"
example_code_2: "```\n{print} Hello!\n{ask} What is your name?\n{echo} hello\n```\n"
example_code_3: "```\n_ How are you doing?\n_\n```\n"
Expand Down Expand Up @@ -956,6 +952,10 @@ adventures:
start_code: "animals {is} dog, cat, blobfish\n{for} animal {in} animals\n {print} 'I love ' animal"
story_text: "## For\nIn this level we learn a new code called `{for}`. With `{for}` you can make a list and use all elements.\n`{for}` creates a block, like `{repeat}` and `{if}` so all lines in the block need to start with 4 spaces."
example_code: "```\nanimals {is} dog, cat, blobfish\n{for} animal {in} animals\n {print} 'I love ' animal\n```\n"
17:
start_code: "{for} i {in} {range} 1 {to} 10:\n {print} i\n{print} 'Ready or not, here I come!'"
story_text: "Now we are going to change indentation a little bit. Every time that we need an indentation, we need `:` at the line before the indentation.\n"
example_code: "```\n{for} i {in} {range} 1 {to} 10:\n {print} i\n{print} 'Ready or not, here I come!'\n```\n"
name: "{for}"
description: for command
default_save_name: for
Expand All @@ -974,6 +974,15 @@ adventures:
start_code: "{print} 'decimal numbers now need to use a dot'\n{print} 2.5 + 2.5"
story_text: "**Decimal numbers**\nSo far, Hedy did not allow for decimal numbers like 1.5, but now we do allow that. Note that computers use the `.` for decimal numbers."
example_code: "```\n{print} 'Two and a half plus two and a half is...'\n{print} 2.5 + 2.5\n```\n"
story_text_2: |-
**Maths with words**
In this level you can also do addition with words like this:
example_code_2: |
```
a = 'Hello '
b = 'world!'
{print} a + b
```
rock_2:
default_save_name: rock_2
levels:
Expand Down
19 changes: 14 additions & 5 deletions content/adventures/bg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1660,10 +1660,6 @@ adventures:
example_code: "```\n{print} Hi there, programmer!\n{print} Welcome to Hedy!\n```\n"
example_code_2: "```\n_ Hello!\n```\n"
start_code: "{print} Welcome to Hedy!\n"
17:
start_code: "{for} i {in} {range} 1 {to} 10:\n {print} i\n{print} 'Ready or not, here I come!'"
story_text: "Now we are going to change indentation a little bit. Every time that we need an indentation, we need `:` at the line before the indentation.\n"
example_code: "```\n{for} i {in} {range} 1 {to} 10:\n {print} i\n{print} 'Ready or not, here I come!'\n```\n"
18:
start_code: "name = 'Hedy'\n{print}('My name is ', name)"
story_text: "We arrived at real Python code! That means we need to use parentheses with `{print}` and `{range}` from now on.\nIt also means you can use Hedy code from this level in any Python environment as long as you use the English commands. If you haven't until now, you can switch the toggle in the commands menu to do so."
Expand Down Expand Up @@ -1767,7 +1763,7 @@ adventures:
1:
story_text: "## The ask command\nNow that you can use the `{print}` command, you are ready to learn the next command: `{ask}`. With the `{ask}` command, you can ask a question. Check it out:\n"
example_code: "```\n{print} Hello!\n{ask} What is your name?\n```\n"
story_text_2: "## The echo command\nIf you want the computer to repeat the answer back to you, you can use the `{echo}` command. Mind that the answer is echoed back at the end of the sentence, so it this example after hello.\n"
story_text_2: "## The echo command\nIf you want the computer to repeat the answer, you can use the `{echo}` command. The answer will then be echoed back at the end of the sentence, so in this example after hello.\n"
story_text_3: "### Exercise\nTry out the `{ask}` and `{echo}` commands. Firstly, fill in the blanks to make this program work.\nThen ask 2 more questions using the `{ask}` command, after each `{ask}` use an `{echo}` to print the answer on the screen.\n"
example_code_2: "```\n{print} Hello!\n{ask} What is your name?\n{echo} hello\n```\n"
example_code_3: "```\n_ How are you doing?\n_\n```\n"
Expand Down Expand Up @@ -1870,6 +1866,10 @@ adventures:
start_code: "{for} counter {in} {range} 1 {to} 5\n {print} counter"
story_text: "In this level, we add a new form of the `{for}`. In earlier levels, we used `{for}` with a list, but we can also use `{for}` with numbers.\nWe do that by adding a variable name, followed by `{in}` `{range}`. We then write the number to start at, `{to}` and the number to end at.\n\nTry the example to see what happens! In this level again, you will need to use indentations in lines below the `{for}` statements."
example_code: "```\n{for} counter {in} {range} 1 {to} 5\n {print} counter\n```\n"
17:
start_code: "{for} i {in} {range} 1 {to} 10:\n {print} i\n{print} 'Ready or not, here I come!'"
story_text: "Now we are going to change indentation a little bit. Every time that we need an indentation, we need `:` at the line before the indentation.\n"
example_code: "```\n{for} i {in} {range} 1 {to} 10:\n {print} i\n{print} 'Ready or not, here I come!'\n```\n"
maths:
name: maths
description: Introducing maths
Expand All @@ -1885,6 +1885,15 @@ adventures:
start_code: "{print} 'decimal numbers now need to use a dot'\n{print} 2.5 + 2.5"
story_text: "**Decimal numbers**\nSo far, Hedy did not allow for decimal numbers like 1.5, but now we do allow that. Note that computers use the `.` for decimal numbers."
example_code: "```\n{print} 'Two and a half plus two and a half is...'\n{print} 2.5 + 2.5\n```\n"
story_text_2: |-
**Maths with words**
In this level you can also do addition with words like this:
example_code_2: |
```
a = 'Hello '
b = 'world!'
{print} a + b
```
and_or_command:
name: "{and} & {or}"
description: introducing and or
Expand Down
Loading

0 comments on commit 11051e1

Please sign in to comment.