internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: hedyorg/hedy

Issue:
Move turtle location to upper middle
The turtle now starts in the middle of the middle, which is a bit low. Higher would make it easier to use the whole (already small) canvas


Discussion:

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -21,6 +21,7 @@
 from website.auth import auth_templates, current_user, requires_login, is_admin, is_teacher
 from utils import timems, load_yaml, load_yaml_rt, dump_yaml_rt, version, is_debug_mode
 import utils
+import textwrap
 
 # app.py
 from flask import Flask, request, jsonify, session, abort, g, redirect, Response, make_response
@@ -285,7 +286,18 @@ def parse():
 
         response['has_turtle'] = has_turtle
         if has_turtle:
-            response["Code"] = "# coding=utf8\nimport random\nimport time\nimport turtle\nt = turtle.Turtle()\nt.forward(0)\n" + python_code
+            response["Code"] = textwrap.dedent("""\
+            # coding=utf8
+            import random, time, turtle
+            t = turtle.Turtle()
+            t.hideturtle()
+            t.speed(0)
+            t.penup()
+            t.goto(50,100)
+            t.showturtle()
+            t.pendown()
+            t.speed(3)
+            """) + python_code
         else:
             response["Code"] = "# coding=utf8\nimport random\n" + python_code
 


Test patch:
Repository: hedyorg/hedy

Issue:
Log "read aloud"
When a program is ran with sound on, log this so we can see how often this is used


Discussion:
@fpereiro Another one you could pick up I think?

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -272,6 +272,9 @@ def parse():
     # reason.
     lang = body.get('lang', requested_lang())
 
+    # true if kid enabled the read aloud option
+    read_aloud = body.read_aloud
+
     response = {}
     username = current_user(request) ['username'] or None
 
@@ -325,6 +328,7 @@ def parse():
         'server_error': response.get('Error'),
         'version': version(),
         'username': username,
+        'read_aloud': read_aloud,
         'is_test': 1 if os.getenv ('IS_TEST_ENV') else None,
         'adventure_name': body.get('adventure_name', None)
     })


Test patch:
Repository: hedyorg/hedy

Issue:
Fix: If inside repeat doesn't (always) work
My code in level 7 doesn't work and should be fixed. 

```
print 'kassabon'
prijs is 0
repeat 7 times
    ingredient is ask 'wat wil je kopen?'
    if ingredient is appel 
        prijs is prijs + 1
print 'Dat is in totaal ' prijs ' euro.'
```


Discussion:

Resolving patch:
diff --git a/hedy.py b/hedy.py
--- a/hedy.py
+++ b/hedy.py
@@ -176,6 +176,10 @@ class CodePlaceholdersPresentException(HedyException):
     def __init__(self):
         super().__init__('Has Blanks')
 
+class IndentationException(HedyException):
+    def __init__(self, **arguments):
+        super().__init__('Unexpected Indentation', **arguments)
+
 class ExtractAST(Transformer):
     # simplifies the tree: f.e. flattens arguments of text, var and punctuation for further processing
     def text(self, args):
@@ -1280,7 +1284,9 @@ def preprocess_blocks(code):
     current_number_of_indents = 0
     previous_number_of_indents = 0
     indent_size = None #we don't fix indent size but the first encounter sets it
+    line_number = 0
     for line in lines:
+        line_number += 1
         leading_spaces = find_indent_length(line)
 
         #first encounter sets indent size for this program
@@ -1291,6 +1297,9 @@ def preprocess_blocks(code):
         if indent_size != None:
             current_number_of_indents = leading_spaces // indent_size
 
+        if current_number_of_indents - previous_number_of_indents > 1:
+            raise IndentationException(line_number = line_number, leading_spaces = leading_spaces, indent_size = indent_size)
+
         if current_number_of_indents < previous_number_of_indents:
             # we springen 'terug' dus er moeten end-blocken in
             # bij meerdere terugsprongen sluiten we ook meerdere blokken


