Skip to content

Commit

Permalink
Basic fix for 745 (hedyorg#755)
Browse files Browse the repository at this point in the history
This updates the print code to always use f-string to allow for lists to be printed. That makes the tests easier to read and prevents errors. However, in a near future I will to implement a basic type system so we can tell kids they should not print a whole list cause why would you even at this stage. But at least this prevents ugly Python errors.
  • Loading branch information
Felienne authored Sep 15, 2021
1 parent 51ad9e7 commit 06ae4e3
Showing 6 changed files with 145 additions and 101 deletions.
51 changes: 42 additions & 9 deletions hedy.py
Original file line number Diff line number Diff line change
@@ -476,16 +476,23 @@ def turn(self, args):
else:
return "t.right(90)" #something else also defaults to right turn



def process_variable(name, lookup):
#processes a variable by hashing and escaping when needed
if name in lookup:
if hash_needed(name):
return hash_var(name)
else:
return name
return process_hash(name)
else:
return f"'{name}'"


def process_hash(name):
if hash_needed(name):
return hash_var(name)
else:
return name


class ConvertToPython_2(ConvertToPython_1):
def punctuation(self, args):
return ''.join([str(c) for c in args])
@@ -495,7 +502,7 @@ def var(self, args):
return hash_var(name)
# return "_" + name if name in reserved_words else name
def print(self, args):
all_arguments_converted = []
argument_string = ""
i = 0

for argument in args:
@@ -506,10 +513,21 @@ def print(self, args):
if i == len(args)-1 or args[i+1] in self.punctuation_symbols:
space = ''
else:
space = "+' '"
all_arguments_converted.append(process_variable(argument, self.lookup) + space)
space = " "

if argument in self.lookup:
#variables are placed in {} in the f string
argument_string += "{" + process_hash(argument) + "}"
argument_string += space
else:
#strings are written regularly
argument_string += argument
argument_string += space

i = i + 1
return 'print(' + '+'.join(all_arguments_converted) + ')'

return f"print(f'{argument_string}')"

def forward(self, args):
# no args received? default to 50
if len(args) == 0:
@@ -552,6 +570,20 @@ def list_access(self, args):
def quoted(s):
return s[0] == "'" and s[-1] == "'"

def make_f_string(args, lookup):
argument_string = ''
for argument in args:
if argument in lookup:
# variables are placed in {} in the f string
argument_string += "{" + process_hash(argument) + "}"
else:
# strings are written regularly
# however we no longer need their quptes in the f-string
# the quotes are only left on to check if they are there.
argument_string += argument.replace("'",'')

return f"print(f'{argument_string}')"

#TODO: punctuation chars not be needed for level2 and up anymore, could be removed
class ConvertToPython_3(ConvertToPython_2):

@@ -567,7 +599,7 @@ def print(self, args):
unquoted_in_lookup = [a in self.lookup for a in unquoted_args]
#we can print if all arguments are quoted OR they are all variables
if unquoted_in_lookup == [] or all(unquoted_in_lookup):
return "print(" + '+'.join(args) + ')'
return make_f_string(args, self.lookup)
else:
# I would like to raise normally but that is caught by the transformer :(
first_unquoted_var = unquoted_args[0]
@@ -627,6 +659,7 @@ def repeat(self, args):
{indent(command)}"""

class ConvertToPython_6(ConvertToPython_5):
#todo: now that Skulpt can do it, we would love fstrings here too, looks nicer and is less error prine!

def print(self, args):
#force all to be printed as strings (since there can not be int arguments)
80 changes: 41 additions & 39 deletions tests/tests_level_02.py
Original file line number Diff line number Diff line change
@@ -42,15 +42,28 @@ def test_transpile_echo_at_level_2(self):
def test_spaces_in_arguments(self):
result = hedy.transpile("print hallo wereld", self.level)
expected = textwrap.dedent("""\
print('hallo'+' '+'wereld')""")
print(f'hallo wereld')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)

def test_transpile_print(self):
result = hedy.transpile("print Hallo welkom bij Hedy!", self.level)
expected = textwrap.dedent("""\
print('Hallo'+' '+'welkom'+' '+'bij'+' '+'Hedy'+'!')""")
print(f'Hallo welkom bij Hedy!')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)

def test_print_list(self):
code = textwrap.dedent("""\
plaatsen is een stad, een dorp, een strand
print test plaatsen""")

result = hedy.transpile(code, self.level)
expected = textwrap.dedent("""\
plaatsen = ['een stad', 'een dorp', 'een strand ']
print(f'test {plaatsen}')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -81,19 +94,23 @@ def test_transpile_ask_with_print(self):

expected = textwrap.dedent("""\
kleur = input('wat is je lievelingskleur'+'?')
print(kleur+'!')""")
print(f'{kleur}!')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)



def test_transpile_print_multiple_lines(self):
result = hedy.transpile("print Hallo welkom bij Hedy!\nprint Mooi hoor", self.level)
code = textwrap.dedent("""\
print Hallo welkom bij Hedy!
print Mooi hoor""")

