Skip to content

Commit 002abee

Browse files
Extend regex1 lab exercise
Signed-off-by: David A. Wheeler <[email protected]>
1 parent d016212 commit 002abee

File tree

2 files changed

+155
-51
lines changed

2 files changed

+155
-51
lines changed

docs/labs/checker.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ function runSelftest() {
529529
let testAttempt = expected.slice(); // shallow copy of expected
530530
testAttempt[hint.index] = example;
531531
// What hint does our new testAttempt give?
532-
actualHint = findHint(testAttempt);
532+
actualHint = findHint(testAttempt, [hint.index]);
533533
if (actualHint != hint.text) {
534534
alert(`Lab Error: Unexpected hint!\n\nExample:\n${example}\n\nExpected hint:\n${hint.text}\n\nProduced hint:\n${actualHint}\n\nExpected (passing example)=${JSON.stringify(expected)}\n\ntestAttempt=${JSON.stringify(testAttempt)}\nFailing hint=${JSON.stringify(hint)}`);
535535
};

docs/labs/regex1.html

Lines changed: 154 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,43 @@
2828

2929
<!-- Sample expected answer -->
3030
<script id="expected1" type="plain/text">
31-
^(true|false)$
31+
^[A-Z]+$
3232
</script>
3333

3434
<!-- Full pattern of correct answer -->
3535
<script id="correct1" type="plain/text">
36+
\^
37+
\[A-Z\]
38+
(\+|\[A-Z\]\*)
39+
\$
40+
</script>
41+
42+
<!-- Sample expected answer -->
43+
<script id="expected2" type="plain/text">
44+
^(true|false)$
45+
</script>
46+
47+
<!-- Full pattern of correct answer -->
48+
<script id="correct2" type="plain/text">
3649
\^\((
3750
true\|false|
3851
false\|true
3952
)\)\$
4053
</script>
4154

55+
<!-- Sample expected answer -->
56+
<script id="expected3" type="plain/text">
57+
^[A-Z]+\Z
58+
</script>
59+
60+
<!-- Full pattern of correct answer -->
61+
<script id="correct3" type="plain/text">
62+
\^
63+
\[A-Z\]
64+
(\+|\[A-Z\]\*)
65+
\\Z
66+
</script>
67+
4268
<script id="info" type="application/yaml">
4369
---
4470
hints:
@@ -47,62 +73,95 @@
4773
text: For input validation, start with '^' to indicate a full match.
4874
examples:
4975
- - "(Y|N)"
76+
- present: |-
77+
\\[Zz]
78+
text: The ECMAScript (JavaScript) specification does not support \Z or \z.
79+
examples:
80+
- - "^Y|N\\z"
5081
- absent: |-
5182
\$$
5283
text: For input validation, end with '$' to indicate a full match.
5384
examples:
5485
- - "^(Y|N)"
86+
- absent: |-
87+
[\|\[]
88+
text: Consider using [YN], to match either a Y or an N.
89+
examples:
90+
- - "^$"
5591
- present: |-
5692
\|
5793
absent: |-
5894
\(
5995
text: If you use "|" you must parentheses or the precedence will be wrong.
6096
examples:
6197
- - "^Y|N$"
62-
# - - " query(),"
63-
# - present: query \( ["'`]id["'`] \) [^. ]
64-
# text: After query("id") use a period to invoke a verification method.
65-
# examples:
66-
# - - " query('id'),"
67-
# - present: "(isint|Isint|IsInt|ISINT)"
68-
# text: JavaScript is case-sensitive. Use isInt instead of the case you have.
69-
# examples:
70-
# - - " query('id').isint(),"
71-
# - - " query('id').IsInt(),"
72-
# - absent: isInt
73-
# text: Use isInt to determine if the parameter is an integer.
74-
# examples:
75-
# - - " query('id').,"
76-
# - present: ' query \( ["''`]id["''`] \).*\([^)]*$'
77-
# text: After query("id") you have an ( but there's no matching ).
78-
# examples:
79-
# - - " query('id').isInt(,"
80-
# - absent: isInt \(.*\)
81-
# text: isInt should be followed by (...).
82-
# examples:
83-
# - - " query('id').isInt,"
84-
# - present: "\\{[^}]*$"
85-
# text: You have started an object using { but there's no matching }.
86-
# examples:
87-
# - - " query('id').isInt({),"
88-
# - absent: isInt \( \{.*\} \)
89-
# text: Inside the parenthesis of isInt() you should have an object like {...}.
90-
# examples:
91-
# - - " query('id').isInt(),"
92-
# - absent: min
93-
# text: 'Use min: to specify a minimum value.'
94-
# examples:
95-
# - - " query('id').isInt({}),"
96-
# - absent: max
97-
# text: 'Use max: to specify a minimum value.'
98-
# examples:
99-
# - - " query('id').isInt({min: 1}),"
100-
# - present: max.*min
101-
# text: JavaScript allows hash entries to be in any order,
102-
# but this can be confusing to humans. Conventionally minimum values
103-
# are given before maximum values; please follow that convention.
104-
# examples:
105-
# - - " query('id').isInt({max: 9999, min: 1}),"
98+
- present: " "
99+
text: Spaces normally match spaces in a regex; do not use them in this case.
100+
examples:
101+
- - "^[YN] $"
102+
- absent: |-
103+
^\^
104+
index: 1
105+
text: For input validation, start with '^' to indicate a full match.
106+
# examples:
107+
# -
108+
# - "^[YN]$"
109+
# - ""
110+
- absent: |-
111+
\$$
112+
index: 1
113+
text: For input validation, end with '$' to indicate a full match.
114+
# examples:
115+
# -
116+
# - "^[YN]$"
117+
# - "^"
118+
- absent: |-
119+
\[A-Z\]
120+
index: 1
121+
text: You can use [A-Z] to match one uppercase Latin letter (A through Z).
122+
# examples:
123+
# -
124+
# - "^[YN]$"
125+
# - "^$"
126+
- present: |-
127+
\^\[A-Z\]\*
128+
index: 1
129+
text: A "*" matches one or more, not one or more.
130+
- present: |-
131+
\(
132+
index: 1
133+
text: You do not need parentheses to solve this problem.
134+
- absent: |-
135+
(\[A-Z\]\+|
136+
\[A-Z\]\[A-Z\]\*)
137+
index: 1
138+
text: You can use [A-Z]+ to match one or more uppercase Latin letters.
139+
# examples:
140+
# -
141+
# - "^[YN]$"
142+
# - "^[A-Z]$"
143+
- present: "True"
144+
index: 2
145+
text: Regular expressions are case-sensitive by default; use "true".
146+
- present: "False"
147+
index: 2
148+
text: Regular expressions are case-sensitive by default; use "false".
149+
- absent: |-
150+
\|
151+
index: 2
152+
text: Use "|" to express alternatives.
153+
- absent: |-
154+
\(
155+
index: 2
156+
text: Use parentheses.
157+
- present: |-
158+
\$
159+
index: 3
160+
text: This is Python, not ECMAScript (JavaScript). Use \Z at the end, not $.
161+
- present: |-
162+
\\z
163+
index: 3
164+
text: This is Python. Use \Z at the end, not \z.
106165
# successes:
107166
# - - " query ( 'id' ) . isInt ( {min: 1 , max: 9999 } ) ,"
108167
# - - " query ( `id` ) . isInt ( {min: 1 , max: 9_999 } ) , "
@@ -142,11 +201,16 @@ <h1>Lab Exercise regex1</h1>
142201
<p>
143202
<h2>Task</h2>
144203
<p>
145-
<b>Please create various regex patterns that meet the criteria below.</b>
204+
<b>Please create various regular expression (regex) patterns
205+
that meet the criteria below.</b>
146206

147207
<p>
148208
<h2>Background</h2>
149209
<p>
210+
Regular expressions (regexes) are a widely-used notation for
211+
expressing text patterns.
212+
Regexes can be used to validate input; when used correctly,
213+
they can counter many attacks.
150214

151215
<p>
152216
<h2>Task Information</h2>
@@ -157,7 +221,7 @@ <h2>Interactive Lab (<span id="grade"></span>)</h2>
157221

158222
<h3>Part 1</h2>
159223
<p>
160-
Create a regular expression, for use in JavaScript,
224+
Create a regular expression, for use in ECMAScript (JavaScript),
161225
that only matches the letters "Y" or "N".
162226
<!--
163227
You can use this an example for new labs.
@@ -175,8 +239,8 @@ <h3>Part 1</h2>
175239

176240
<h3>Part 2</h2>
177241
<p>
178-
Create a regular expression, for use in JavaScript,
179-
that only matches the words "true" or "false".
242+
Create a regular expression, for use in ECMAScript (JavaScript),
243+
that only matches one or more uppercase Latin letters (A through Z).
180244
<!--
181245
You can use this an example for new labs.
182246
For multi-line inputs, instead of <input id="attempt0" type="text" ...>, use
@@ -189,11 +253,51 @@ <h3>Part 2</h2>
189253
<button type="button" class="hintButton">Hint</button>
190254
<button type="button" class="resetButton">Reset</button>
191255
<button type="button" class="giveUpButton">Give up</button>
256+
</form>
257+
258+
<h3>Part 3</h2>
259+
<p>
260+
Create a regular expression, for use in ECMAScript (JavaScript),
261+
that only matches the words "true" or "false".
262+
<!--
263+
You can use this an example for new labs.
264+
For multi-line inputs, instead of <input id="attempt0" type="text" ...>, use
265+
<textarea id="attempt" rows="2" cols="70">...</textarea>
266+
-->
267+
<form id="lab3">
268+
<pre></code>
269+
<input id="attempt2" type="text" size="70" spellcheck="false" value="">
270+
</code></pre>
271+
<button type="button" class="hintButton">Hint</button>
272+
<button type="button" class="resetButton">Reset</button>
273+
<button type="button" class="giveUpButton">Give up</button>
274+
</form>
275+
276+
<h3>Part 4</h2>
277+
<p>
278+
Create a regular expression
279+
that only matches one or more uppercase Latin letters (A through Z).
280+
However, this time, do it for Python (not JavaScript).
281+
<!--
282+
You can use this an example for new labs.
283+
For multi-line inputs, instead of <input id="attempt0" type="text" ...>, use
284+
<textarea id="attempt" rows="2" cols="70">...</textarea>
285+
-->
286+
<form id="lab4">
287+
<pre></code>
288+
<input id="attempt3" type="text" size="70" spellcheck="false" value="">
289+
</code></pre>
290+
<button type="button" class="hintButton">Hint</button>
291+
<button type="button" class="resetButton">Reset</button>
292+
<button type="button" class="giveUpButton">Give up</button>
293+
</form>
294+
295+
296+
192297
<br><br><!-- These go in the last form if there's more than one: -->
193298
<pre id="correctStamp"></pre>
194299
<textarea id="debugData" class="displayNone" rows="20" cols="70" readonly>
195300
</textarea>
196-
</form>
197301

198302
</div><!-- End GitHub pages formatting -->
199303
</body>

0 commit comments

Comments
 (0)