We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
No or incorrect output [BUG]
Sometimes when my students run a program they don't get any or incorrect output. It is hard to pinpoint when exactly this happens. I think it has to do with pressing "Run Code" while a program is still running. Student do this a lot and I see this issue multiple times per lesson. Running the program keeps on giving incorrect results once this has happened. My workaround is to save the program, refresh the webpage in the browser and try again. This usually works.

One example of this issue arises when I run the code below and press the "Run Code" button multiple times during execution. At one point it will create two figures and raise an error (see screenshot). However the issue is certainly not limited to drawings, it also happens when using the `repeat` and `ask` commands.

```
hoek = 90
repeat 10 times
    turn hoek
    forward 50
forward 100
```

![image](https://user-images.githubusercontent.com/10562903/150156604-ddb95243-c88f-4ff3-a791-db2dda773c86.png)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `website/achievements.py`
Content:
```
1 from website import database
2 from hedyweb import AchievementTranslations
3 from website.auth import requires_login, current_user
4 from flask import request, jsonify, session
5 import hedy
6 
7 
8 class Achievements:
9 
10     def __init__(self):
11         self.DATABASE = database.Database()
12         self.TRANSLATIONS = AchievementTranslations()
13         self.all_commands = self.get_all_commands()
14 
15     def get_all_commands(self):
16         commands = []
17         for i in range(1, hedy.HEDY_MAX_LEVEL+1):
18             for command in hedy.commands_per_level.get(i):
19                 commands.append(command)
20         return set(commands)
21 
22     def initialize_user_data_if_necessary(self):
23         if 'achieved' not in session:
24             achievements_data = self.DATABASE.progress_by_username(current_user()['username'])
25             session['new_achieved'] = []
26             session['new_commands'] = []
27             session['previous_code'] = None
28             session['identical_consecutive_errors'] = 0
29             session['consecutive_errors'] = 0
30             if not achievements_data:
31                 achievements_data = {}
32             if 'achieved' in achievements_data:
33                 session['achieved'] = achievements_data['achieved']
34             else:
35                 session['achieved'] = []
36             if 'commands' in achievements_data:
37                 session['commands'] = achievements_data['commands']
38             else:
39                 session['commands'] = []
40             if 'run_programs' in achievements_data:
41                 session['run_programs'] = achievements_data['run_programs']
42             else:
43                 session['run_programs'] = 0
44             if 'saved_programs' in achievements_data:
45                 session['saved_programs'] = achievements_data['saved_programs']
46             else:
47                 session['saved_programs'] = 0
48             if 'submitted_programs' in achievements_data:
49                 session['submitted_programs'] = achievements_data['submitted_programs']
50             else:
51                 session['submitted_programs'] = 0
52 
53     def routes(self, app, database):
54         global DATABASE
55         DATABASE = database
56 
57         @app.route('/achievements', methods=['POST'])
58         @requires_login
59         def push_new_achievement(user):
60             body = request.json
61             if "achievement" in body:
62                 self.initialize_user_data_if_necessary()
63                 if body['achievement'] not in session['achieved'] and body['achievement'] in self.TRANSLATIONS.get_translations(session['lang']):
64                     return jsonify({"achievements": self.verify_pushed_achievement(user.get('username'), body['achievement'])})
65             return jsonify({})
66 
67     def increase_count(self, category):
68         self.initialize_user_data_if_necessary()
69         if category == "run":
70             session['run_programs'] += 1
71         elif category == "saved":
72             session['saved_programs'] += 1
73         elif category == "submitted":
74             session['submitted_programs'] += 1
75 
76     def add_single_achievement(self, username, achievement):
77         self.initialize_user_data_if_necessary()
78         if achievement not in session['achieved'] and achievement in self.TRANSLATIONS.get_translations(session['lang']):
79             return self.verify_pushed_achievement(username, achievement)
80         else:
81             return None
82 
83     def verify_run_achievements(self, username, code=None, level=None, response=None):
84         self.initialize_user_data_if_necessary()
85         self.check_programs_run()
86         if code and level:
87             self.check_code_achievements(code, level)
88         if code and response:
89             self.check_response_achievements(code, response)
90 
91         if len(session['new_commands']) > 0:
92             for command in session['new_commands']:
93                 session['commands'].append(command)
94             session['new_commands'] = []
95             self.DATABASE.add_commands_to_username(username, session['commands'])
96 
97         if len(session['new_achieved']) > 0:
98             self.DATABASE.add_achievements_to_username(username, session['new_achieved'])
99             for achievement in session['new_achieved']:
100                 session['achieved'].append(achievement)
101             return True
102         return False
103 
104     def verify_save_achievements(self, username, adventure=None):
105         self.initialize_user_data_if_necessary()
106         self.check_programs_saved()
107         if adventure and 'adventure_is_worthwhile' not in session['achieved']:
108             session['new_achieved'].append("adventure_is_worthwhile")
109         if len(session['new_achieved']) > 0:
110             self.DATABASE.add_achievements_to_username(username, session['new_achieved'])
111             for achievement in session['new_achieved']:
112                 session['achieved'].append(achievement)
113             return True
114         return False
115 
116     def verify_submit_achievements(self, username):
117         self.initialize_user_data_if_necessary()
118         self.check_programs_submitted()
119 
120         if len(session['new_achieved']) > 0:
121             self.DATABASE.add_achievements_to_username(username, session['new_achieved'])
122             for achievement in session['new_achieved']:
123                 session['achieved'].append(achievement)
124             return True
125         return False
126 
127     def verify_pushed_achievement(self, username, achievement):
128         self.initialize_user_data_if_necessary()
129         session['new_achieved'] = [achievement]
130         self.DATABASE.add_achievement_to_username(username, achievement)
131         session['achieved'].append(achievement)
132         return self.get_earned_achievements()
133 
134     def get_earned_achievements(self):
135         self.initialize_user_data_if_necessary()
136         translations = self.TRANSLATIONS.get_translations(session['lang'])
137         translated_achievements = []
138         for achievement in session['new_achieved']:
139             translated_achievements.append([translations[achievement]['title'], translations[achievement]['text'], translations[achievement]['image']])
140         session['new_achieved'] = [] #Once we get earned achievements -> empty the array with "waiting" ones
141         session['new_commands'] = []
142         return translated_achievements
143 
144     def check_programs_run(self):
145         self.initialize_user_data_if_necessary()
146         if 'getting_started_I' not in session['achieved'] and session['run_programs'] >= 1:
147             session['new_achieved'].append("getting_started_I")
148         if 'getting_started_II' not in session['achieved'] and session['run_programs'] >= 10:
149             session['new_achieved'].append("getting_started_II")
150         if 'getting_started_III' not in session['achieved'] and session['run_programs'] >= 50:
151             session['new_achieved'].append("getting_started_III")
152         if 'getting_started_IV' not in session['achieved'] and session['run_programs'] >= 200:
153             session['new_achieved'].append("getting_started_IV")
154         if 'getting_started_V' not in session['achieved'] and session['run_programs'] >= 500:
155             session['new_achieved'].append("getting_started_V")
156 
157     def check_programs_saved(self):
158         self.initialize_user_data_if_necessary()
159         if 'one_to_remember_I' not in session['achieved'] and session['saved_programs'] >= 1:
160             session['new_achieved'].append("one_to_remember_I")
161         if 'one_to_remember_II' not in session['achieved'] and session['saved_programs'] >= 5:
162             session['new_achieved'].append("one_to_remember_II")
163         if 'one_to_remember_III' not in session['achieved'] and session['saved_programs'] >= 10:
164             session['new_achieved'].append("one_to_remember_III")
165         if 'one_to_remember_IV' not in session['achieved'] and session['saved_programs'] >= 25:
166             session['new_achieved'].append("one_to_remember_IV")
167         if 'one_to_remember_V' not in session['achieved'] and session['saved_programs'] >= 50:
168             session['new_achieved'].append("one_to_remember_V")
169 
170     def check_programs_submitted(self):
171         self.initialize_user_data_if_necessary()
172         if 'deadline_daredevil_I' not in session['achieved'] and session['submitted_programs'] >= 1:
173             session['new_achieved'].append("deadline_daredevil_I")
174         if 'deadline_daredevil_II' not in session['achieved'] and session['submitted_programs'] >= 3:
175             session['new_achieved'].append("deadline_daredevil_II")
176         if 'deadline_daredevil_III' not in session['achieved'] and session['submitted_programs'] >= 10:
177             session['new_achieved'].append("deadline_daredevil_III")
178 
179     def check_code_achievements(self, code, level):
180         self.initialize_user_data_if_necessary()
181         commands_in_code = hedy.all_commands(code, level, session['lang'])
182         if 'trying_is_key' not in session['achieved']:
183             for command in set(commands_in_code):
184                 if command not in session['commands'] and command not in session['new_commands']:
185                     session['new_commands'].append(command)
186         if set(session['commands']).union(session['new_commands']) == self.all_commands:
187             session['new_achieved'].append("trying_is_key")
188         if 'did_you_say_please' not in session['achieved'] and "ask" in hedy.all_commands(code, level, session['lang']):
189             session['new_achieved'].append("did_you_say_please")
190         if 'talk-talk-talk' not in session['achieved'] and hedy.all_commands(code, level, session['lang']).count("ask") >= 5:
191             session['new_achieved'].append("talk-talk-talk")
192         if 'hedy_honor' not in session['achieved'] and "Hedy" in code:
193             session['new_achieved'].append("hedy_honor")
194         if 'hedy-ious' not in session['achieved']:
195             all_print_arguments = hedy.all_print_arguments(code, level, session['lang'])
196             for argument in all_print_arguments:
197                 if all_print_arguments.count(argument) >= 10:
198                     session['new_achieved'].append("hedy-ious")
199                     break
200 
201     def check_response_achievements(self, code, response):
202         self.initialize_user_data_if_necessary()
203         if 'ninja_turtle' not in session['achieved'] and 'has_turtle' in response and response['has_turtle']:
204             session['new_achieved'].append("ninja_turtle")
205         if 'watch_out' not in session['achieved'] and 'Warning' in response and response['Warning']:
206             session['new_achieved'].append("watch_out")
207         if 'Error' in response and response['Error']:
208             session['consecutive_errors'] += 1
209             if session['previous_code'] == code:
210                 if session['identical_consecutive_errors'] == 0:
211                     session['identical_consecutive_errors'] += 2 #We have to count the first one too!
212                 else:
213                     session['identical_consecutive_errors'] += 1
214             if session['identical_consecutive_errors'] >= 3:
215                 if 'programming_panic' not in session['achieved']:
216                     session['new_achieved'].append("programming_panic")
217             session['previous_code'] = code
218         else:
219             if 'programming_protagonist' not in session['achieved'] and session['consecutive_errors'] >= 1:
220                 session['new_achieved'].append("programming_protagonist")
221             session['consecutive_errors'] = 0
222             session['identical_consecutive_errors'] = 0
223 
224 
225 
226
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/website/achievements.py b/website/achievements.py
--- a/website/achievements.py
+++ b/website/achievements.py
@@ -183,8 +183,8 @@
             for command in set(commands_in_code):
                 if command not in session['commands'] and command not in session['new_commands']:
                     session['new_commands'].append(command)
-        if set(session['commands']).union(session['new_commands']) == self.all_commands:
-            session['new_achieved'].append("trying_is_key")
+            if set(session['commands']).union(session['new_commands']) == self.all_commands:
+                session['new_achieved'].append("trying_is_key")
         if 'did_you_say_please' not in session['achieved'] and "ask" in hedy.all_commands(code, level, session['lang']):
             session['new_achieved'].append("did_you_say_please")
         if 'talk-talk-talk' not in session['achieved'] and hedy.all_commands(code, level, session['lang']).count("ask") >= 5:

{"golden_diff": "diff --git a/website/achievements.py b/website/achievements.py\n--- a/website/achievements.py\n+++ b/website/achievements.py\n@@ -183,8 +183,8 @@\n             for command in set(commands_in_code):\n                 if command not in session['commands'] and command not in session['new_commands']:\n                     session['new_commands'].append(command)\n-        if set(session['commands']).union(session['new_commands']) == self.all_commands:\n-            session['new_achieved'].append(\"trying_is_key\")\n+            if set(session['commands']).union(session['new_commands']) == self.all_commands:\n+                session['new_achieved'].append(\"trying_is_key\")\n         if 'did_you_say_please' not in session['achieved'] and \"ask\" in hedy.all_commands(code, level, session['lang']):\n             session['new_achieved'].append(\"did_you_say_please\")\n         if 'talk-talk-talk' not in session['achieved'] and hedy.all_commands(code, level, session['lang']).count(\"ask\") >= 5:\n", "issue": "No or incorrect output [BUG]\nSometimes when my students run a program they don't get any or incorrect output. It is hard to pinpoint when exactly this happens. I think it has to do with pressing \"Run Code\" while a program is still running. Student do this a lot and I see this issue multiple times per lesson. Running the program keeps on giving incorrect results once this has happened. My workaround is to save the program, refresh the webpage in the browser and try again. This usually works.\r\n\r\nOne example of this issue arises when I run the code below and press the \"Run Code\" button multiple times during execution. At one point it will create two figures and raise an error (see screenshot). However the issue is certainly not limited to drawings, it also happens when using the `repeat` and `ask` commands.\r\n\r\n```\r\nhoek = 90\r\nrepeat 10 times\r\n    turn hoek\r\n    forward 50\r\nforward 100\r\n```\r\n\r\n![image](https://user-images.githubusercontent.com/10562903/150156604-ddb95243-c88f-4ff3-a791-db2dda773c86.png)\r\n\n", "before_files": [{"content": "from website import database\nfrom hedyweb import AchievementTranslations\nfrom website.auth import requires_login, current_user\nfrom flask import request, jsonify, session\nimport hedy\n\n\nclass Achievements:\n\n    def __init__(self):\n        self.DATABASE = database.Database()\n        self.TRANSLATIONS = AchievementTranslations()\n        self.all_commands = self.get_all_commands()\n\n    def get_all_commands(self):\n        commands = []\n        for i in range(1, hedy.HEDY_MAX_LEVEL+1):\n            for command in hedy.commands_per_level.get(i):\n                commands.append(command)\n        return set(commands)\n\n    def initialize_user_data_if_necessary(self):\n        if 'achieved' not in session:\n            achievements_data = self.DATABASE.progress_by_username(current_user()['username'])\n            session['new_achieved'] = []\n            session['new_commands'] = []\n            session['previous_code'] = None\n            session['identical_consecutive_errors'] = 0\n            session['consecutive_errors'] = 0\n            if not achievements_data:\n                achievements_data = {}\n            if 'achieved' in achievements_data:\n                session['achieved'] = achievements_data['achieved']\n            else:\n                session['achieved'] = []\n            if 'commands' in achievements_data:\n                session['commands'] = achievements_data['commands']\n            else:\n                session['commands'] = []\n            if 'run_programs' in achievements_data:\n                session['run_programs'] = achievements_data['run_programs']\n            else:\n                session['run_programs'] = 0\n            if 'saved_programs' in achievements_data:\n                session['saved_programs'] = achievements_data['saved_programs']\n            else:\n                session['saved_programs'] = 0\n            if 'submitted_programs' in achievements_data:\n                session['submitted_programs'] = achievements_data['submitted_programs']\n            else:\n                session['submitted_programs'] = 0\n\n    def routes(self, app, database):\n        global DATABASE\n        DATABASE = database\n\n        @app.route('/achievements', methods=['POST'])\n        @requires_login\n        def push_new_achievement(user):\n            body = request.json\n            if \"achievement\" in body:\n                self.initialize_user_data_if_necessary()\n                if body['achievement'] not in session['achieved'] and body['achievement'] in self.TRANSLATIONS.get_translations(session['lang']):\n                    return jsonify({\"achievements\": self.verify_pushed_achievement(user.get('username'), body['achievement'])})\n            return jsonify({})\n\n    def increase_count(self, category):\n        self.initialize_user_data_if_necessary()\n        if category == \"run\":\n            session['run_programs'] += 1\n        elif category == \"saved\":\n            session['saved_programs'] += 1\n        elif category == \"submitted\":\n            session['submitted_programs'] += 1\n\n    def add_single_achievement(self, username, achievement):\n        self.initialize_user_data_if_necessary()\n        if achievement not in session['achieved'] and achievement in self.TRANSLATIONS.get_translations(session['lang']):\n            return self.verify_pushed_achievement(username, achievement)\n        else:\n            return None\n\n    def verify_run_achievements(self, username, code=None, level=None, response=None):\n        self.initialize_user_data_if_necessary()\n        self.check_programs_run()\n        if code and level:\n            self.check_code_achievements(code, level)\n        if code and response:\n            self.check_response_achievements(code, response)\n\n        if len(session['new_commands']) > 0:\n            for command in session['new_commands']:\n                session['commands'].append(command)\n            session['new_commands'] = []\n            self.DATABASE.add_commands_to_username(username, session['commands'])\n\n        if len(session['new_achieved']) > 0:\n            self.DATABASE.add_achievements_to_username(username, session['new_achieved'])\n            for achievement in session['new_achieved']:\n                session['achieved'].append(achievement)\n            return True\n        return False\n\n    def verify_save_achievements(self, username, adventure=None):\n        self.initialize_user_data_if_necessary()\n        self.check_programs_saved()\n        if adventure and 'adventure_is_worthwhile' not in session['achieved']:\n            session['new_achieved'].append(\"adventure_is_worthwhile\")\n        if len(session['new_achieved']) > 0:\n            self.DATABASE.add_achievements_to_username(username, session['new_achieved'])\n            for achievement in session['new_achieved']:\n                session['achieved'].append(achievement)\n            return True\n        return False\n\n    def verify_submit_achievements(self, username):\n        self.initialize_user_data_if_necessary()\n        self.check_programs_submitted()\n\n        if len(session['new_achieved']) > 0:\n            self.DATABASE.add_achievements_to_username(username, session['new_achieved'])\n            for achievement in session['new_achieved']:\n                session['achieved'].append(achievement)\n            return True\n        return False\n\n    def verify_pushed_achievement(self, username, achievement):\n        self.initialize_user_data_if_necessary()\n        session['new_achieved'] = [achievement]\n        self.DATABASE.add_achievement_to_username(username, achievement)\n        session['achieved'].append(achievement)\n        return self.get_earned_achievements()\n\n    def get_earned_achievements(self):\n        self.initialize_user_data_if_necessary()\n        translations = self.TRANSLATIONS.get_translations(session['lang'])\n        translated_achievements = []\n        for achievement in session['new_achieved']:\n            translated_achievements.append([translations[achievement]['title'], translations[achievement]['text'], translations[achievement]['image']])\n        session['new_achieved'] = [] #Once we get earned achievements -> empty the array with \"waiting\" ones\n        session['new_commands'] = []\n        return translated_achievements\n\n    def check_programs_run(self):\n        self.initialize_user_data_if_necessary()\n        if 'getting_started_I' not in session['achieved'] and session['run_programs'] >= 1:\n            session['new_achieved'].append(\"getting_started_I\")\n        if 'getting_started_II' not in session['achieved'] and session['run_programs'] >= 10:\n            session['new_achieved'].append(\"getting_started_II\")\n        if 'getting_started_III' not in session['achieved'] and session['run_programs'] >= 50:\n            session['new_achieved'].append(\"getting_started_III\")\n        if 'getting_started_IV' not in session['achieved'] and session['run_programs'] >= 200:\n            session['new_achieved'].append(\"getting_started_IV\")\n        if 'getting_started_V' not in session['achieved'] and session['run_programs'] >= 500:\n            session['new_achieved'].append(\"getting_started_V\")\n\n    def check_programs_saved(self):\n        self.initialize_user_data_if_necessary()\n        if 'one_to_remember_I' not in session['achieved'] and session['saved_programs'] >= 1:\n            session['new_achieved'].append(\"one_to_remember_I\")\n        if 'one_to_remember_II' not in session['achieved'] and session['saved_programs'] >= 5:\n            session['new_achieved'].append(\"one_to_remember_II\")\n        if 'one_to_remember_III' not in session['achieved'] and session['saved_programs'] >= 10:\n            session['new_achieved'].append(\"one_to_remember_III\")\n        if 'one_to_remember_IV' not in session['achieved'] and session['saved_programs'] >= 25:\n            session['new_achieved'].append(\"one_to_remember_IV\")\n        if 'one_to_remember_V' not in session['achieved'] and session['saved_programs'] >= 50:\n            session['new_achieved'].append(\"one_to_remember_V\")\n\n    def check_programs_submitted(self):\n        self.initialize_user_data_if_necessary()\n        if 'deadline_daredevil_I' not in session['achieved'] and session['submitted_programs'] >= 1:\n            session['new_achieved'].append(\"deadline_daredevil_I\")\n        if 'deadline_daredevil_II' not in session['achieved'] and session['submitted_programs'] >= 3:\n            session['new_achieved'].append(\"deadline_daredevil_II\")\n        if 'deadline_daredevil_III' not in session['achieved'] and session['submitted_programs'] >= 10:\n            session['new_achieved'].append(\"deadline_daredevil_III\")\n\n    def check_code_achievements(self, code, level):\n        self.initialize_user_data_if_necessary()\n        commands_in_code = hedy.all_commands(code, level, session['lang'])\n        if 'trying_is_key' not in session['achieved']:\n            for command in set(commands_in_code):\n                if command not in session['commands'] and command not in session['new_commands']:\n                    session['new_commands'].append(command)\n        if set(session['commands']).union(session['new_commands']) == self.all_commands:\n            session['new_achieved'].append(\"trying_is_key\")\n        if 'did_you_say_please' not in session['achieved'] and \"ask\" in hedy.all_commands(code, level, session['lang']):\n            session['new_achieved'].append(\"did_you_say_please\")\n        if 'talk-talk-talk' not in session['achieved'] and hedy.all_commands(code, level, session['lang']).count(\"ask\") >= 5:\n            session['new_achieved'].append(\"talk-talk-talk\")\n        if 'hedy_honor' not in session['achieved'] and \"Hedy\" in code:\n            session['new_achieved'].append(\"hedy_honor\")\n        if 'hedy-ious' not in session['achieved']:\n            all_print_arguments = hedy.all_print_arguments(code, level, session['lang'])\n            for argument in all_print_arguments:\n                if all_print_arguments.count(argument) >= 10:\n                    session['new_achieved'].append(\"hedy-ious\")\n                    break\n\n    def check_response_achievements(self, code, response):\n        self.initialize_user_data_if_necessary()\n        if 'ninja_turtle' not in session['achieved'] and 'has_turtle' in response and response['has_turtle']:\n            session['new_achieved'].append(\"ninja_turtle\")\n        if 'watch_out' not in session['achieved'] and 'Warning' in response and response['Warning']:\n            session['new_achieved'].append(\"watch_out\")\n        if 'Error' in response and response['Error']:\n            session['consecutive_errors'] += 1\n            if session['previous_code'] == code:\n                if session['identical_consecutive_errors'] == 0:\n                    session['identical_consecutive_errors'] += 2 #We have to count the first one too!\n                else:\n                    session['identical_consecutive_errors'] += 1\n            if session['identical_consecutive_errors'] >= 3:\n                if 'programming_panic' not in session['achieved']:\n                    session['new_achieved'].append(\"programming_panic\")\n            session['previous_code'] = code\n        else:\n            if 'programming_protagonist' not in session['achieved'] and session['consecutive_errors'] >= 1:\n                session['new_achieved'].append(\"programming_protagonist\")\n            session['consecutive_errors'] = 0\n            session['identical_consecutive_errors'] = 0\n\n\n\n", "path": "website/achievements.py"}], "after_files": [{"content": "from website import database\nfrom hedyweb import AchievementTranslations\nfrom website.auth import requires_login, current_user\nfrom flask import request, jsonify, session\nimport hedy\n\n\nclass Achievements:\n\n    def __init__(self):\n        self.DATABASE = database.Database()\n        self.TRANSLATIONS = AchievementTranslations()\n        self.all_commands = self.get_all_commands()\n\n    def get_all_commands(self):\n        commands = []\n        for i in range(1, hedy.HEDY_MAX_LEVEL+1):\n            for command in hedy.commands_per_level.get(i):\n                commands.append(command)\n        return set(commands)\n\n    def initialize_user_data_if_necessary(self):\n        if 'achieved' not in session:\n            achievements_data = self.DATABASE.progress_by_username(current_user()['username'])\n            session['new_achieved'] = []\n            session['new_commands'] = []\n            session['previous_code'] = None\n            session['identical_consecutive_errors'] = 0\n            session['consecutive_errors'] = 0\n            if not achievements_data:\n                achievements_data = {}\n            if 'achieved' in achievements_data:\n                session['achieved'] = achievements_data['achieved']\n            else:\n                session['achieved'] = []\n            if 'commands' in achievements_data:\n                session['commands'] = achievements_data['commands']\n            else:\n                session['commands'] = []\n            if 'run_programs' in achievements_data:\n                session['run_programs'] = achievements_data['run_programs']\n            else:\n                session['run_programs'] = 0\n            if 'saved_programs' in achievements_data:\n                session['saved_programs'] = achievements_data['saved_programs']\n            else:\n                session['saved_programs'] = 0\n            if 'submitted_programs' in achievements_data:\n                session['submitted_programs'] = achievements_data['submitted_programs']\n            else:\n                session['submitted_programs'] = 0\n\n    def routes(self, app, database):\n        global DATABASE\n        DATABASE = database\n\n        @app.route('/achievements', methods=['POST'])\n        @requires_login\n        def push_new_achievement(user):\n            body = request.json\n            if \"achievement\" in body:\n                self.initialize_user_data_if_necessary()\n                if body['achievement'] not in session['achieved'] and body['achievement'] in self.TRANSLATIONS.get_translations(session['lang']):\n                    return jsonify({\"achievements\": self.verify_pushed_achievement(user.get('username'), body['achievement'])})\n            return jsonify({})\n\n    def increase_count(self, category):\n        self.initialize_user_data_if_necessary()\n        if category == \"run\":\n            session['run_programs'] += 1\n        elif category == \"saved\":\n            session['saved_programs'] += 1\n        elif category == \"submitted\":\n            session['submitted_programs'] += 1\n\n    def add_single_achievement(self, username, achievement):\n        self.initialize_user_data_if_necessary()\n        if achievement not in session['achieved'] and achievement in self.TRANSLATIONS.get_translations(session['lang']):\n            return self.verify_pushed_achievement(username, achievement)\n        else:\n            return None\n\n    def verify_run_achievements(self, username, code=None, level=None, response=None):\n        self.initialize_user_data_if_necessary()\n        self.check_programs_run()\n        if code and level:\n            self.check_code_achievements(code, level)\n        if code and response:\n            self.check_response_achievements(code, response)\n\n        if len(session['new_commands']) > 0:\n            for command in session['new_commands']:\n                session['commands'].append(command)\n            session['new_commands'] = []\n            self.DATABASE.add_commands_to_username(username, session['commands'])\n\n        if len(session['new_achieved']) > 0:\n            self.DATABASE.add_achievements_to_username(username, session['new_achieved'])\n            for achievement in session['new_achieved']:\n                session['achieved'].append(achievement)\n            return True\n        return False\n\n    def verify_save_achievements(self, username, adventure=None):\n        self.initialize_user_data_if_necessary()\n        self.check_programs_saved()\n        if adventure and 'adventure_is_worthwhile' not in session['achieved']:\n            session['new_achieved'].append(\"adventure_is_worthwhile\")\n        if len(session['new_achieved']) > 0:\n            self.DATABASE.add_achievements_to_username(username, session['new_achieved'])\n            for achievement in session['new_achieved']:\n                session['achieved'].append(achievement)\n            return True\n        return False\n\n    def verify_submit_achievements(self, username):\n        self.initialize_user_data_if_necessary()\n        self.check_programs_submitted()\n\n        if len(session['new_achieved']) > 0:\n            self.DATABASE.add_achievements_to_username(username, session['new_achieved'])\n            for achievement in session['new_achieved']:\n                session['achieved'].append(achievement)\n            return True\n        return False\n\n    def verify_pushed_achievement(self, username, achievement):\n        self.initialize_user_data_if_necessary()\n        session['new_achieved'] = [achievement]\n        self.DATABASE.add_achievement_to_username(username, achievement)\n        session['achieved'].append(achievement)\n        return self.get_earned_achievements()\n\n    def get_earned_achievements(self):\n        self.initialize_user_data_if_necessary()\n        translations = self.TRANSLATIONS.get_translations(session['lang'])\n        translated_achievements = []\n        for achievement in session['new_achieved']:\n            translated_achievements.append([translations[achievement]['title'], translations[achievement]['text'], translations[achievement]['image']])\n        session['new_achieved'] = [] #Once we get earned achievements -> empty the array with \"waiting\" ones\n        session['new_commands'] = []\n        return translated_achievements\n\n    def check_programs_run(self):\n        self.initialize_user_data_if_necessary()\n        if 'getting_started_I' not in session['achieved'] and session['run_programs'] >= 1:\n            session['new_achieved'].append(\"getting_started_I\")\n        if 'getting_started_II' not in session['achieved'] and session['run_programs'] >= 10:\n            session['new_achieved'].append(\"getting_started_II\")\n        if 'getting_started_III' not in session['achieved'] and session['run_programs'] >= 50:\n            session['new_achieved'].append(\"getting_started_III\")\n        if 'getting_started_IV' not in session['achieved'] and session['run_programs'] >= 200:\n            session['new_achieved'].append(\"getting_started_IV\")\n        if 'getting_started_V' not in session['achieved'] and session['run_programs'] >= 500:\n            session['new_achieved'].append(\"getting_started_V\")\n\n    def check_programs_saved(self):\n        self.initialize_user_data_if_necessary()\n        if 'one_to_remember_I' not in session['achieved'] and session['saved_programs'] >= 1:\n            session['new_achieved'].append(\"one_to_remember_I\")\n        if 'one_to_remember_II' not in session['achieved'] and session['saved_programs'] >= 5:\n            session['new_achieved'].append(\"one_to_remember_II\")\n        if 'one_to_remember_III' not in session['achieved'] and session['saved_programs'] >= 10:\n            session['new_achieved'].append(\"one_to_remember_III\")\n        if 'one_to_remember_IV' not in session['achieved'] and session['saved_programs'] >= 25:\n            session['new_achieved'].append(\"one_to_remember_IV\")\n        if 'one_to_remember_V' not in session['achieved'] and session['saved_programs'] >= 50:\n            session['new_achieved'].append(\"one_to_remember_V\")\n\n    def check_programs_submitted(self):\n        self.initialize_user_data_if_necessary()\n        if 'deadline_daredevil_I' not in session['achieved'] and session['submitted_programs'] >= 1:\n            session['new_achieved'].append(\"deadline_daredevil_I\")\n        if 'deadline_daredevil_II' not in session['achieved'] and session['submitted_programs'] >= 3:\n            session['new_achieved'].append(\"deadline_daredevil_II\")\n        if 'deadline_daredevil_III' not in session['achieved'] and session['submitted_programs'] >= 10:\n            session['new_achieved'].append(\"deadline_daredevil_III\")\n\n    def check_code_achievements(self, code, level):\n        self.initialize_user_data_if_necessary()\n        commands_in_code = hedy.all_commands(code, level, session['lang'])\n        if 'trying_is_key' not in session['achieved']:\n            for command in set(commands_in_code):\n                if command not in session['commands'] and command not in session['new_commands']:\n                    session['new_commands'].append(command)\n            if set(session['commands']).union(session['new_commands']) == self.all_commands:\n                session['new_achieved'].append(\"trying_is_key\")\n        if 'did_you_say_please' not in session['achieved'] and \"ask\" in hedy.all_commands(code, level, session['lang']):\n            session['new_achieved'].append(\"did_you_say_please\")\n        if 'talk-talk-talk' not in session['achieved'] and hedy.all_commands(code, level, session['lang']).count(\"ask\") >= 5:\n            session['new_achieved'].append(\"talk-talk-talk\")\n        if 'hedy_honor' not in session['achieved'] and \"Hedy\" in code:\n            session['new_achieved'].append(\"hedy_honor\")\n        if 'hedy-ious' not in session['achieved']:\n            all_print_arguments = hedy.all_print_arguments(code, level, session['lang'])\n            for argument in all_print_arguments:\n                if all_print_arguments.count(argument) >= 10:\n                    session['new_achieved'].append(\"hedy-ious\")\n                    break\n\n    def check_response_achievements(self, code, response):\n        self.initialize_user_data_if_necessary()\n        if 'ninja_turtle' not in session['achieved'] and 'has_turtle' in response and response['has_turtle']:\n            session['new_achieved'].append(\"ninja_turtle\")\n        if 'watch_out' not in session['achieved'] and 'Warning' in response and response['Warning']:\n            session['new_achieved'].append(\"watch_out\")\n        if 'Error' in response and response['Error']:\n            session['consecutive_errors'] += 1\n            if session['previous_code'] == code:\n                if session['identical_consecutive_errors'] == 0:\n                    session['identical_consecutive_errors'] += 2 #We have to count the first one too!\n                else:\n                    session['identical_consecutive_errors'] += 1\n            if session['identical_consecutive_errors'] >= 3:\n                if 'programming_panic' not in session['achieved']:\n                    session['new_achieved'].append(\"programming_panic\")\n            session['previous_code'] = code\n        else:\n            if 'programming_protagonist' not in session['achieved'] and session['consecutive_errors'] >= 1:\n                session['new_achieved'].append(\"programming_protagonist\")\n            session['consecutive_errors'] = 0\n            session['identical_consecutive_errors'] = 0\n\n\n\n", "path": "website/achievements.py"}]}