Test patch:
diff --git a/tests/tests_level_07.py b/tests/tests_level_07.py
--- a/tests/tests_level_07.py
+++ b/tests/tests_level_07.py
@@ -323,6 +323,21 @@ def test_issue_297(self):
 
 # programs with issues to see if we catch them properly
 
+  def test_issue_902(self):
+    code = textwrap.dedent("""\
+    print 'kassabon'
+    prijs is 0
+    repeat 7 times
+      ingredient is ask 'wat wil je kopen?'
+      if ingredient is appel
+          prijs is prijs + 1
+    print 'Dat is in totaal ' prijs ' euro.'""")
+
+    with self.assertRaises(hedy.IndentationException) as context:
+      result = hedy.transpile(code, self.level)
+    self.assertEqual('Unexpected Indentation', context.exception.error_code)
+
+
   def test_issue_396(self):
     code = textwrap.dedent("""\
     repeat 5 times
Repository: hedyorg/hedy

Issue:
It seems the server broken.
<img width="560" src="https://user-images.githubusercontent.com/12047524/136717701-3f93c7e7-45be-4fc2-9130-23407f3838b4.png">



Discussion:
Hi @alexwenbj !

Do you know what steps lead you to see this error? For us it all seems up and our monitoring also does not show any issues.
@Felienne I only clicked the "Try it" button in the homepage,and then it showed me the error.(It still shows me the error by now).

<img width="1270" src="https://user-images.githubusercontent.com/12047524/136803396-74edd870-669a-47c1-ba35-50b375e6429c.png">

Ah I see! If you click Hedy in the tab bar you will get there! Will fix
this straight away.

On Monday, 11 October 2021, alexwenbj ***@***.***> wrote:

> @Felienne <https://github.com/Felienne> I only clicked the "Try it"
> button in the homepage,and then it showed me the error.(It still shows me
> the error by now).
>
>
> <https://user-images.githubusercontent.com/12047524/136803396-74edd870-669a-47c1-ba35-50b375e6429c.png>
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/Felienne/hedy/issues/951#issuecomment-940062045>, or
> unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAHVBJPCPZZCSQGZEOVF7XDUGLVG7ANCNFSM5FXA5S6A>
> .
> Triage notifications on the go with GitHub Mobile for iOS
> <https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
> or Android
> <https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
>
>

Hi @alexwenbj!

I tried to reproduce it but for me, it also works with the Try it button. What language did you set Hedy to? And what operating system and browser are you using?
Never mind I understand the issue! We are looking into it!

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -74,7 +74,9 @@
 def load_adventures_in_all_languages():
     adventures = {}
     for lang in ALL_LANGUAGES.keys ():
-        adventures[lang] = YamlFile.for_file(f'coursedata/adventures/{lang}.yaml')
+        filename = f'coursedata/adventures/{lang}.yaml'
+        if os.path.exists(filename):
+            adventures[lang] = YamlFile.for_file(filename)
     return adventures
 
 


Test patch:
Repository: hedyorg/hedy

Issue:
No 404 given when /hedy/ is not present in the url
https://hedy-alpha.herokuapp.com/adventure/lalala does not give a nice 404 error:

![image](https://user-images.githubusercontent.com/1003685/138877797-b81e8d0b-5829-4d4b-95d4-73e6321b6db1.png)

while this does not:

https://hedy-alpha.herokuapp.com/adventure/lalala

![image](https://user-images.githubusercontent.com/1003685/138877826-478eb81d-647a-4a53-b52b-c644f33204b0.png)




Discussion:

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -80,7 +80,7 @@ def load_adventure_for_language(lang):
 
     if not adventures_for_lang.has_adventures():
         # The default fall back language is English
-        fall_back = FALL_BACK_ADVENTURE.get(lang, "en")        
+        fall_back = FALL_BACK_ADVENTURE.get(lang, "en")
         adventures_for_lang = ADVENTURES[fall_back]
     return adventures_for_lang.adventures_file['adventures']
 
@@ -513,7 +513,7 @@ def get_quiz(level_source, question_nr, attempt):
                             option_obj['char_index'] = char_array[i]
                     i += 1
                 question_obj.append(option_obj)
-                
+
             html_obj = render_template('quiz_question.html',
                                    quiz=quiz_data,
                                    level_source=level_source,
@@ -819,6 +819,10 @@ def client_messages():
 
     return response
 
+@app.errorhandler(404)
+def not_found(exception):
+    return utils.page_404 (TRANSLATIONS, render_main_menu('adventures'), current_user(request) ['username'], requested_lang (), TRANSLATIONS.get_translations (requested_lang (), 'ui').get ('page_not_found'))
+
 @app.errorhandler(500)
 def internal_error(exception):
     import traceback


Test patch:
Repository: hedyorg/hedy

Issue:
Accessing a level that is not defined throws a 500 error
For example: http://localhost:5000/hedy/23

There is a check for this in `hedyweb.py` but before the execution reaches it, the endpoint at `app.py` throws. We should add tighter validation in the `app.py` endpoint for requesting a level (`defaults = level_defaults_for_lang.get_defaults_for_level(level)`).


Discussion:

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -766,6 +766,8 @@ def index(level, step):
 
     adventures = load_adventures_per_level(requested_lang(), level)
     level_defaults_for_lang = LEVEL_DEFAULTS[requested_lang()]
+    if level not in level_defaults_for_lang.levels:
+        return utils.page_404 (TRANSLATIONS, render_main_menu('hedy'), current_user(request) ['username'], requested_lang (), TRANSLATIONS.get_translations (requested_lang (), 'ui').get ('no_such_level'))
     defaults = level_defaults_for_lang.get_defaults_for_level(level)
     max_level = level_defaults_for_lang.max_level()
 


Test patch:
Repository: hedyorg/hedy

Issue:
[BUG] If line contains only spaces in levels 8+ it throws parse error
**Describe the bug**
After indentation is introduced in level 7, if you type a line consisting of only spaces it will throw a ParseException, and the resulting error does not say space, it just says `" "`

**Paste the Hedy code & level**
```
repeat 3 times
    food is ask 'What do you want?'
    if food is 'pizza'
        print 'nice!'
         
```
**Add a screenshot (optional)**
![image](https://user-images.githubusercontent.com/45865185/140667159-8f356e96-c88b-4f6e-b163-866f6ff7ca25.png)

**Expected behavior**
If this isn't valid code, say "You typed a space, but that's not allowed". I'd personally prefer this to be valid code



Discussion:
Hi @racertop!

Thanks to #1211 this is now a bit better:

![image](https://user-images.githubusercontent.com/1003685/140897283-1445f6b8-bcbe-4543-9608-cdde899efe2e.png)

But I totally agree that it should be valid code!

Resolving patch:
diff --git a/hedy.py b/hedy.py
--- a/hedy.py
+++ b/hedy.py
@@ -1536,6 +1536,10 @@ def preprocess_blocks(code, level):
         if indent_size == None and leading_spaces > 0:
             indent_size = leading_spaces
 
+        # ignore whitespace-only lines
+        if leading_spaces == len(line):
+            continue
+
         #calculate nuber of indents if possible
         if indent_size != None:
             if (leading_spaces % indent_size) != 0:


Test patch:
diff --git a/tests/test_level_08.py b/tests/test_level_08.py
--- a/tests/test_level_08.py
+++ b/tests/test_level_08.py
@@ -116,6 +116,28 @@ def test_issue_396(self):
 
     self.assertEqual(expected, result.code)
 
+  def test_empty_line_with_whitespace(self):
+    code = textwrap.dedent("""\
+    repeat 3 times
+      food is ask 'What do you want?'
+      if food is 'pizza'
+        print 'nice!'
+         
+      else
+        print 'pizza is better'""")
+
+    result = hedy.transpile(code, self.level)
+
+    expected = textwrap.dedent("""\
+    for i in range(int(3)):
+      food = input('What do you want?')
+      if str(food) == str('pizza'):
+        print(f'nice!')
+      else:
+        print(f'pizza is better')""")
+
+    self.assertEqual(expected, result.code)
+
Repository: hedyorg/hedy

Issue:
feat: add sleep to an early level
That allows for the making of counters like 3...2...1... BOOM


Discussion:
Superseded by #1263 
Reopening to make a separate PR for this to minizine chances of merge conflicts

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -92,7 +92,10 @@
 """)
 
 # Preamble that will be used for non-Turtle programs
