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 > 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 > 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 >
0 commit comments