Skip to content

Commit

Permalink
[LANGUAGE] Adds new exception to catch the use of at in level 16+ (h…
Browse files Browse the repository at this point in the history
…edyorg#3831)

**Description**
Fixes issue hedyorg#3800 so now if a student attempts to use 'at random' in either a print statement or an expression or just by itself (fruit at random), an informative message will tell them to use 'list_name[random]' instead. 



**How to test**

Added some test cases to test for "print fruits at random," "x = fruits at random," and "x is fruits at random"

**Checklist**
Done? Check if you have it all in place using this list:*
  
- [ ] Contains one of the PR categories in the name
- [ ] Describes changes in the format above
- [ ] Links to an existing issue or discussion 
- [ ] Has a "How to test" section

If you're unsure about any of these, don't hesitate to ask. We're here to help!
  • Loading branch information
reiades authored Feb 21, 2023
1 parent 7d03c76 commit 846ecaa
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 2 deletions.
3 changes: 2 additions & 1 deletion content/error-messages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,5 @@ gettext('number')
gettext('integer')
gettext('float')
gettext('list')
gettext('input')
gettext('input')
gettext('Invalid At Command')
8 changes: 8 additions & 0 deletions exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ def __init__(self, command, level, line_number):
line_number=line_number)


class InvalidAtCommandException(HedyException):
def __init__(self, command, level, line_number):
super().__init__('Invalid At Command',
command=command,
level=level,
line_number=line_number)


class IncompleteRepeatException(HedyException):
def __init__(self, command, level, line_number):
super().__init__('Incomplete Repeat',
Expand Down
11 changes: 10 additions & 1 deletion grammars/level16-Additions.lark
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
// adds list access with numbers and brackets
command:+= change_list_item
// TODO for tomorrow: this stills needs tests in level 16 for > and !=
command:+= change_list_item

?comparison_arg: var_access | text_in_quotes | NUMBER | list_access

?atom: NUMBER | _MINUS NUMBER | var_access | list_access | text_in_quotes
list_access: var_access _LEFT_SQUARE_BRACKET (INT | random | var_access) _RIGHT_SQUARE_BRACKET
change_list_item: var_access _LEFT_SQUARE_BRACKET (INT | var_access) _RIGHT_SQUARE_BRACKET _EQUALS (var_access | textwithoutspaces)
assign_list: var (_IS | _EQUALS) _LEFT_SQUARE_BRACKET ((quoted_text | INT) (_COMMA (quoted_text | INT))*)? _RIGHT_SQUARE_BRACKET

error_list_access_at: var_access _AT (INT | random)

_print_argument: (_SPACE | quoted_text | list_access | error_list_access_at | expression | print_expression)*
assign: var (_IS| _EQUALS) (list_access | error_list_access_at | atom | expression)
error_print_no_quotes: _PRINT (textwithoutspaces | list_access | error_list_access_at | var_access) (_SPACE (textwithoutspaces | list_access | var_access))* -> error_print_nq
sleep: _SLEEP (INT | list_access | error_list_access_at | var_access | expression)?
turtle: _FORWARD ((NUMBER | list_access | error_list_access_at | textwithoutspaces | expression))? -> forward | _TURN ((NUMBER | list_access | error_list_access_at | textwithoutspaces | expression))? -> turn | _COLOR ((black | blue | brown | gray | green | orange | pink | purple | red | white | yellow | list_access | error_list_access_at | textwithoutspaces))? -> color
5 changes: 5 additions & 0 deletions hedy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,9 @@ def error_text_no_print(self, meta, args):
error = InvalidInfo('lonely text', arguments=[str(args[0])], line=meta.line, column=meta.column)
return False, error, meta

def error_list_access_at(self, meta, args):
error = InvalidInfo('invalid at keyword', arguments=[str(args[0])], line=meta.line, column=meta.column)
return False, error, meta
# other rules are inherited from Filter


Expand Down Expand Up @@ -2867,6 +2870,8 @@ def is_program_valid(program_root, input_string, level, lang):
raise exceptions.UnsupportedFloatException(value=''.join(invalid_info.arguments))
elif invalid_info.error_type == 'lonely text':
raise exceptions.LonelyTextException(level=level, line_number=line)
elif invalid_info.error_type == 'invalid at keyword':
raise exceptions.InvalidAtCommandException(command='at', level=level, line_number=invalid_info.line)
else:
invalid_command = invalid_info.command
closest = closest_command(invalid_command, get_suggestions_for_language(lang, level))
Expand Down
3 changes: 3 additions & 0 deletions messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ msgstr ""
msgid "input"
msgstr ""

msgid "Invalid At Command"
msgstr ""

msgid "general"
msgstr ""

Expand Down
7 changes: 7 additions & 0 deletions tests/test_level/test_level_16.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,3 +616,10 @@ def test_if_pressed_with_list_and_for(self):
break""")

self.single_level_tester(code=code, expected=expected)

@parameterized.expand(['sleep', 'number is', 'print', 'forward', 'turn'])
def test_at_random_express(self, command):
code = textwrap.dedent(f"""\
numbers is [1, 2, 3]
{command} numbers at random""")
self.single_level_tester(code=code, exception=hedy.exceptions.InvalidAtCommandException)

0 comments on commit 846ecaa

Please sign in to comment.