Skip to content

Commit 533fd9c

Browse files
better error handling, corrected question typos
1 parent c74cd89 commit 533fd9c

File tree

2 files changed

+43
-28
lines changed

2 files changed

+43
-28
lines changed

interactive_exercises/questions.json

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@
247247
"always X",
248248
"a X"
249249
],
250-
"Reference solution": "re.sub(r'test.+', r'X', flags=re.I)"
250+
"Reference solution": "re.sub(r'test.+', r'X', s, flags=re.I)"
251251
},
252252
"15": {
253253
"question": "Split the given input strings to get the corresponding output as shown below.",
@@ -423,7 +423,7 @@
423423
"right column": [
424424
"redo X credible :X: rod X"
425425
],
426-
"Reference solution": "re.sub(r'\\bre[ae]?d\\b', 'X', s)"
426+
"Reference solution": "re.sub(r'\\bre[ae]?d\\b', r'X', s)"
427427
},
428428
"25": {
429429
"question": "Change whole words starting with `hand` and ending with `s` or `y` or `le` to `X.",
@@ -540,9 +540,15 @@
540540
"flags": "0",
541541
"function": "re.split",
542542
"left column": [
543+
"food:good",
544+
"food:good-cool",
545+
"food:good-cool;tool",
543546
"42:no-op;10:car-tr:u-ck;SQ1"
544547
],
545548
"right column": [
549+
"['food:good']",
550+
"['food:good-cool']",
551+
"['food', 'cool', 'tool']",
546552
"['42', 'op', '10', 'tr:u-ck', 'SQ1']"
547553
],
548554
"Reference solution": "re.split(r':[^-]+-([^;]+);', s)"
@@ -557,7 +563,7 @@
557563
"right column": [
558564
"a\n1<> b 2<>"
559565
],
560-
"Reference solution": "re.sub(r'<[^>]+>', s)"
566+
"Reference solution": "re.sub(r'<[^>]+>', r'', s)"
561567
},
562568
"34": {
563569
"question": "Match strings whose first non-whitespace character is not a `#` character. Any string made up of only whitespace characters should not be matched.",
@@ -611,7 +617,7 @@
611617
"right column": [
612618
"X not X X X took X"
613619
],
614-
"Reference solution": "re.sub(r'\\b(\\w|(\\w)\\w*\\2)\\b', 'X', s, flags=re.I)"
620+
"Reference solution": "re.sub(r'\\b(\\w|(\\w)\\w*\\2)\\b', r'X', s, flags=re.I)"
615621
},
616622
"38": {
617623
"question": "Convert the given markdown anchors to hyperlinks as shown below.",
@@ -729,7 +735,7 @@
729735
"{{cherry-200",
730736
"2-42"
731737
],
732-
"Reference solution": "re.search(r'\\A({{)?[a-z]+-\\d+(?(1)}})\\Z', w)"
738+
"Reference solution": "re.search(r'\\A({{)?[a-z]+-\\d+(?(1)}})\\Z', s)"
733739
},
734740
"46": {
735741
"question": "Replace all whole words with `X` unless it is preceded by `(` character.",
@@ -743,7 +749,7 @@
743749
"(apple) X X)",
744750
"X (mango) (grape"
745751
],
746-
"Reference solution": "re.sub(r'(?<!\\()\\b\\w+', 'X', s)"
752+
"Reference solution": "re.sub(r'(?<!\\()\\b\\w+', r'X', s)"
747753
},
748754
"47": {
749755
"question": "Replace all whole words with `X` unless it is followed by `)` character.",
@@ -757,7 +763,7 @@
757763
"(apple) X berry)",
758764
"X (mango) (X"
759765
],
760-
"Reference solution": "re.sub(r'\\b\\w+\\b(?!\\))', 'X', s)"
766+
"Reference solution": "re.sub(r'\\b\\w+\\b(?!\\))', r'X', s)"
761767
},
762768
"48": {
763769
"question": "Replace all whole words with `X` unless it is preceded by `(` or followed by `)` characters.",
@@ -771,7 +777,7 @@
771777
"(apple) X berry)",
772778
"X (mango) (grape"
773779
],
774-
"Reference solution": "re.sub(r'(?<!\\()\\b\\w+\\b(?!\\))', 'X', s)"
780+
"Reference solution": "re.sub(r'(?<!\\()\\b\\w+\\b(?!\\))', r'X', s)"
775781
},
776782
"49": {
777783
"question": "Extract all whole words that do not end with `e` or `n`.",
@@ -875,7 +881,7 @@
875881
"hello,nice ice,42,2",
876882
"1,,stall small"
877883
],
878-
"Reference solution": "re.sub(r'(?<![^,])\\s+|\\s+(?![^,])', s)"
884+
"Reference solution": "re.sub(r'(?<![^,])\\s+|\\s+(?![^,])', r'', s)"
879885
},
880886
"56": {
881887
"question": "Match strings that satisfy all of these rules:\n* at least two alphabets\n* at least 3 digits\n* doesn't end with a whitespace character",
@@ -995,7 +1001,7 @@
9951001
"But Cool Te",
9961002
"it this ."
9971003
],
998-
"Reference solution": "re.sub(r'hat.*it', r'', flags=re.S|re.I)"
1004+
"Reference solution": "re.sub(r'hat.*it', r'', s, flags=re.S|re.I)"
9991005
},
10001006
"64": {
10011007
"question": "Delete from `start` if it is at the beginning of a line up to the next occurrence of the `end` at the end of a line. Match these markers case insensitively.",

interactive_exercises/regex_practice.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import json
2+
import os
23
import re
34
import sys
45
import tkinter as tk
56
from tkinter import ttk
7+
from tkinter.messagebox import showwarning, showerror
68

79
class Root(tk.Tk):
810
def __init__(self):
@@ -143,7 +145,6 @@ def create_button_frame(self):
143145

144146
def initialize(self):
145147
self.format = {0: str, 1: repr}
146-
self.format_change = {0: eval, 1: repr}
147148
self.previous_format = self.test_string_format.get()
148149

149150
self.progress_file = 'user_progress.json'
@@ -153,27 +154,29 @@ def initialize(self):
153154
except FileNotFoundError:
154155
self.user_progress = {}
155156

156-
# todo: handle FileNotFoundError
157157
with open('questions.json') as f:
158158
all_questions = json.load(f)
159159
self.questions = tuple(v for k, v in all_questions.items())
160160
self.question_count = len(self.questions)
161161

162162
self.question_idx = 0
163-
try:
164-
self.question_idx = int(sys.argv[1]) - 1
165-
except (IndexError, ValueError):
166-
# todo: find a better way
167-
pass
168-
else:
169-
if self.question_idx < 0:
170-
self.question_idx = 0
171-
elif self.question_idx >= self.question_count:
172-
self.question_idx = self.question_count - 1
163+
if len(sys.argv) == 2:
164+
try:
165+
self.question_idx = int(sys.argv[1]) - 1
166+
except ValueError:
167+
showwarning("Warning!",
168+
("Couldn't convert cli argument to integer!"
169+
"\n\nDefault question will be shown"))
170+
else:
171+
if self.question_idx < 0:
172+
self.question_idx = 0
173+
elif self.question_idx >= self.question_count:
174+
self.question_idx = self.question_count - 1
173175

174176
self.display_question(self.questions[self.question_idx])
175177
# skip already answered questions
176-
for idx in range(self.question_count):
178+
# selecting already answered question (via sys.argv[1]) is also skipped!
179+
for idx in range(self.question_idx, self.question_count):
177180
progress_key = str(idx)
178181
if self.user_progress.get(progress_key, ('', '', 0, False))[3]:
179182
self.next()
@@ -248,8 +251,11 @@ def change_format(self):
248251
new_format = self.test_string_format.get()
249252
if new_format != self.previous_format:
250253
self.previous_format = new_format
251-
for label in self.l_test_strings:
252-
label['text'] = self.format_change[new_format](label['text'])
254+
fmt_func = self.format[new_format]
255+
for row, t in enumerate(zip(self.left_col, self.right_col)):
256+
idx = row * 2
257+
self.l_test_strings[idx]['text'] = fmt_func(t[0])
258+
self.l_test_strings[idx + 1]['text'] = fmt_func(t[1])
253259

254260
def next(self, previous=False):
255261
self.save_progress()
@@ -355,7 +361,10 @@ def quit(self):
355361
self.destroy()
356362

357363
if __name__ == '__main__':
358-
root = Root()
359-
root.protocol('WM_DELETE_WINDOW', root.quit)
360-
root.mainloop()
364+
if not os.path.isfile('questions.json'):
365+
showerror("Error!", "questions.json not found!")
366+
else:
367+
root = Root()
368+
root.protocol('WM_DELETE_WINDOW', root.quit)
369+
root.mainloop()
361370

0 commit comments

Comments
 (0)