Skip to content

Commit 8c6cb03

Browse files
committed
Add Quiz
1 parent 723ae56 commit 8c6cb03

File tree

3 files changed

+240
-0
lines changed

3 files changed

+240
-0
lines changed

docs/banner.gif

360 KB
Loading

docs/index.html

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<link rel="icon" type="image/png" href="lj.png" />
5+
<title>LiquidJava Quiz</title>
6+
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
7+
<meta charset="utf-8">
8+
<style>
9+
body {
10+
font-family: sans-serif;
11+
}
12+
code, pre {
13+
font-family: monospace;
14+
}
15+
h1 code,
16+
h2 code,
17+
h3 code,
18+
h4 code,
19+
h5 code,
20+
h6 code {
21+
font-size: inherit;
22+
}
23+
ul li {
24+
list-style-type: none;
25+
}
26+
27+
code {
28+
background-color: #e0f2fe;
29+
color: #0369a1;
30+
padding: 2px 6px;
31+
border-radius: 4px;
32+
}
33+
34+
.btns-container {
35+
display: flex;
36+
justify-content: center;
37+
align-items: center;
38+
gap: 10px;
39+
}
40+
</style>
41+
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
42+
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
43+
crossorigin="anonymous"></script>
44+
</head>
45+
<body>
46+
47+
<div class="container">
48+
<div class="form-row">
49+
<div class="container">
50+
<br />
51+
<h1>LiquidJava Quiz</h1>
52+
<img src="banner.gif" alt="LiquidJava Banner"/>
53+
<hr>
54+
<ol>
55+
<li>
56+
<p>Liquid types allow developers to catch bugs at:</p>
57+
<ul class="radio-list">
58+
<li><label><input type="radio" data-question="1" data-content="0" /> Execution time</label></li>
59+
<li><label><input type="radio" data-question="0" data-content="1" /> Compile time</label></li>
60+
<li><label><input type="radio" data-question="1" data-content="0" /> Deployment time</label></li>
61+
<li><label><input type="radio" data-question="1" data-content="0" /> Testing time</label></li>
62+
</ul>
63+
</li>
64+
<li>
65+
<p>Liquid types can prevent bugs such as (select multiple):</p>
66+
<ul class="checklist">
67+
<li><label><input type="checkbox" data-question="0" data-content="1" /> Array index out of bounds</label></li>
68+
<li><label><input type="checkbox" data-question="0" data-content="1" /> Null pointer exceptions</label></li>
69+
<li><label><input type="checkbox" data-question="1" data-content="0" /> Memory leaks</label></li>
70+
<li><label><input type="checkbox" data-question="0" data-content="1" /> Division by zero</label></li>
71+
</ul>
72+
</li>
73+
<li>
74+
<p>In LiquidJava, what integer values for <code>x</code> are allowed with this refinement? <code>@Refinement("x &gt; 0")</code></p>
75+
<ul class="radio-list">
76+
<li><label><input type="radio" data-question="1" data-content="0" /> All values</label></li>
77+
<li><label><input type="radio" data-question="1" data-content="0" /> All negative values</label></li>
78+
<li><label><input type="radio" data-question="1" data-content="0" /> All non-negative values</label></li>
79+
<li><label><input type="radio" data-question="0" data-content="1" /> All positive values</label></li>
80+
</ul>
81+
</li>
82+
<li>
83+
<p>In LiquidJava, it's possible to refine method parameters and return values.</p>
84+
<ul class="checklist">
85+
<li><label><input type="checkbox" data-question="0" data-content="1" /> True</label></li>
86+
<li><label><input type="checkbox" data-question="1" data-content="0" /> False</label></li>
87+
</ul>
88+
</li>
89+
<li>
90+
<p>In LiquidJava, which of the following is <strong>not</strong> a valid refinement?</p>
91+
<ul class="radio-list">
92+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@Refinement("x == 1 || x == -1")</code></label></li>
93+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@Refinement("x &gt; 0")</code></label></li>
94+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@Refinement("x % 2 == 0")</code></label></li>
95+
<li><label><input type="radio" data-question="0" data-content="1" /> <code>@Refinement("x + 1")</code></label></li>
96+
</ul>
97+
</li>
98+
<li>
99+
<p>In LiquidJava, to specify that a method should only be called when in the <code>open</code> state, we should use:</p>
100+
<ul class="radio-list">
101+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@StateRefinement("state == 'open'")</code></label></li>
102+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@Refinement("state == 'open'")</code></label></li>
103+
<li><label><input type="radio" data-question="0" data-content="1" /> <code>@StateRefinement(from="open(this)")</code></label></li>
104+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@State("open")</code></label></li>
105+
</ul>
106+
</li>
107+
<li>
108+
<p>In LiquidJava, what does the following state refinement mean? <code>@StateRefinement(from="!closed(this)", to="closed(this)")</code></p>
109+
<ul class="radio-list">
110+
<li><label><input type="radio" data-question="1" data-content="0" /> The method can only be called when the object is closed and will leave it closed.</label></li>
111+
<li><label><input type="radio" data-question="1" data-content="0" /> The method can only be called when the object is open and will leave it open.</label></li>
112+
<li><label><input type="radio" data-question="0" data-content="1" /> The method can only be called when the object is not closed and will leave it closed.</label></li>
113+
<li><label><input type="radio" data-question="1" data-content="0" /> The method can be called in any state and will leave it closed.</label></li>
114+
</ul>
115+
</li>
116+
<li>
117+
<p>In LiquidJava, the <code>@ExternalRefinementsFor</code> annotation is used to:</p>
118+
<ul class="radio-list">
119+
<li><label><input type="radio" data-question="1" data-content="0" /> Import refinements from external libraries</label></li>
120+
<li><label><input type="radio" data-question="0" data-content="1" /> Define new refinements for an external class</label></li>
121+
<li><label><input type="radio" data-question="1" data-content="0" /> Export refinements to other modules</label></li>
122+
<li><label><input type="radio" data-question="1" data-content="0" /> None of the above</label></li>
123+
</ul>
124+
</li>
125+
<li>
126+
<p>In LiquidJava, a ghost variable is used to:</p>
127+
<ul class="radio-list">
128+
<li><label><input type="radio" data-question="1" data-content="0" /> Store temporary data during method execution</label></li>
129+
<li><label><input type="radio" data-question="0" data-content="1" /> Represent abstract properties of objects to be used in refinements</label></li>
130+
<li><label><input type="radio" data-question="1" data-content="0" /> To track memory usage</label></li>
131+
<li><label><input type="radio" data-question="1" data-content="0" /> To replace regular variables for better performance</label></li>
132+
</ul>
133+
</li>
134+
<li>
135+
<p>In LiquidJava, which of the following refinements updates the ghost variable <code>size</code>?</p>
136+
<ul class="radio-list">
137+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@Refinement("size = 0")</code></label></li>
138+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@StateRefinement(to="size(this) == size(old(this))")</code></label></li>
139+
<li><label><input type="radio" data-question="1" data-content="0" /> <code>@Refinement("size++")</code></label></li>
140+
<li><label><input type="radio" data-question="0" data-content="1" /> <code>@StateRefinement(to="size(this) == size(old(this)) + 1")</code></label></li>
141+
</ul>
142+
</li>
143+
</ol>
144+
</div>
145+
</div>
146+
<div id="tg-msg" class="alert" role="alert" style="display: none">
147+
<span id="tg-correct-questions"></span> Correct! <br /><b>Rating: <span id="tg-score"></span>%</b>
148+
</div>
149+
<div class="row btns-container">
150+
<button id="check-questions" class="btn btn-md btn-success">Check Answers</button>
151+
<button id="reset-questions" class="btn btn-link">Reset All</button>
152+
</div>
153+
<br />
154+
<script type="text/javascript">$(function(){
155+
$('ul.radio-list,ul.checklist,ul.textbox').each(function(i, el){
156+
var questionClass = $(this).attr('class');
157+
$(this).parent().addClass('question-row').addClass(questionClass);
158+
if (questionClass=='radio-list') {
159+
$(this).find('input[type="radio"]').attr('name', 'radio-question-' + i);
160+
}
161+
});
162+
163+
function checkQuestion() {
164+
resetQuestions(true);
165+
var questions = $('li.question-row');
166+
var total_questions = questions.length;
167+
var correct = 0;
168+
169+
questions.each(function(i, el) {
170+
var self = $(this);
171+
// Single Question.
172+
if (self.hasClass('radio-list')) {
173+
if (self.find('input[type="radio"][data-content="1"]:checked').length == 1) {
174+
correct += 1;
175+
} else {
176+
self.addClass('text-danger');
177+
}
178+
}
179+
// Textbox Question.
180+
if(self.hasClass('textbox')) {
181+
var textbox = self.find('input[type="text"]');
182+
var correct_text = String(textbox.data("content")).trim().split("").reverse().join("");
183+
if(String(textbox.val()).trim().toLowerCase()==correct_text.toLowerCase()) {
184+
correct += 1;
185+
} else {
186+
self.addClass('text-danger');
187+
textbox.parent().find("i.text-correct").html(correct_text);
188+
}
189+
}
190+
// Multiple selection Questions.
191+
if(self.hasClass('checklist')) {
192+
var total_corrects = self.find('input[type="checkbox"][data-content="1"]').length;
193+
var total_incorrects = self.find('input[type="checkbox"][data-content="0"]').length;
194+
var correct_selected = self.find('input[type="checkbox"][data-content="1"]:checked').length;
195+
var incorrect_selected = self.find('input[type="checkbox"][data-content="0"]:checked').length;
196+
var qc = +((correct_selected / total_corrects) - (incorrect_selected/total_incorrects)).toFixed(2);
197+
if (qc < 0) {
198+
qc = 0;
199+
}
200+
correct += qc;
201+
if (qc == 0) {
202+
self.addClass('text-danger');
203+
} else if (qc > 0 && qc < 1) {
204+
self.addClass('text-warning');
205+
}
206+
}
207+
});
208+
209+
showScore(correct, total_questions);
210+
}
211+
212+
function showScore(correct, total) {
213+
var score = (correct / total).toFixed(2) * 100;
214+
var msgClass = 'alert-danger';
215+
if (score >= 70) {
216+
msgClass = 'alert-success';
217+
} else if (score >= 50) {
218+
msgClass = 'alert-warning';
219+
}
220+
$('#tg-correct-questions').text(correct + ' out of ' + total);
221+
$('#tg-score').text(score);
222+
$('#tg-msg').addClass(msgClass).show();
223+
}
224+
function resetQuestions(keep) {
225+
$('li.question-row').removeClass('text-danger').removeClass('text-warning');
226+
$('i.text-correct').html('');
227+
$('#tg-msg').removeClass('alert-danger').removeClass('alert-success').removeClass('alert-warning').hide();
228+
if(keep === true) {
229+
return;
230+
}
231+
$('li.question-row').find('input[type="text"]').val('');
232+
$('li.question-row').find('input[type="radio"],input[type="checkbox"]').prop('checked', false);
233+
}
234+
$('#check-questions').on('click', checkQuestion);
235+
$('#reset-questions').on('click', resetQuestions);
236+
237+
});</script>
238+
</div>
239+
</body>
240+
</html>

docs/lj.png

20 KB
Loading

0 commit comments

Comments
 (0)