result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('Hallo'+' '+'welkom'+' '+'bij'+' '+'Hedy'+'!')
print('Mooi'+' '+'hoor')""")
print(f'Hallo welkom bij Hedy!')
print(f'Mooi hoor')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -169,7 +186,7 @@ def test_transpile_assign_and_print(self):

expected = textwrap.dedent("""\
naam = 'Felienne'
print(naam)""")
print(f'{naam}')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -184,7 +201,7 @@ def test_transpile_assign_and_print_more_words(self):

expected = textwrap.dedent("""\
naam = 'Felienne'
print('hallo'+' '+naam)""")
print(f'hallo {naam}')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -198,7 +215,7 @@ def test_transpile_assign_and_print_punctuation(self):

expected = textwrap.dedent("""\
naam = 'Hedy'
print('Hallo'+' '+naam+'!')""")
print(f'Hallo {naam}!')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -214,7 +231,7 @@ def test_transpile_assign_and_print_in_sentence(self):

expected = textwrap.dedent("""\
naam = 'Hedy'
print(naam+' '+'is'+' '+'jouw'+' '+'voornaam')""")
print(f'{naam} is jouw voornaam')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -230,7 +247,7 @@ def test_transpile_assign_and_print_something_else(self):

expected = textwrap.dedent("""\
naam = 'Felienne'
print('Hallo')""")
print(f'Hallo')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -258,7 +275,7 @@ def test_print_with_list_var(self):

expected = textwrap.dedent("""\
dieren = ['Hond', 'Kat', 'Kangoeroe']
print(dieren[1])""")
print(f'{dieren[1]}')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -275,22 +292,7 @@ def test_failing_car_program(self):

expected = textwrap.dedent("""\
naam = input('wat is de naam van de hoofdpersoon')
print(naam+' '+'doet'+' '+'mee'+' '+'aan'+' '+'een'+' '+'race'+' '+'hij'+' '+'krijgt'+' '+'een'+' '+'willekeurige'+' '+'auto')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)

def test_windows_line_endings(self):

code = textwrap.dedent("""\
print hallo
print allemaal""")

result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('hallo')
print('allemaal')""")
print(f'{naam} doet mee aan een race hij krijgt een willekeurige auto')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -300,7 +302,7 @@ def test_allow_use_of_quotes_in_print(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('\\'Welcome'+' '+'to'+' '+'OceanView'+'!'+' '+'\\'')""")
print(f'\\'Welcome to OceanView! \\'')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -313,7 +315,7 @@ def test_allow_use_of_slashes_in_print(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('Welcome'+' '+'to'+' '+'O/ceanView')""")
print(f'Welcome to O/ceanView')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -326,7 +328,7 @@ def test_allow_use_of_backslashes_in_print(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('Welcome'+' '+'to'+' '+'O\ceanView')""")
print(f'Welcome to O\ceanView')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -339,7 +341,7 @@ def test_allow_use_of_quotes_in_ask(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('\\'Welcome'+' '+'to'+' '+'OceanView'+'!'+' '+'\\'')""")
print(f'\\'Welcome to OceanView! \\'')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -373,7 +375,7 @@ def test_ask_bengali_vars(self):

expected = textwrap.dedent("""\
ve1760b6272d4c9f816e62af4882d874f = input('আপনার প্রিয় রং কি'+'?')
print(ve1760b6272d4c9f816e62af4882d874f+' '+'is'+' '+'আপনার'+' '+'প্রিয')""")
print(f'{ve1760b6272d4c9f816e62af4882d874f} is আপনার প্রিয')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -383,7 +385,7 @@ def test_two_spaces_after_print(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('hallo'+'!')""")
print(f'hallo!')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -393,7 +395,7 @@ def test_print_asterisk(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('*Jouw*'+' '+'favoriet'+' '+'is'+' '+'dus'+' '+'kleur')""")
print(f'*Jouw* favoriet is dus kleur')""")

self.assertEqual(expected, result.code)
self.assertEqual(False, result.has_turtle)
@@ -406,7 +408,7 @@ def test_turn_number(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('Turtle'+' '+'race')
print(f'Turtle race')
t.right(90)""")

self.assertEqual(expected, result.code)
@@ -421,7 +423,7 @@ def test_turn_number_var(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('Turtle'+' '+'race')
print(f'Turtle race')
direction = '70'
t.right(direction)""")

@@ -437,7 +439,7 @@ def test_turn_ask(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('Turtle'+' '+'race')
print(f'Turtle race')
direction = input('Where to turn'+'?')
t.right(direction)""")

@@ -453,7 +455,7 @@ def test_random_turn(self):
result = hedy.transpile(code, self.level)

expected = textwrap.dedent("""\
print('Turtle'+' '+'race')
print(f'Turtle race')
directions = ['10', '100', '360']
t.right(random.choice(directions))""")

Loading

0 comments on commit 06ae4e3

Please sign in to comment.