-NORMAL_PREFIX_CODE = "# coding=utf8\nimport random\n"
+NORMAL_PREFIX_CODE = textwrap.dedent("""\
+    # coding=utf8
+    import random, time
+""")
 
 def load_adventure_for_language(lang):
     adventures_for_lang = ADVENTURES[lang]
diff --git a/hedy.py b/hedy.py
--- a/hedy.py
+++ b/hedy.py
@@ -851,6 +851,13 @@ def list_access(self, args):
         else:
             return args[0] + '[' + args[1] + '-1]'
 
+    def sleep(self, args):
+        if args == []:
+            return "time.sleep(1)"
+        else:
+            return f"time.sleep({args[0]})"
+
+
 def is_quoted(s):
     return s[0] == "'" and s[-1] == "'"
 


Test patch:
diff --git a/tests/test_level_02.py b/tests/test_level_02.py
--- a/tests/test_level_02.py
+++ b/tests/test_level_02.py
@@ -26,7 +26,6 @@ def test_print(self):
 
     self.assertEqual(expected, result.code)
     self.assertEqual(False, result.has_turtle)
-
   def test_print_comma(self):
     result = hedy.transpile("print welkom bij steen, schaar, papier", self.level)
     expected = textwrap.dedent("""\
@@ -235,6 +234,26 @@ def test_ask_with_comma(self):
     self.assertEqual(expected, result.code)
     self.assertEqual(False, result.has_turtle)
 
+  #sleep tests
+  def test_sleep_with_number(self):
+    code = "sleep 2"
+    expected = "time.sleep(2)"
+
+    self.multi_level_tester(
+      code=code,
+      expected=expected,
+      test_name=self.name()
+    )
+  def test_sleep_without_number(self):
+    code = "sleep"
+    expected = "time.sleep(1)"
+
+    self.multi_level_tester(
+      code=code,
+      expected=expected,
+      test_name=self.name()
+    )
+
   #turn tests
   def test_turn_number(self):
     code = textwrap.dedent("""\
@@ -285,7 +304,6 @@ def test_forward_without_argument(self):
 
     self.assertEqual(expected, result.code)
     self.assertEqual(True, result.has_turtle)
-
   def test_forward_with_string_variable(self):
     code = textwrap.dedent("""\
         a is test
@@ -296,7 +314,6 @@ def test_forward_with_string_variable(self):
       exception=hedy.exceptions.InvalidArgumentTypeException,
       test_name=self.name()
     )
-
   def test_forward_with_list_variable(self):
     code = textwrap.dedent("""\
         a is 1, 2, 3
Repository: hedyorg/hedy

Issue:
[BUG] Class names can be duplicate
**Describe the bug**
Currently, we are able to create multiple classes with an identical name. I think this is undesirable and should be prevented. Might be best to tackle this issue at the same time as #1152.

**Paste the Hedy code & level**
It is super helpful if we can copy-paste the Hedy code to test, so please paste the code here, and don't forget to tell us what level you were in.

**Add a screenshot (optional)**
Make a picture or screenshot to show the issue. Tip! You can make a screenshot and simply paste the image into GitHub with ctrl-v.

**Expected behavior**
A clear and concise description of what you expected to happen.

**What machine and browser you were using (optional)**
If the issue concerns things in the website, let us know:
- What computer you are using (Windows, Mac, Linux?)
- What browser you were using (Chrome, Edge, Safari)



Discussion:

Resolving patch:
diff --git a/website/teacher.py b/website/teacher.py
--- a/website/teacher.py
+++ b/website/teacher.py
@@ -60,6 +60,12 @@ def create_class (user):
         if not isinstance(body.get('name'), str):
             return 'name must be a string', 400
 
+        # We use this extra call to verify if the class name doesn't already exist, if so it's a duplicate
+        Classes = DATABASE.get_teacher_classes(user['username'], True)
+        for Class in Classes:
+            if Class['name'] == body['name']:
+                return "duplicate", 200
+
         Class = {
             'id': uuid.uuid4().hex,
             'date': utils.timems (),
@@ -89,6 +95,12 @@ def update_class (user, class_id):
         if not Class or Class ['teacher'] != user ['username']:
             return 'No such class', 404
 
+        # We use this extra call to verify if the class name doesn't already exist, if so it's a duplicate
+        Classes = DATABASE.get_teacher_classes(user ['username'], True)
+        for Class in Classes:
+            if Class['name'] == body['name']:
+                return "duplicate", 200
+
         Class = DATABASE.update_class (class_id, body ['name'])
 
         return {}, 200


Test patch:
Repository: hedyorg/hedy

Issue:
[BUG] Shared program view UI is always in Frysk
**Describe the bug**
Currently when opening a shared program by share link the page will always be loaded in the Frysk language. When switching languages only the menubar changes correctly (expect the my profile page for some reason) but the rest of the UI stays at Frysk. This might be an issue with the fallback language for this page where we always return Frysk. 

Visit, for example: https://www.hedycode.com/hedy/69a752cc91b441be96c55c4d299f4f6a/view?lang=nl

**Add a screenshot (optional)**
![Schermafbeelding 2021-11-24 om 10 44 11](https://user-images.githubusercontent.com/38155424/143214418-aecb706b-a83c-48fc-9414-d5ccd3a70296.png)


**Expected behavior**
The viewed program should correctly display the language of choice in the menubar and the program view UI.

**What machine and browser you were using (optional)**
If the issue concerns things in the website, let us know:
- What computer you are using (Windows, Mac, Linux?)
- What browser you were using (Chrome, Edge, Safari)



Discussion:
Haha, weird!! The fallback should work the other way around (Frysk falls back to Nl instead of En as other langs do) but guess something is amiss here.

@rix0rrr do you know what went wrong here? This surely has not always been like this. Might #1266 have something to do with it?
I think I've found a fix! It seems that the translations on the `@app.route('/hedy/<id>/view', methods=['GET'])` are retrieved with the `lang` variable. For some reason this variable is always `fry`. However, we should (as is consistent with other templates rendering) use the `g.lang` variabel which does contain the correct value. I don't know how/why/when we should use the `lang` value, but it exists for some reason.

By changing `lang` into `g.lang` on lines 845 and 848 in `app.py` the issue should be fixed!

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -842,10 +842,10 @@ def view_program(id):
     # Everything below this line has nothing to do with this page and it's silly
     # that every page needs to put in so much effort to re-set it
     arguments_dict['menu'] = True
-    arguments_dict['auth'] = TRANSLATIONS.get_translations(lang, 'Auth')
+    arguments_dict['auth'] = TRANSLATIONS.get_translations(g.lang, 'Auth')
     arguments_dict['username'] = user.get('username', None)
     arguments_dict['is_teacher'] = is_teacher(user)
-    arguments_dict.update(**TRANSLATIONS.get_translations(lang, 'ui'))
+    arguments_dict.update(**TRANSLATIONS.get_translations(g.lang, 'ui'))
 
     return render_template("view-program-page.html", **arguments_dict)
 


Test patch:
Repository: hedyorg/hedy

Issue:
[BUG] Users can overwrite saved program by saving with identical program name
**Describe the bug**
Currently when saving a program it is stored with a chosen name. However, when storing a program with an identical name the stored program is overwritten. Even if this is written on a different level! This is, of course, undesirable behavior. Programs should only be overwritten if we open a previously stored program and then save it again. But even in that case we want to return the user with a warning such as "Saving this program will over-write an older version, are you sure?". In any other case of saving a program if the name already exists: return an error "you already have a program saved with this name".

**Edit:** This bug has some priority because of this bug students are able to overwrite submitted programs!

**Expected behavior**
When saving a program with the same name as an already saved program we want to return an "name already exists error". In the case that the user alters an already stored program (which is currently handled identical) we want to return a "are you sure you want to overwrite the older version" error. The second case should only occur iff the program is opened from the programs overview, otherwise we should view it as a new program.


Discussion:

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -824,7 +824,7 @@ def index(level, step):
         result = DATABASE.program_by_id(step)
         if not result:
             return utils.page_404 (TRANSLATIONS, current_user()['username'], g.lang, TRANSLATIONS.get_translations (g.lang, 'ui').get ('no_such_program'))
-        # If the program is not public, allow only the owner of the program, the admin user and the teacher users to access the program
+
         user = current_user()
         public_program = 'public' in result and result['public']
         if not public_program and user['username'] != result['username'] and not is_admin(user) and not is_teacher(user):
@@ -1105,6 +1105,21 @@ def delete_program(user, program_id):
     DATABASE.increase_user_program_count(user['username'], -1)
     return redirect('/programs')
 
+@app.route('/programs/duplicate-check', methods=['POST'])
+@requires_login
+def check_duplicate_program(user):
+    body = request.json
+    if not isinstance(body, dict):
+        return 'body must be an object', 400
+    if not isinstance(body.get('name'), str):
+        return 'name must be a string', 400
+
+    programs = DATABASE.programs_for_user(user['username'])
+    for program in programs:
+        if program['name'] == body['name']:
+            return jsonify({'duplicate': True})
+    return jsonify({'duplicate': False})
+
 @app.route('/programs', methods=['POST'])
 @requires_login
 def save_program(user):


Test patch:
Repository: hedyorg/hedy

Issue:
[BUG] Last edited timestamp not adjusted for timezone
**Describe the bug**
Currently the timestamp of last edited shown on the program-view page when a program is submitted does show the time as GMT. In the case of the Netherlands we would like the time represented as GMT+1. It would be nice to, in some way, localize the time to the current user and make sure that the displayed time is correct. This can be important in the case of deadlines and/or strict rules within a class of code submissions.

**Expected behavior**
Localize timestamp to show current time for current user location.


Discussion:

Resolving patch:
diff --git a/app.py b/app.py
--- a/app.py
+++ b/app.py
@@ -879,9 +879,11 @@ def view_program(id):
         arguments_dict['show_edit_button'] = False
         texts = TRANSLATIONS.get_translations(g.lang, 'Programs')
         now = timems()
+        date, measure = get_user_formatted_timestamp(texts, now, result['date'])
+        arguments_dict['program_age'] = f"{texts['ago-1']} {date} {measure} {texts['ago-2']}"
+        arguments_dict['program_timestamp'] = f"{datetime.datetime.fromtimestamp(result['date']/1000.0).strftime('%d-%m-%Y, %H:%M:%S')} GMT"
         arguments_dict['submitted_header'] = texts['submitted_header']
         arguments_dict['last_edited'] = texts['last_edited']
-        arguments_dict['program_timestamp'] = datetime.datetime.fromtimestamp(result['date']/1000.0).strftime('%d-%m-%Y, %H:%M:%S')
     else:
         arguments_dict['show_edit_button'] = True
 


Test patch: