codeforlife-portal 7.1.2__py2.py3-none-any.whl → 7.2.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of codeforlife-portal might be problematic. Click here for more details.

@@ -107,6 +107,7 @@ $color-background-danger: #ff0000;
107
107
  $color-background-tint-primary: #f1ecec;
108
108
  $color-background-sub-banner: $color-secondary-300;
109
109
  $color-background-box-shadow: rgba(0, 0, 0, 0.2);
110
+ $color-background-python-den: #213ce7;
110
111
  // Popups & Messages
111
112
  $color-ui-dialog-border: #808080;
112
113
  $color-ui-widget-overlay: #666666;
@@ -180,6 +180,11 @@ blockquote {
180
180
  }
181
181
  }
182
182
 
183
+ .background--python-den {
184
+ background-color: $color-background-python-den;
185
+ color: $color-text-secondary;
186
+ }
187
+
183
188
  @media (min-width: $tablet-small-min-width) {
184
189
  .list--two-columns {
185
190
  columns: 2;
@@ -54,6 +54,12 @@
54
54
  Built on Blockly, it's a visual programming language similar
55
55
  to Scratch. Rapid Router is our flagship game with the
56
56
  biggest user base.</p>
57
+
58
+ <p><b>Python Den</b></p>
59
+ <p>Our new Python Den uses Blockly, Blockly/Python split
60
+ screen, and an IDE. It takes students from no previous
61
+ Python experience to a foundation in Python, helping
62
+ prepare them for GCSE and beyond.</p>
57
63
  </div>
58
64
  <div class="col-sm-6">
59
65
  <img title="Rapid Router" alt="Rapid Router"
@@ -37,6 +37,7 @@
37
37
  Games <span class="material-icons-outlined md-32">arrow_drop_down</span></a>
38
38
  <div class="dropdown-content">
39
39
  <a href="{% url 'levels' %}"><small>Rapid Router</small></a>
40
+ <a href="{% url 'python_levels' %}"><small>Python Den</small></a>
40
41
  </div>
41
42
  </div>
42
43
  <div class="dropdown">
@@ -46,6 +47,8 @@
46
47
  <div class="dropdown-content">
47
48
  <a id="rapid_router_resources_button" href="https://code-for-life.gitbook.io/teaching-resources/" target="_blank">
48
49
  <small>Rapid Router</small> <span class="iconify" data-icon="mdi:open-in-new"></span></a>
50
+ <a href="https://code-for-life.gitbook.io/python-lessons-with-raspberry-pi-ide/DGiFT28ihVJK7ghZQHqu" target="_blank">
51
+ <small>Python Den</small> <span class="iconify" data-icon="mdi:open-in-new"></span></a>
49
52
  <a href="{% url 'codingClub' %}"><small>Coding Clubs</small></a>
50
53
  </div>
51
54
  </div>
@@ -75,6 +78,7 @@
75
78
  </a>
76
79
  <div class="dropdown-content">
77
80
  <a href="{% url 'levels' %}"><small>Rapid Router</small></a>
81
+ <a href="{% url 'python_levels' %}"><small>Python Den</small></a>
78
82
  </div>
79
83
  </div>
80
84
  {% if user|is_logged_in_as_school_user %}
@@ -186,11 +190,15 @@
186
190
  href="{% url 'dashboard' %}">School / Club<span class="material-icons-outlined md-32">chevron_right</span></a>
187
191
  <a class="button button--menu__item button--menu__item__sub"
188
192
  href="{% url 'levels' %}">Rapid Router<span class="material-icons-outlined md-32">chevron_right</span></a>
193
+ <a class="button button--menu__item button--menu__item__sub"
194
+ href="{% url 'python_levels' %}">Python Den<span class="material-icons-outlined md-32">chevron_right</span></a>
189
195
  <button class="button--menu__item button--menu__item__sub
190
196
  button--menu__item--sub-header" data-toggle="collapse" data-target="#resources-tabs">Teaching Resources</button>
191
197
  <div id="resources-tabs" class="collapse">
192
198
  <a class="button button--menu__item button--menu__item__sub__sub"
193
199
  href="https://code-for-life.gitbook.io/teaching-resources/" target="_blank">Rapid Router<span class="material-icons-outlined md-32">chevron_right</span></a>
200
+ <a class="button button--menu__item button--menu__item__sub__sub"
201
+ href="https://code-for-life.gitbook.io/python-lessons-with-raspberry-pi-ide/DGiFT28ihVJK7ghZQHqu" target="_blank">Python Den<span class="material-icons-outlined md-32">chevron_right</span></a>
194
202
  </div>
195
203
  </div>
196
204
  {% else %}
@@ -209,6 +217,8 @@
209
217
  <div id="games-tabs" class="collapse">
210
218
  <a class="button button--menu__item button--menu__item--{% if user|is_independent_student %}independent{% else %}student{% endif %} button--menu__item__sub"
211
219
  href="{% url 'levels' %}">Rapid Router<span class="material-icons-outlined md-32">chevron_right</span></a>
220
+ <a class="button button--menu__item button--menu__item--{% if user|is_independent_student %}independent{% else %}student{% endif %} button--menu__item__sub"
221
+ href="{% url 'python_levels' %}">Python Den<span class="material-icons-outlined md-32">chevron_right</span></a>
212
222
  </div>
213
223
  {% if user|is_logged_in_as_school_user %}
214
224
  <a class="button button--menu__item button--menu__item--student"
@@ -3,7 +3,11 @@
3
3
  {% load app_tags %}
4
4
 
5
5
  {% block subNav %}
6
+ {% if user|is_independent_student %}
7
+ <section class="banner banner--independent-student row mx-0">
8
+ {% else %}
6
9
  <section class="banner banner--student row mx-0">
10
+ {% endif %}
7
11
  <div>
8
12
  <h1 class="banner__text--primary">
9
13
  Welcome, {{ user|make_into_username }}
@@ -16,13 +20,13 @@
16
20
  {% block content %}
17
21
  <div id="play_dashboard_page">
18
22
  <div class="background container">
19
- <section><h4>Your class games</h4></section>
20
- <div class="grid-games col-center col-sm-4">
23
+ <section><h4>Your games</h4></section>
24
+ <div class="grid-games col-center col-sm-9">
21
25
  <div class="card">
22
26
  <div class="card__images">
23
27
  <img title="Rapid Router" alt="Rapid Router"
24
28
  class="card__image"
25
- src="{% static 'portal/img/RR_logo_green.svg' %}">
29
+ src="{% static 'portal/img/RR_logo_grass_background.png' %}">
26
30
  </div>
27
31
  <div class="card__text">
28
32
  <h5 class="card__title">Rapid Router</h5>
@@ -35,17 +39,34 @@
35
39
  </div>
36
40
  </div>
37
41
  </div>
42
+ <div class="card">
43
+ <div class="card__images">
44
+ <img title="Python Den" alt="Python Den"
45
+ class="card__image"
46
+ src="{% static 'portal/img/python_den.png' %}">
47
+ </div>
48
+ <div class="card__text">
49
+ <h5 class="card__title">Python Den</h5>
50
+ <p>The Python Den takes you on a programming journey from
51
+ beginner to syntax superhero. Build a good solid
52
+ foundation of Python to start your coding career!</p>
53
+ <div class="button-group">
54
+ <a href="{% url 'python_levels'%}"
55
+ class="button button--primary">Play</a>
56
+ </div>
57
+ </div>
58
+ </div>
38
59
  </div>
39
60
  </div>
40
61
  <div class="background background--primary">
41
62
  <div class="container">
42
63
  <div class="text-center">
43
64
  <section><img title="Rapid Router logo" alt="Rapid Router logo" src="{% static 'portal/img/RR_logo_simple.png' %}"></section>
44
- <h4>You have completed {{ num_completed }} Rapid Router level{{ num_completed|pluralize }}!</h4>
45
- <h4>You have {{ num_top_scores }} top score{{ num_top_scores|pluralize }}!</h4>
46
- <h4>You have a score of {{ total_score }}. There are {{ total_available_score }} available points.</h4>
47
- {% if total_custom_available_score %}
48
- <h4>You have a score of {{ total_custom_score }} out of {{ total_custom_available_score }} available points on custom levels.</h4>
65
+ <h4>You have completed {{ rapid_router.num_completed }} Rapid Router level{{ rapid_router.num_completed|pluralize }}!</h4>
66
+ <h4>You have {{ rapid_router.num_top_scores }} top score{{ rapid_router.num_top_scores|pluralize }}!</h4>
67
+ <h4>You have a score of {{ rapid_router.total_score }}. There are {{ rapid_router.total_available_score }} available points.</h4>
68
+ {% if rapid_router.total_custom_available_score %}
69
+ <h4>You have a score of {{ rapid_router.total_custom_score }} out of {{ rapid_router.total_custom_available_score }} available points on custom levels.</h4>
49
70
  {% endif %}
50
71
  <section>
51
72
  <a href="{% url 'scoreboard' %}"
@@ -56,5 +77,15 @@
56
77
  </div>
57
78
  </div>
58
79
  </div>
80
+ <div class="background background--python-den">
81
+ <div class="container">
82
+ <div class="text-center">
83
+ <section><img title="Python Den logo" alt="Python Den logo" src="{% static 'portal/img/logo_python_den.svg' %}"></section>
84
+ <h4>You have completed {{ python_den.num_completed }} Python Den level{{ python_den.num_completed|pluralize }}!</h4>
85
+ <h4>You have {{ python_den.num_top_scores }} top score{{ python_den.num_top_scores|pluralize }}!</h4>
86
+ <h4>You have a score of {{ python_den.total_score }}. There are {{ python_den.total_available_score }} available points.</h4>
87
+ </div>
88
+ </div>
89
+ </div>
59
90
  </div>
60
91
  {% endblock %}
@@ -94,6 +94,40 @@
94
94
  </div>
95
95
  </section>
96
96
 
97
+ <div class="background container">
98
+ <section>
99
+ <img title="Python Den logo"
100
+ alt="Banner image of Python Den logo and game"
101
+ src="{% static 'portal/img/python_den_banner.svg' %}">
102
+ </section>
103
+ <div class="background row d-flex">
104
+ <div class="col-sm-6">
105
+ <img src="{% static 'portal/img/python_den.png' %}"
106
+ alt="Python Den logo and characters">
107
+ </div>
108
+ <div class="col-sm-6 d-flex flex-column">
109
+ <div class="flex-grow-1">
110
+ <h5 class="mt-0">Python programming</h5>
111
+ <p>The Python Den is an exploration of Python programming
112
+ through a comprehensive course with free lesson plans,
113
+ videos and worksheets to support you in your learning.</p>
114
+ <p>From foundational syntax to advanced concepts like loops
115
+ and data manipulation, each session is a new challenge.</p>
116
+ <p>We aim to provide a tried-and-tested, structured set of
117
+ lessons that you can use at home or in class, no matter
118
+ your own level of experience.</p>
119
+ </div>
120
+ <div class="row my-4">
121
+ <div class="col-sm-12">
122
+ <a href="{% url 'python_levels' %}"
123
+ class="button button--primary button--icon col-sm-8">
124
+ Play Python Den <span class="iconify" data-icon="mdi:chevron-right"></span></a>
125
+ </div>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ </div>
130
+
97
131
  <script type="text/javascript">
98
132
  $(document).ready(function () {
99
133
  invokeColorbox();
@@ -149,6 +149,41 @@
149
149
  </div>
150
150
  </div>
151
151
 
152
+ <div class="background background--primary">
153
+ <div class="container">
154
+ <div class="row d-flex">
155
+ <div class="col-sm-6 d-flex flex-column">
156
+ <div class="flex-grow-1">
157
+ <h4 class="mt-0">Python programming</h4>
158
+ <p>The Python Den is an exploration of Python
159
+ programming through a comprehensive course with free
160
+ lesson plans, videos and worksheets to support you in
161
+ teaching Python programming to your students. From
162
+ foundational syntax to advanced concepts like loops
163
+ and data manipulation, each session is tailored to
164
+ engage young learners.</p>
165
+ <p>We aim to provide a tried-and-tested, structured set
166
+ of lessons that you can use in your classroom, no
167
+ matter your own level of experience.
168
+ </p>
169
+ </div>
170
+ <div>
171
+ <a href="{% url 'python_levels' %}"
172
+ class="button button--primary button-right-arrow">
173
+ Try out Python Den
174
+ </a>
175
+ </div>
176
+ </div>
177
+ <div class="col-sm-6">
178
+ <a href="https://www.youtube-nocookie.com/embed/ko4nrr4kDzA?rel=0&amp;autoplay=1" class="youtube">
179
+ <img src="{% static 'portal/img/thumbnail_python_den.png' %}"
180
+ alt="Python Den logo">
181
+ </a>
182
+ </div>
183
+ </div>
184
+ </div>
185
+ </div>
186
+
152
187
  <script type="text/javascript">
153
188
  $(document).ready(function(){
154
189
  invokeColorbox();
@@ -560,29 +560,53 @@ class TestViews(TestCase):
560
560
 
561
561
  # Expected context data when a student hasn't played anything yet
562
562
  EXPECTED_DATA_FIRST_LOGIN = {
563
- "num_completed": 0,
564
- "num_top_scores": 0,
565
- "total_score": 0,
566
- "total_available_score": 1450,
563
+ "rapid_router": {
564
+ "num_completed": 0,
565
+ "num_top_scores": 0,
566
+ "total_score": 0,
567
+ "total_available_score": 1450,
568
+ },
569
+ "python_den": {
570
+ "num_completed": 0,
571
+ "num_top_scores": 0,
572
+ "total_score": 0,
573
+ "total_available_score": 830,
574
+ },
567
575
  }
568
576
 
569
577
  # Expected context data when a student has attempted some RR levels
570
578
  EXPECTED_DATA_WITH_ATTEMPTS = {
571
- "num_completed": 2,
572
- "num_top_scores": 1,
573
- "total_score": 39,
574
- "total_available_score": 1450,
579
+ "rapid_router": {
580
+ "num_completed": 2,
581
+ "num_top_scores": 1,
582
+ "total_score": 39,
583
+ "total_available_score": 1450,
584
+ },
585
+ "python_den": {
586
+ "num_completed": 2,
587
+ "num_top_scores": 2,
588
+ "total_score": 30,
589
+ "total_available_score": 830,
590
+ },
575
591
  }
576
592
 
577
593
  # Expected context data when a student has also attempted some custom RR
578
594
  # levels
579
595
  EXPECTED_DATA_WITH_CUSTOM_ATTEMPTS = {
580
- "num_completed": 2,
581
- "num_top_scores": 1,
582
- "total_score": 39,
583
- "total_available_score": 1450,
584
- "total_custom_score": 10,
585
- "total_custom_available_score": 20,
596
+ "rapid_router": {
597
+ "num_completed": 2,
598
+ "num_top_scores": 1,
599
+ "total_score": 39,
600
+ "total_available_score": 1450,
601
+ "total_custom_score": 10,
602
+ "total_custom_available_score": 20,
603
+ },
604
+ "python_den": {
605
+ "num_completed": 2,
606
+ "num_top_scores": 2,
607
+ "total_score": 30,
608
+ "total_available_score": 830,
609
+ },
586
610
  }
587
611
 
588
612
  c = Client()
@@ -599,13 +623,20 @@ class TestViews(TestCase):
599
623
  assert response.status_code == 200
600
624
  assert response.context_data == EXPECTED_DATA_FIRST_LOGIN
601
625
 
602
- # Attempt the first two levels, one perfect attempt, one not
626
+ # Attempt the first two RR levels, one perfect attempt, one not
603
627
  level1 = Level.objects.get(name="1")
604
628
  level2 = Level.objects.get(name="2")
605
629
 
606
630
  create_attempt(student, level1, 20)
607
631
  create_attempt(student, level2, 19)
608
632
 
633
+ # Attempt the first and fourth Python Den levels, both perfect
634
+ level1001 = Level.objects.get(name="1001")
635
+ level1004 = Level.objects.get(name="1004")
636
+
637
+ create_attempt(student, level1001, 20)
638
+ create_attempt(student, level1004, 10)
639
+
609
640
  response = c.get(student_dashboard_url)
610
641
 
611
642
  assert response.status_code == 200
@@ -37,10 +37,16 @@ class SchoolStudentDashboard(
37
37
  the student's scores for any levels shared with them by their teacher.
38
38
  """
39
39
  # Get score data for all original levels
40
- levels = Level.objects.filter(episode__pk__in=range(1, 10))
40
+ rapid_router_levels = Level.objects.filter(episode__pk__in=range(1, 10))
41
+ python_den_levels = Level.objects.filter(
42
+ episode__pk__in=[12, 13, 14, 15, 22]
43
+ )
41
44
  student = self.request.user.new_student
42
45
 
43
- context_data = _compute_rapid_router_scores(student, levels)
46
+ context_data = {
47
+ "rapid_router": _compute_scores(student, rapid_router_levels),
48
+ "python_den": _compute_scores(student, python_den_levels),
49
+ }
44
50
 
45
51
  # Find any custom levels created by the teacher and shared with the
46
52
  # student
@@ -49,16 +55,15 @@ class SchoolStudentDashboard(
49
55
  custom_levels = student.new_user.shared.filter(owner=teacher)
50
56
 
51
57
  if custom_levels:
52
- custom_levels_data = _compute_rapid_router_scores(
53
- student, custom_levels
54
- )
58
+ custom_levels_data = _compute_scores(student, custom_levels)
55
59
 
56
- context_data["total_custom_score"] = custom_levels_data[
57
- "total_score"
58
- ]
59
- context_data["total_custom_available_score"] = custom_levels_data[
60
- "total_available_score"
61
- ]
60
+ context_data["rapid_router"]["total_custom_score"] = (
61
+ custom_levels_data
62
+ )["total_score"]
63
+
64
+ context_data["rapid_router"][
65
+ "total_custom_available_score"
66
+ ] = custom_levels_data["total_available_score"]
62
67
 
63
68
  return context_data
64
69
 
@@ -66,23 +71,26 @@ class SchoolStudentDashboard(
66
71
  class IndependentStudentDashboard(
67
72
  LoginRequiredNoErrorMixin, UserPassesTestMixin, TemplateView, FormView
68
73
  ):
69
- template_name = "portal/play/independent_student_dashboard.html"
74
+ template_name = "portal/play/student_dashboard.html"
70
75
  login_url = reverse_lazy("independent_student_login")
71
76
 
72
77
  def test_func(self) -> Optional[bool]:
73
78
  return logged_in_as_independent_student(self.request.user)
74
79
 
75
80
  def get_context_data(self, **kwargs: Any) -> Dict[str, Any]:
76
- levels = Level.objects.filter(episode__pk__in=range(1, 10))
81
+ rapid_router_levels = Level.objects.filter(episode__pk__in=range(1, 10))
82
+ python_den_levels = Level.objects.filter(
83
+ episode__pk__in=[12, 13, 14, 15, 22]
84
+ )
77
85
  student = self.request.user.new_student
78
86
 
79
- return _compute_rapid_router_scores(
80
- student,
81
- levels,
82
- )
87
+ return {
88
+ "rapid_router": _compute_scores(student, rapid_router_levels),
89
+ "python_den": _compute_scores(student, python_den_levels),
90
+ }
83
91
 
84
92
 
85
- def _compute_rapid_router_scores(
93
+ def _compute_scores(
86
94
  student: Student, levels: List[Level] or QuerySet
87
95
  ) -> Dict[str, int]:
88
96
  """
@@ -1,51 +0,0 @@
1
- {% extends 'portal/base.html' %}
2
- {% load static %}
3
- {% load app_tags %}
4
-
5
- {% block subNav %}
6
- <section class="banner banner--independent-student row mx-0">
7
- <div>
8
- <h1 class="banner__text--primary">
9
- Welcome, {{ user|make_into_username }}
10
- </h1>
11
- <h4>This is where you can access your games</h4>
12
- </div>
13
- </section>
14
- {% endblock subNav %}
15
-
16
- {% block content %}
17
- <div id="play_dashboard_page">
18
- <div class="background container">
19
- <section><h4>Your games</h4></section>
20
- <div class="grid-games col-center col-sm-4">
21
- <div class="card">
22
- <div class="card__images">
23
- <img title="Rapid Router" alt="Rapid Router"
24
- class="card__image"
25
- src="{% static 'portal/img/RR_logo_green.svg' %}">
26
- </div>
27
- <div class="card__text">
28
- <h5 class="card__title">Rapid Router</h5>
29
- <p>Rapid Router guides you, and makes learning to code easy
30
- and great fun. Using Blockly, you can advance through
31
- the levels to become an Ocado delivery hero.</p>
32
- <div class="button-group">
33
- <a href="{% url 'levels'%}"
34
- class="button button--primary">Play</a>
35
- </div>
36
- </div>
37
- </div>
38
- </div>
39
- </div>
40
- <div class="background background--primary">
41
- <div class="container">
42
- <div class="col-center text-center col-sm-9">
43
- <section><img title="Rapid Router logo" alt="Rapid Router logo" src="{% static 'portal/img/RR_logo_simple.png' %}"></section>
44
- <h4>You have completed {{ num_completed }} Rapid Router level{{ num_completed|pluralize }}!</h4>
45
- <h4>You have {{ num_top_scores }} top score{{ num_top_scores|pluralize }}!</h4>
46
- <h4>You have a score of {{ total_score }}. There are {{ total_available_score }} available points.</h4>
47
- </div>
48
- </div>
49
- </div>
50
- </div>
51
- {% endblock %}