Skip to content

Commit

Permalink
Merge branch 'main' into start-page
Browse files Browse the repository at this point in the history
  • Loading branch information
Felienne authored Oct 1, 2023
2 parents 90a42d7 + 693a4bb commit d706100
Show file tree
Hide file tree
Showing 269 changed files with 10,341 additions and 8,569 deletions.
7 changes: 4 additions & 3 deletions .run/Python tests in test_level.run.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Python tests in test_level" type="tests" factoryName="Autodetect" nameIsGenerated="true">
<module name="hedyorg" />
<module name="hedy" />
<option name="INTERPRETER_OPTIONS" value="" />
<option name="PARENT_ENVS" value="true" />
<option name="SDK_HOME" value="" />
<option name="SDK_HOME" value="$PROJECT_DIR$/venv/bin/python" />
<option name="SDK_NAME" value="Python 3.9 (hedy)" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="IS_MODULE_SDK" value="true" />
<option name="IS_MODULE_SDK" value="false" />
<option name="ADD_CONTENT_ROOTS" value="true" />
<option name="ADD_SOURCE_ROOTS" value="true" />
<option name="_new_additionalArguments" value="&quot;&quot;" />
Expand Down
Binary file modified all_snippet_hashes.pkl
Binary file not shown.
69 changes: 42 additions & 27 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,13 +551,15 @@ 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 transpile_result.commands
except BaseException:
pass

try:
if username and not body.get('tutorial') and ACHIEVEMENTS.verify_run_achievements(
username, code, level, response):
username, code, level, response, transpile_result.commands):
response['achievements'] = ACHIEVEMENTS.get_earned_achievements()
except Exception as E:
print(f"error determining achievements for {code} with {E}")
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 @@ -747,6 +746,7 @@ def translate_error(code, arguments, keyword_lang):
'allowed_types',
'invalid_type',
'invalid_type_2',
'offending_keyword',
'character_found',
'concept',
'tip',
Expand All @@ -763,6 +763,7 @@ def translate_error(code, arguments, keyword_lang):
'guessed_command',
'invalid_argument',
'invalid_argument_2',
'offending_keyword',
'variable',
'invalid_value',
'print',
Expand Down Expand Up @@ -1606,6 +1607,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 @@ -1675,12 +1681,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 @@ -2278,6 +2288,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()
2 changes: 1 addition & 1 deletion content/achievements/ca.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ achievements:
title: Full House
text: "Have a class with more than 20 students\n"
well_begun_is_half_done:
title: Ben començat està mig fet
title: Un bon començament és fet a mitges
text: "Acaba el tutorial de Hedy\n"
adventure_is_worthwhile:
title: L'aventura val la pena
Expand Down
12 changes: 6 additions & 6 deletions content/achievements/es.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ achievements:
text: |
Ejecuta un programa exitoso después de un error
did_you_say_please:
title: "Lo has pedido por favor?"
title: "¿Lo has pedido por favor?"
text: |
Crea un programa con el comando 'ask'
error_or_empty:
Expand All @@ -32,7 +32,7 @@ achievements:
text: |
Comparte un programa guardado
do_you_have_copy:
title: "Tienes una copia?"
title: "¿Tienes una copia?"
text: |
Elimina un programa guardado
epic_education:
Expand Down Expand Up @@ -128,7 +128,7 @@ achievements:
text: |
Finaliza el tutorial para profesores
ready_set_education:
title: "Preparados, Listos, Educación!"
title: "¡Preparados, Listos, Educación!"
text: |
Crear una clase
end_of_semester:
Expand All @@ -152,15 +152,15 @@ achievements:
text: |
Retirar a un alumno de una clase
hedy-ious:
title: "Hedy-ious"
title: "Hedy-cioso"
text: |
Imprimir 10 veces la misma cadena sin utilizar un bucle
talk-talk-talk:
title: "Blablabla"
text: |
Crear un programa con al menos 5 palabras clave
hedy_hacking:
title: "Hedy Hacking"
title: "Tramposo Hedy"
text: |
Crear un tiempo de espera debido a que su programa se ejecuta demasiado tiempo
hedy_honor:
Expand All @@ -172,7 +172,7 @@ achievements:
text: |
Intenta ejecutar un programa defectuoso 3 veces seguidas
watch_out:
title: "Cuidado!"
title: "¡Cuidado!"
text: |
Crear un programa que dé como resultado un aviso (no vacío)
one_for_money:
Expand Down
40 changes: 30 additions & 10 deletions content/adventures/ar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,9 @@ adventures:
```
{print} حقيبة الظهر خاصته أصبحت ثقيلة للغاية.
{print} كان داخلها زجاجة ماء و مصباح و طعام.
المحتويات هي ماء، مصباح، طعام
المحتويات {is} ماء، مصباح، طعام
الزائد {is} {ask} ما الذي عليه التخلص منه؟
{remove} الزائد {from} المحتويات
{remove} الزائد {from} المحتويات
```
start_code: "{print} قصتك"
13:
Expand Down 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 @@ -949,13 +945,28 @@ adventures:
for_command:
levels:
11:
example_code: "```\n{for} counter {in} {range} 1 {to} 5\n {print} counter\n```\n"
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."
start_code: |-
{for} counter {in} {range} 1 {to} 10
{print} counter
{print} 'Ready or not. Here I come!'
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.
We 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.
Try the example to see what happens! In this level again, you will need to use indentations in lines below the `{for}` statements.
example_code: |
```
{for} counter {in} {range} 1 {to} 10
{print} counter
{print} 'Ready or not. Here I come!'
```
10:
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 +985,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
Loading

0 comments on commit d706100

Please sign in to comment.