1
- < head >
2
- < meta name =" viewport " content =" width=device-width, initial-scale=1 " />
3
- < link
4
- rel =" stylesheet "
5
- href =" https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.15/codemirror.min.css "
6
- />
1
+ {% extends "base.html" %}
2
+
3
+ {% block head %}
4
+ {{ super() }}
5
+
6
+ < link rel =" stylesheet " href =" https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.15/codemirror.min.css " />
7
7
< script src ="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.15/codemirror.min.js "> </ script >
8
8
< script src ="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.15/mode/python/python.min.js "> </ script >
9
- < style >
10
- html {
11
- font-size : 1.2rem ;
9
+ < title > Python Type Challenge - {{ name }}</ title >
10
+
11
+ < style type ="text/css ">
12
+ .challenge-container {
13
+ display : flex;
14
+ padding : 1rem 2rem ;
15
+ justify-content : center;
16
+ max-height : 100vh ;
17
+ width : max (80vw , 80% );
18
+ }
19
+
20
+ /* Sidebar Area */
21
+ .sidebar-container {
22
+ display : flex;
23
+ flex-direction : column;
24
+ align-items : center;
25
+ margin-right : 2rem ;
26
+ }
27
+
28
+ .sidebar-container .sidebar-challenge-list {
29
+ overflow-y : auto;
30
+ max-width : fit-content;
31
+ min-width : 100px ;
12
32
}
13
33
14
- .container {
34
+ .sidebar- container . sidebar-actions {
15
35
display : flex;
16
- flex-direction : row;
17
36
justify-content : center;
18
- margin : 0 auto;
37
+ width : 100% ;
38
+ align-items : center;
39
+ margin-top : 8px ;
40
+ padding-top : 8px ;
41
+ border-top : 1px solid hsl (205 , 20% , 94% );
19
42
}
20
43
21
- .navigation-container {
22
- padding : 10px ;
23
- flex : 1 ;
44
+ /* Challenge Area */
45
+ .challenge-area {
46
+ display : flex;
47
+ flex-direction : column;
24
48
}
25
49
26
- .codemirror-container {
27
- padding : 10px ;
50
+ .challenge-header__title {
51
+ display : flex;
52
+ align-items : center;
53
+ margin-bottom : 1rem ;
54
+ }
55
+
56
+ .challenge-header__title > span : nth-child (1 ) {
57
+ font-size : 30px ;
58
+ font-weight : bold;
59
+ margin-right : 20px ;
60
+ }
61
+
62
+ .challenge-main {
63
+ display : flex;
64
+ justify-content : space-between;
65
+ gap : 24px ;
66
+ }
67
+
68
+ /* Code Editor Area */
69
+ .challenge-main .codemirror-container {
28
70
display : flex;
29
71
flex-direction : column;
30
- flex : 4 ;
72
+ gap : 16px ;
73
+ width : 50% ;
31
74
}
32
75
33
- .result-container {
34
- flex : 4 ;
76
+ .codemirror-container # run-button {
77
+ align-self : flex-end;
78
+ width : 100px ;
79
+ padding : 2px 4px ;
80
+ border-radius : 4px ;
81
+ }
82
+
83
+ .tests-result-container {
35
84
display : flex;
36
- justify-content : start;
37
- margin-left : 10px ;
85
+ flex-direction : column;
86
+ justify-content : space-between;
87
+ width : 50% ;
88
+ gap : 16px ;
89
+ }
90
+
91
+ .test-result-container # tests {
92
+ width : 50% ;
38
93
}
39
94
40
95
/* 当视口宽度小于 800px 时,更改布局为单列 */
41
96
@media only screen and (max-width : 800px ) {
42
- .container {
97
+ .challenge- container {
43
98
flex-direction : column;
99
+ align-items : center;
100
+ margin-top : 20px ;
101
+ height : 100% ;
102
+ width : 100% ;
103
+ }
104
+
105
+ .sidebar-container {
106
+ overflow-y : auto;
107
+ margin-right : 0 ;
108
+ margin-bottom : 2rem ;
109
+ min-height : 100px ;
110
+ }
111
+
112
+ .sidebar-container .sidebar-challenge-list {
113
+ height : 100% ;
114
+ }
115
+
116
+ .challenge-header__title {
117
+ justify-content : space-between;
118
+ font-size : 14px ;
119
+ }
120
+
121
+ .challenge-header__title > span : nth-child (1 ) {
122
+ margin-right : auto;
123
+ font-size : 20px ;
124
+ }
125
+
126
+ .challenge-main {
127
+ flex-direction : column;
128
+ justify-content : center;
129
+ align-items : center;
130
+ gap : 0 ;
131
+ }
132
+
133
+ .challenge-main .codemirror-container ,
134
+ .challenge-main .tests-result-container {
135
+ width : 100% ;
44
136
}
45
137
}
46
138
53
145
border : 2px solid blue;
54
146
}
55
147
56
- .code {
57
- background-color : # ffffcc ;
58
- }
59
148
</ style >
60
- </ head >
61
-
62
- < body >
63
- {% include 'github_ribbon.html' %}
64
- < div class ="container ">
65
- < div class ="navigation-container "> {% include 'challenge_list.html' %}</ div >
66
- < div class ="codemirror-container ">
67
- < div
68
- style ="
69
- display: flex;
70
- justify-content: space-between;
71
- align-items: center;
72
- "
73
- >
74
- < h2 > Challenge - {{name}}</ h2 >
75
- < p > Python version: {{ python_info }}</ p >
149
+ {% endblock %}
150
+
151
+ {% block content %}
152
+ < div class ="challenge-container container-fluid ">
153
+ <!-- Left/Top Sidebar -->
154
+ < div class ="sidebar-container ">
155
+ < div class ="sidebar-challenge-list ">
156
+ {% include 'components/challenge_list.html' %}
76
157
</ div >
77
- < p style ="margin-top: 0; line-height: 1.5 ">
158
+ < div class ="sidebar-actions ">
159
+ {% include 'components/darkmode.html' %}
160
+ </ div >
161
+ </ div >
162
+
163
+ <!-- Right/Bottom Challenge Area-->
164
+ < div class ="challenge-area ">
165
+ <!-- Challenge Header Area-->
166
+ < div class ="challenge-header ">
167
+ < div class ="challenge-header__title ">
168
+ < span > Challenge - {{ name }}</ span >
169
+ {%include 'components/badge.html' with context %}
170
+ </ div >
171
+ < p class ="challenge-header__exerpt " style ="margin-top: 0; line-height: 1.5 ">
78
172
Complete code following the instructions below, so that there are no type errors
79
173
throughout the test code except for those lines followed by a < code > # expect-type-error</ code > comment.
80
174
You don't need to implement the function, just add type annotations.
81
175
Hit the "Run" button to see result.
82
176
</ p >
83
- < div id ="editor "> </ div >
84
- < div style ="display: flex; justify-content: flex-end ">
85
- < button id ="run-button " style ="width: 100px; margin-top: 10px ">
177
+ </ div >
178
+
179
+ < div class ="challenge-main ">
180
+ <!-- Code Editor Area -->
181
+ < div class ="codemirror-container ">
182
+ < div id ="editor "> </ div >
183
+ < button id ="run-button ">
86
184
▶️ Run
87
185
</ button >
186
+ </ div >
187
+ <!-- Test Cases and Result Area -->
188
+ < div class ="tests-result-container ">
189
+ < div id ="tests "> </ div >
190
+ < div id ="result " style ="white-space: pre-line "> </ div >
191
+ </ div >
88
192
</ div >
89
- < p style ="margin-top: 0 "> Test cases</ p >
90
- < div id ="tests "> </ div >
91
- </ div >
92
- < div class ="result-container ">
93
- < p id ="result " style ="white-space: pre-line "> </ p >
94
193
</ div >
95
194
</ div >
195
+
96
196
< script type ="text/javascript ">
97
- let code_under_test = { { code_under_test | tojson } } ;
98
- console . log ( code_under_test ) ;
99
- var myCodeMirror = CodeMirror ( document . getElementById ( "editor" ) , {
100
- value : code_under_test ,
197
+ let codeMirrorShared = {
101
198
mode : "python" ,
102
199
lineWrapping : true ,
103
200
lineNumbers : true ,
104
- indentUnit : 4
201
+ }
202
+ let code_under_test = { { code_under_test | tojson } } ;
203
+ let myCodeMirror = CodeMirror ( document . getElementById ( "editor" ) , {
204
+ value : code_under_test ,
205
+ ...codeMirrorShared ,
105
206
} ) ;
106
- let test_code = { { test_code | tojson } } ;
207
+ let test_code = { { test_code | tojson } } ;
107
208
CodeMirror ( document . getElementById ( "tests" ) , {
108
209
value : test_code ,
109
- mode : "python" ,
110
- lineWrapping : true ,
111
- lineNumbers : true ,
112
- readOnly : "nocursor"
210
+ readOnly : "nocursor" ,
211
+ ...codeMirrorShared ,
113
212
} ) ;
114
213
115
- document . getElementById ( 'run-button' ) . onclick = function ( ) {
116
- var code = myCodeMirror . getValue ( ) ;
214
+ let runButton = document . getElementById ( 'run-button' )
215
+ runButton . onclick = function ( ) {
216
+ // set button spinner
217
+ let rawInnerText = runButton . innerText ;
218
+ runButton . ariaBusy = true ;
219
+ runButton . innerText = ""
220
+
221
+ let code = myCodeMirror . getValue ( ) ;
117
222
fetch ( '/run/{{name}}' , {
118
223
method : 'POST' ,
119
224
body : code
@@ -122,12 +227,17 @@ <h2>Challenge - {{name}}</h2>
122
227
. then ( result => document . getElementById ( "result" ) . innerHTML = result )
123
228
. catch ( ( error ) => {
124
229
console . error ( 'Error:' , error ) ;
230
+ } )
231
+ . finally ( ( ) => {
232
+ // reset button spinner
233
+ runButton . ariaBusy = false ;
234
+ runButton . innerText = rawInnerText ;
125
235
} ) ;
126
236
} ;
127
237
128
238
// If window size is > 800, expand the challenge list.
129
239
function checkWidth ( ) {
130
- var detailsElement = document . getElementById ( 'challenge-list' ) ;
240
+ let detailsElement = document . getElementById ( 'challenge-list' ) ;
131
241
if ( window . innerWidth < 800 ) {
132
242
detailsElement . removeAttribute ( 'open' ) ;
133
243
} else {
@@ -137,4 +247,4 @@ <h2>Challenge - {{name}}</h2>
137
247
checkWidth ( ) ; // Check the width initially
138
248
window . addEventListener ( 'resize' , checkWidth ) ;
139
249
</ script >
140
- </ body >
250
+ {% endblock %}
0 commit comments