1+ import { pythonURI , fetchOptions } from '../../assets/js/api/config.js' ;
2+ const quizGradingsApi = `${ pythonURI } /api/quizgrading` ;
3+
4+ const Questions = [
5+ {
6+ question : "What does an arithmetic shift do?" ,
7+ answers : {
8+ a : "All bits are deleted" ,
9+ b : "The bits not shifted are discarded" ,
10+ c : "The bits that are shifted out of either end are discarded" ,
11+ d : "Nothing changes"
12+ } ,
13+ correctAnswer : "c"
14+ } ,
15+ {
16+ question : "What is the binary equivalent of the decimal number 5?" ,
17+ answers : {
18+ a : "101" ,
19+ b : "001" ,
20+ c : "100" ,
21+ d : "1001"
22+ } ,
23+ correctAnswer : "a"
24+ } ,
25+ {
26+ question : "What is binary addition result of 1011 + 1101?" ,
27+ answers : {
28+ a : "2112" ,
29+ b : "10100" ,
30+ c : "11000" ,
31+ d : "00111"
32+ } ,
33+ correctAnswer : "c"
34+ } ,
35+ {
36+ question : "Which encoding standard allows for more characters?" ,
37+ answers : {
38+ a : "ASCII" ,
39+ b : "Unicode" ,
40+ } ,
41+ correctAnswer : "b"
42+ } ,
43+ {
44+ question : "In a 4-bit two's complement system, what is the representation of -5?" ,
45+ answers : {
46+ a : "1011" ,
47+ b : "1101" ,
48+ c : "1110" ,
49+ d : "1100"
50+ } ,
51+ correctAnswer : "b"
52+ } ,
53+ {
54+ question : "How many bits are used to represent an ASCII character?" ,
55+ answers : {
56+ a : "7" ,
57+ b : "16" ,
58+ c : "32" ,
59+ d : "8"
60+ } ,
61+ correctAnswer : "d"
62+ } ,
63+ {
64+ question : "What is the binary representation of the decimal number 13?" ,
65+ answers : {
66+ a : "1010" ,
67+ b : "1100" ,
68+ c : "1101" ,
69+ d : "1011"
70+ } ,
71+ correctAnswer : "c"
72+ } ,
73+ {
74+ question : "What happens during a left arithmetic shift?" ,
75+ answers : {
76+ a : "Zeroes are shifted to the right" ,
77+ b : "Zeroes are shifted to the left" ,
78+ c : "Zeroes are deleted" ,
79+ d : "Ones are shifted to the right"
80+ } ,
81+ correctAnswer : "a"
82+ } ,
83+ {
84+ question : "What is the binary addition result of 1001 + 0110?" ,
85+ answers : {
86+ a : "10110" ,
87+ b : "01101" ,
88+ c : "1111" ,
89+ d : "10001"
90+ } ,
91+ correctAnswer : "c"
92+ } ,
93+ {
94+ question : "What is the binary subtraction result of 1011 - 0101?" ,
95+ answers : {
96+ a : "0110" ,
97+ b : "1000" ,
98+ c : "0101" ,
99+ d : "0011"
100+ } ,
101+ correctAnswer : "c"
102+ }
103+ ] ;
104+
105+ function getRandomInt ( max ) {
106+ return Math . floor ( Math . random ( ) * max ) ;
107+ }
108+
109+ function randomizeQuestions ( questions , numQuestions ) {
110+ const shuffledQuestions = [ ...questions ] ;
111+ for ( let i = shuffledQuestions . length - 1 ; i > 0 ; i -- ) {
112+ const j = getRandomInt ( i + 1 ) ;
113+ [ shuffledQuestions [ i ] , shuffledQuestions [ j ] ] = [ shuffledQuestions [ j ] , shuffledQuestions [ i ] ] ;
114+ }
115+ return shuffledQuestions . slice ( 0 , numQuestions ) ;
116+ }
117+
118+ function buildQuiz ( questions ) {
119+ const quizContainer = document . getElementById ( 'quiz' ) ;
120+ const output = [ ] ;
121+ questions . forEach ( ( currentQuestion , questionNumber ) => {
122+ const answers = [ ] ;
123+ for ( let letter in currentQuestion . answers ) {
124+ answers . push (
125+ `<label>
126+ <input type="radio" name="question${ questionNumber } " value="${ letter } ">
127+ ${ letter } :
128+ ${ currentQuestion . answers [ letter ] }
129+ </label>`
130+ ) ;
131+ }
132+ output . push (
133+ `<div class="question">${ currentQuestion . question } </div>
134+ <div class="answers">${ answers . join ( '' ) } </div>`
135+ ) ;
136+ } ) ;
137+ quizContainer . innerHTML = output . join ( '' ) ;
138+ }
139+
140+ function showResults ( questions ) {
141+ const quizContainer = document . getElementById ( 'quiz' ) ;
142+ const answerContainers = quizContainer . querySelectorAll ( '.answers' ) ;
143+ let numCorrect = 0 ;
144+ questions . forEach ( ( currentQuestion , questionNumber ) => {
145+ const answerContainer = answerContainers [ questionNumber ] ;
146+ const selector = `input[name=question${ questionNumber } ]:checked` ;
147+ const userAnswer = ( answerContainer . querySelector ( selector ) || { } ) . value ;
148+ if ( userAnswer === currentQuestion . correctAnswer ) {
149+ numCorrect ++ ;
150+ answerContainers [ questionNumber ] . style . color = 'green' ;
151+ } else {
152+ answerContainers [ questionNumber ] . style . color = 'red' ;
153+ }
154+ } ) ;
155+ const resultsContainer = document . getElementById ( 'results' ) ;
156+ resultsContainer . innerHTML = `${ numCorrect } out of ${ questions . length } ` ;
157+
158+ // Send the attempt data to the backend
159+ const attemptData = {
160+ quizgrade : numCorrect ,
161+ attempt : new Date ( ) . toISOString ( )
162+ } ;
163+
164+ fetch ( "http://localhost:8887/api/quizgrading" , {
165+ method : "POST" ,
166+ headers : {
167+ "Content-Type" : "application/json"
168+ } ,
169+ body : JSON . stringify ( attemptData )
170+ } )
171+ . then ( response => response . json ( ) )
172+ . then ( data => {
173+ console . log ( "Score stored successfully:" , data ) ;
174+ loadAttempts ( ) ; // Reload attempts after submission
175+ } )
176+ . catch ( error => {
177+ console . error ( "Error storing score:" , error ) ;
178+ } ) ;
179+ }
180+
181+ function deleteAttempt ( id ) {
182+ fetch ( `${ quizGradingsApi } /${ id } ` , {
183+ method : "DELETE" ,
184+ headers : {
185+ "Content-Type" : "application/json"
186+ }
187+ } )
188+ . then ( response => response . json ( ) )
189+ . then ( data => {
190+ console . log ( "attempt deleted" , data . message ) ;
191+ loadAttempts ( ) ; // Reload attempts after deletion
192+ } )
193+ . catch ( error => {
194+ console . error ( "Error deleting score:" , error ) ;
195+ } ) ;
196+ }
197+
198+ async function loadAttempts ( ) {
199+ const quizGrading = await fetch ( quizGradingsApi , fetchOptions )
200+ if ( ! quizGrading . ok ) { console . error ( "Error loading attempts:" , quizGrading ) ; }
201+
202+ const quizResults = await quizGrading . json ( ) ;
203+ console . log ( quizResults )
204+
205+ // Finds table body and clears existing rows, then replaces it with data
206+ const tableBody = document . getElementById ( 'attemptsTable' ) ;
207+ tableBody . innerHTML = '' ; // Clear existing rows
208+ quizResults . forEach ( attempt => {
209+ const row = document . createElement ( 'tr' ) ;
210+ const idCell = document . createElement ( 'td' )
211+ idCell . innerHTML = attempt . id ;
212+ const quizgradeCell = document . createElement ( 'td' )
213+ quizgradeCell . innerHTML = attempt . quizgrade ;
214+ const attemptCell = document . createElement ( 'td' )
215+ attemptCell . innerHTML = attempt . attempt ;
216+ const actionCell = document . createElement ( 'td' ) ;
217+ const deleteButton = document . createElement ( 'button' )
218+ deleteButton . innerHTML = 'Delete' ;
219+ deleteButton . addEventListener ( 'click' , ( ) => deleteAttempt ( attempt . id ) ) ;
220+ const editButton = document . createElement ( 'button' )
221+ editButton . innerHTML = 'Edit' ;
222+ editButton . addEventListener ( 'click' , ( ) => editAttempt ( attempt . id ) ) ;
223+ row . append ( idCell ) ;
224+ row . append ( quizgradeCell ) ;
225+ row . append ( attemptCell ) ;
226+ row . append ( actionCell ) ;
227+ actionCell . append ( deleteButton ) ;
228+ actionCell . append ( editButton ) ;
229+ tableBody . append ( row ) ;
230+ } ) ;
231+ }
232+
233+ function editAttempt ( id ) {
234+ const quizgrade = prompt ( "Enter new quiz grade:" ) ;
235+ const attempt = prompt ( "Enter new attempt number:" ) ;
236+ if ( quizgrade && attempt ) {
237+ fetch ( `${ quizGradingsApi } /${ id } ` , {
238+ method : "PUT" ,
239+ headers : { "Content-Type" : "application/json" } ,
240+ body : JSON . stringify ( { id, quizgrade, attempt } ) ,
241+ } )
242+ . then ( ( response ) => response . json ( ) )
243+ . then ( ( data ) => {
244+ console . log ( "Attempt updated:" , data ) ;
245+ loadAttempts ( ) ; // Reload table
246+ } )
247+ . catch ( ( error ) => console . error ( "Error updating attempt:" , error ) ) ;
248+ }
249+ }
250+
251+ function createAttempt ( ) {
252+ const quizgrade = prompt ( "Enter quiz grade:" ) ;
253+ const attempt = prompt ( "Enter attempt number:" ) ;
254+ if ( quizgrade && attempt ) {
255+ fetch ( quizGradingsApi , {
256+ method : "POST" ,
257+ headers : { "Content-Type" : "application/json" } ,
258+ body : JSON . stringify ( { quizgrade, attempt } ) ,
259+ } )
260+ . then ( ( response ) => response . json ( ) )
261+ . then ( ( data ) => {
262+ console . log ( "Attempt created:" , data ) ;
263+ loadAttempts ( ) ; // Reload table
264+ } )
265+ . catch ( ( error ) => console . error ( "Error creating attempt:" , error ) ) ;
266+ }
267+ }
268+
269+ window . onload = ( ) => {
270+ const selectedQuestions = randomizeQuestions ( Questions , 5 ) ;
271+ buildQuiz ( selectedQuestions ) ;
272+ loadAttempts ( ) ;
273+
274+ document . getElementById ( 'submit' ) . addEventListener ( 'click' , ( ) => {
275+ showResults ( selectedQuestions ) ;
276+ } ) ;
277+
278+ document . getElementById ( 'createAttempt' ) . addEventListener ( 'click' , ( ) => {
279+ createAttempt ( ) ;
280+ } ) ;
281+ } ;
0 commit comments