├── .idea
└── inspectionProfiles
│ └── Project_Default.xml
├── LICENSE
├── README.md
├── common
└── resources
│ └── images
│ ├── course-structure-author.png
│ ├── course-structure-student.png
│ ├── files-order.gif
│ ├── get-from-version-control.png
│ ├── light_dark.gif
│ ├── logo.png
│ ├── logo_dark.png
│ └── use_template_blur.jpg
├── course-info.yaml
└── course_section
├── course_guided_project
├── lesson-info.yaml
├── programming_task
│ ├── __init__.py
│ ├── invisible_main.py
│ ├── main.py
│ ├── task-info.yaml
│ ├── task.md
│ └── tests
│ │ ├── __init__.py
│ │ └── test.py
└── theory_task
│ ├── __init__.py
│ ├── invisible_main.py
│ ├── main.py
│ ├── task-info.yaml
│ └── task.md
├── course_lesson
├── lesson-info.yaml
├── multi_file_task
│ ├── __init__.py
│ ├── main.py
│ ├── task-info.yaml
│ ├── task.md
│ ├── task.py
│ └── tests
│ │ ├── input.txt
│ │ └── output.txt
├── programming_task
│ ├── __init__.py
│ ├── invisible_main.py
│ ├── main.py
│ ├── task-info.yaml
│ ├── task.md
│ └── tests
│ │ ├── __init__.py
│ │ └── test.py
├── quiz_task
│ ├── __init__.py
│ ├── main.py
│ ├── task-info.yaml
│ └── task.md
└── theory_task
│ ├── __init__.py
│ ├── invisible_main.py
│ ├── main.py
│ ├── task-info.yaml
│ └── task.md
└── section-info.yaml
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 JetBrains Academy
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JetBrains Academy Python Course Template
2 |
3 | [](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
4 | [](https://opensource.org/licenses/MIT)
5 |
6 | > **Note**
7 | >
8 | > Click the Use this template button and clone it in IntelliJ IDEA.
9 |
10 | **JetBrains Academy Python course template** is a repository that provides a
11 | pure template to make it easier to create a new Python course with the [JetBrains Academy
12 | plugin][ref:plugin.marketplace] (check out the [Creating a repository from a template][gh:template] article).
13 |
14 | The main goal of this template is to speed up the setup phase
15 | of Python course development for both new and experienced educators
16 | by preconfiguring the project scaffold and CI,
17 | linking to the proper documentation pages, and keeping everything organized.
18 |
19 | If you're still not quite sure what this is all about, read our introduction: [What is the JetBrains Academy plugin?][docs:intro]
20 |
21 | > **Note**
22 | >
23 | > Click the Watch button on the top to be notified about releases containing new features and fixes.
24 |
25 | ### Table of contents
26 |
27 | In this README, we will highlight the following elements of template-project creation:
28 |
29 | - [Getting started](#getting-started)
30 | - [Course info configuration file](#course-info-configuration-file)
31 | - [Course ignore file](#course-ignore-file)
32 | - [Sample code](#sample-code)
33 | - [Testing](#testing)
34 | - [Useful links](#useful-links)
35 |
36 | ## Getting started
37 |
38 | Before we dive into course development and everything related to it, it's worth mentioning the benefits of using GitHub Templates.
39 | By creating a new project with the current template, you start with no history or reference to this repository.
40 | This allows you to create a new repository easily, without copying and pasting previous content, cloning repositories, or clearing the history manually.
41 |
42 | All you need to do is click the Use this template button (you must be logged in with your GitHub account).
43 |
44 | ![Use this template][file:use-template-blur]
45 |
46 | The most convenient way of getting your new project from GitHub is the Get from VCS action available on the Welcome Screen,
47 | where you can filter your GitHub repository by its name.
48 |
49 | ![Get from version control][file:get_from_vcs.png]
50 |
51 |
52 | ## Course template structure
53 |
54 | A generated JetBrains Academy Python Course Template repository contains the following content structure:
55 |
56 | ```
57 | .
58 | ├── LICENSE
59 | ├── README.md README
60 | ├── common Course sources common for all sections
61 | │ └── resources Resources - images, icons
62 | ├── course-info.yaml Course info configuration file
63 | └── course_section An example of the course section
64 | ├── course_guided_project An example of the course guided project
65 | │ ├── lesson-info.yaml Lesson config file
66 | │ ├── programming_task Example of programming task
67 | │ │ ├── main.py
68 | │ │ ├── task-info.yaml Task info
69 | │ │ ├── task.md Task text content
70 | │ │ └── tests Task tests
71 | │ │ └── test.py
72 | │ └── theory_task Example of theory task
73 | │ ├── main.py
74 | │ ├── task-info.yaml
75 | │ └── task.md
76 | ├── course_lesson An example of the course lesson
77 | │ ├── lesson-info.yaml
78 | │ ├── multi_file_task Multiple file task example
79 | │ │ ├── main.py
80 | │ │ ├── task-info.yaml
81 | │ │ ├── task.md
82 | │ │ ├── task.py
83 | │ │ └── tests
84 | │ └── quiz_task Quiz task example
85 | │ ├── main.py
86 | │ ├── task-info.yaml
87 | │ └── task.md
88 | └── section-info.yaml Section information
89 | ```
90 |
91 | ## Course info configuration file
92 |
93 | The course info configuration file is the [course-info.yaml][file:course-info.yaml] file located in the root directory.
94 | It provides general information about the course, like description, language, etc.
95 |
96 | ```yaml
97 | type: marketplace
98 | title: JetBrains Academy Python course template
99 | language: English
100 | summary: Here you can put the course description. You can use HTML tags inside the
101 | description.
102 | programming_language: Python
103 | environment: unittest
104 | content:
105 | - course_section
106 | ```
107 |
108 | ## Sample code
109 |
110 | The prepared template provides an example of a course with one section, two lessons (regular and guided), and five tasks in total.
111 |
112 | ![Course structure in the course creator mode][file:course-structure-author]
113 |
114 | Each course may have an unlimited number of sections, lessons, and tasks.
115 | Students will see almost the same course structure as the educator (course author):
116 |
117 | ![Course structure in the course student mode][file:course-structure-student]
118 |
119 | The main difference is in framework lessons, which display only task files, without intermediate steps.
120 |
121 | You can read more about guided projects in the official documentation in the [Guided Projects Creation][ref:guided.projects.creation] section.
122 |
123 | > **Note**
124 | >
125 | > Click Course Creator -> Create Course Preview in the context menu in the root of the repository to create a course preview.
126 |
127 |
128 | The JetBrains Academy plugin provides five different types of tasks,
129 | and you can combine them inside one lesson (whether regular or guided).
130 | You can read more about tasks in the official documentation in the [Task][ref:tasks] section.
131 |
132 | ## Testing
133 |
134 | To check the programming exercises for [**edu**][ref:tasks] tasks, you need to write tests using [unittest](https://docs.python.org/3/library/unittest.html) framework.
135 |
136 | You can find little examples of programming tasks in the repository in the `test.py` files:
137 | in [course lesson][file:course.lesson.tests] and [course guided project][file:course.guided.project.tests].
138 |
139 | ## Useful links
140 |
141 | - [JetBrains Academy plugin][ref:plugin.marketplace]
142 | - [Course creator start guide][ref:course.creator.start.guide]
143 | - [Courses on Marketplace][ref:marketplace]
144 |
145 | [gh:actions]: https://help.github.com/en/actions
146 | [gh:template]: https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template
147 |
148 | [ref:marketplace]: https://plugins.jetbrains.com/education
149 | [ref:course.creator.start.guide]: https://plugins.jetbrains.com/plugin/10081-jetbrains-academy/docs/educator-start-guide.html
150 | [ref:plugin.marketplace]: https://plugins.jetbrains.com/plugin/10081-jetbrains-academy
151 | [ref:course.preview]: https://plugins.jetbrains.com/plugin/10081-jetbrains-academy/docs/educator-start-guide.html#preview_course
152 | [ref:course.distribution]: https://plugins.jetbrains.com/plugin/10081-jetbrains-academy/docs/educator-start-guide.html#course_distribution
153 | [ref:guided.projects.creation]: https://plugins.jetbrains.com/plugin/10081-jetbrains-academy/docs/framework-lessons-guide-for-course-creators.html#a81e8983
154 | [ref:tasks]: https://plugins.jetbrains.com/plugin/10081-jetbrains-academy/docs/framework-lessons-guide-for-course-creators.html#a81e8983
155 |
156 | [docs:intro]: https://plugins.jetbrains.com/plugin/10081-jetbrains-academy/docs/jetbrains-academy-plugin-faq.html#what_is_the_jetbrains_academy_plugin
157 |
158 | [file:course-info.yaml]: ./course-info.yaml
159 | [file:courseignore]: .courseignore
160 | [file:course.lesson.tests]: course_section/course_lesson/programming_task/tests/test.py
161 | [file:course.guided.project.tests]: course_section/course_guided_project/programming_task/tests/test.py
162 |
163 | [semver]: https://semver.org
164 |
165 | [file:get_from_vcs.png]: common/resources/images/get-from-version-control.png
166 | [file:course-structure-author]: common/resources/images/course-structure-author.png
167 | [file:course-structure-student]: common/resources/images/course-structure-student.png
168 | [file:use-template-blur]: common/resources/images/use_template_blur.jpg
169 |
--------------------------------------------------------------------------------
/common/resources/images/course-structure-author.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/common/resources/images/course-structure-author.png
--------------------------------------------------------------------------------
/common/resources/images/course-structure-student.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/common/resources/images/course-structure-student.png
--------------------------------------------------------------------------------
/common/resources/images/files-order.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/common/resources/images/files-order.gif
--------------------------------------------------------------------------------
/common/resources/images/get-from-version-control.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/common/resources/images/get-from-version-control.png
--------------------------------------------------------------------------------
/common/resources/images/light_dark.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/common/resources/images/light_dark.gif
--------------------------------------------------------------------------------
/common/resources/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/common/resources/images/logo.png
--------------------------------------------------------------------------------
/common/resources/images/logo_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/common/resources/images/logo_dark.png
--------------------------------------------------------------------------------
/common/resources/images/use_template_blur.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/common/resources/images/use_template_blur.jpg
--------------------------------------------------------------------------------
/course-info.yaml:
--------------------------------------------------------------------------------
1 | type: marketplace
2 | title: JetBrains Academy Python course template
3 | language: English
4 | summary: Here you can put the course description. You can use HTML tags inside the
5 | description.
6 | programming_language: Python
7 | environment: unittest
8 | content:
9 | - course_section
10 | additional_files:
11 | - name: common/resources/images/logo.png
12 | is_binary: true
13 | - name: common/resources/images/logo_dark.png
14 | is_binary: true
15 | - name: common/resources/images/light_dark.gif
16 | is_binary: true
17 | - name: common/resources/images/files-order.gif
18 | is_binary: true
19 | - name: common/resources/images/use_template_blur.jpg
20 | is_binary: true
21 | - name: common/resources/images/course-structure-author.png
22 | is_binary: true
23 | - name: common/resources/images/course-structure-student.png
24 | is_binary: true
25 | - name: common/resources/images/get-from-version-control.png
26 | is_binary: true
27 | - name: LICENSE
28 | - name: .idea/inspectionProfiles/Project_Default.xml
29 | yaml_version: 2
30 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/lesson-info.yaml:
--------------------------------------------------------------------------------
1 | type: framework
2 | custom_name: Course guided project
3 | content:
4 | - theory_task
5 | - programming_task
6 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/programming_task/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_guided_project/programming_task/__init__.py
--------------------------------------------------------------------------------
/course_section/course_guided_project/programming_task/invisible_main.py:
--------------------------------------------------------------------------------
1 | # This file will be hidden in the student mode
2 | # Since this file is invisible, it can be changed between tasks
3 |
4 | def say_bye() -> str:
5 | return "Bye"
6 |
7 |
8 | if __name__ == '__main__':
9 | say_bye()
10 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/programming_task/main.py:
--------------------------------------------------------------------------------
1 | # This file will be visible for the student
2 | import os
3 |
4 | from invisible_main import say_bye
5 |
6 |
7 | def invoke_say_bye(how_many_times: int):
8 | print(os.linesep.join([say_bye() for _ in range(how_many_times)]))
9 |
10 |
11 | if __name__ == '__main__':
12 | print("How many times should I print Bye?")
13 | how_many_times = int(input())
14 | invoke_say_bye(how_many_times)
15 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/programming_task/task-info.yaml:
--------------------------------------------------------------------------------
1 | type: edu
2 | custom_name: Programming task
3 | files:
4 | - name: invisible_main.py
5 | visible: false
6 | propagatable: false
7 | - name: __init__.py
8 | visible: false
9 | propagatable: false
10 | - name: main.py
11 | visible: true
12 | - name: tests/test.py
13 | visible: false
14 | propagatable: false
15 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/programming_task/task.md:
--------------------------------------------------------------------------------
1 | In this task, the user needs to implement some functions.
2 | You can check the user mode – the content of the `main.py` file will be propagated from the previous step;
3 | however, `invisible_main.py` will be changed.
4 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/programming_task/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_guided_project/programming_task/tests/__init__.py
--------------------------------------------------------------------------------
/course_section/course_guided_project/programming_task/tests/test.py:
--------------------------------------------------------------------------------
1 | import os
2 | import unittest
3 | from unittest.mock import patch
4 |
5 | from invisible_main import say_bye
6 | from main import invoke_say_bye
7 |
8 |
9 | class TestAddFunction(unittest.TestCase):
10 | test_cases = [2, 4, 20, 1900, 400, 2004, 2000, 2001]
11 |
12 | @staticmethod
13 | def correct_invoke_say_bye(how_many_times: int):
14 | return os.linesep.join([say_bye() for _ in range(how_many_times)])
15 |
16 | @patch('builtins.print')
17 | def test_parametrized(self, mock_print):
18 | for how_many_times in self.test_cases:
19 | with self.subTest(how_many_times):
20 | correct_solution = self.correct_invoke_say_bye(how_many_times)
21 | invoke_say_bye(how_many_times)
22 | mock_print.assert_called_once_with(correct_solution)
23 | mock_print.reset_mock()
24 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/theory_task/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_guided_project/theory_task/__init__.py
--------------------------------------------------------------------------------
/course_section/course_guided_project/theory_task/invisible_main.py:
--------------------------------------------------------------------------------
1 | # This file will be hidden in the student mode
2 | # Since this file is invisible, it can be changed between tasks
3 | def say_hello() -> str:
4 | return "Hello"
5 |
6 |
7 | if __name__ == '__main__':
8 | print(say_hello())
9 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/theory_task/main.py:
--------------------------------------------------------------------------------
1 | # This file will be visible for the student
2 | def invoke_say_bye(how_many_times: int):
3 | pass
4 |
5 |
6 | if __name__ == '__main__':
7 | print("How many times should I print Bye?")
8 | how_many_times = int(input())
9 | invoke_say_bye(how_many_times)
10 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/theory_task/task-info.yaml:
--------------------------------------------------------------------------------
1 | type: theory
2 | custom_name: Theory task
3 | files:
4 | - name: main.py
5 | visible: true
6 | - name: invisible_main.py
7 | visible: false
8 | propagatable: false
9 | - name: __init__.py
10 | visible: false
11 | propagatable: false
12 |
--------------------------------------------------------------------------------
/course_section/course_guided_project/theory_task/task.md:
--------------------------------------------------------------------------------
1 | This is an example of a guided project.
2 | If you create this type of lesson, the user can solve tasks step by step.
3 | Initially, the user sees all the visible files from the first task in the lesson.
4 | Next, all changes made by the user in the visible files
5 | will be propagated to the following tasks.
6 |
7 | Beginning from the second task, you can modify the visible files to be able to provide
8 | students with the correct solution from the course author.
9 | Invisible files can be modified between tasks.
10 |
11 | The guided projects also support file synchronization for the creator mode,
12 | which means that all changes made in some file will be propagated to all files below.
13 |
14 | **Note, you need to have the same set of files between all tasks.**
15 | Thus, it is the same for the resources folder, and to avoid double-storing of images,
16 | you can put them into the `common` module:
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | You can put the picture for the dark theme with the suffix "_dark" together with the initial one.
25 | In such a case, the plugin will use this picture if the user switched the IDE theme to the dark one:
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/course_section/course_lesson/lesson-info.yaml:
--------------------------------------------------------------------------------
1 | custom_name: Course lesson
2 | content:
3 | - theory_task
4 | - quiz_task
5 | - programming_task
6 | - multi_file_task
7 |
--------------------------------------------------------------------------------
/course_section/course_lesson/multi_file_task/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_lesson/multi_file_task/__init__.py
--------------------------------------------------------------------------------
/course_section/course_lesson/multi_file_task/main.py:
--------------------------------------------------------------------------------
1 | from task import invoke_say_hello_world
2 |
3 | if __name__ == '__main__':
4 | invoke_say_hello_world()
5 |
--------------------------------------------------------------------------------
/course_section/course_lesson/multi_file_task/task-info.yaml:
--------------------------------------------------------------------------------
1 | type: output
2 | custom_name: Multiple file task
3 | files:
4 | - name: task.py
5 | visible: true
6 | placeholders:
7 | - offset: 34
8 | length: 22
9 | placeholder_text: pass
10 | - name: main.py
11 | visible: true
12 | placeholders:
13 | - offset: 72
14 | length: 24
15 | placeholder_text: pass
16 | - name: __init__.py
17 | visible: true
18 | - name: tests/output.txt
19 | visible: false
20 | - name: tests/input.txt
21 | visible: false
22 |
--------------------------------------------------------------------------------
/course_section/course_lesson/multi_file_task/task.md:
--------------------------------------------------------------------------------
1 | This is an example of an input/output task.
2 | In this type of task, you can give an expected input and output to the program instead of implementing
3 | your own tests.
4 |
5 | This task also demonstrates how you can set up which file should be opened in the student mode if the task has several files.
6 | You just need to put this file as the first file in the `task-info.yaml` config, e.g. in this task the `task.py` will be opened:
7 |
8 | 
9 |
--------------------------------------------------------------------------------
/course_section/course_lesson/multi_file_task/task.py:
--------------------------------------------------------------------------------
1 | def invoke_say_hello_world():
2 | print("Hello, world!")
3 |
--------------------------------------------------------------------------------
/course_section/course_lesson/multi_file_task/tests/input.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_lesson/multi_file_task/tests/input.txt
--------------------------------------------------------------------------------
/course_section/course_lesson/multi_file_task/tests/output.txt:
--------------------------------------------------------------------------------
1 | Hello, world!
2 |
--------------------------------------------------------------------------------
/course_section/course_lesson/programming_task/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_lesson/programming_task/__init__.py
--------------------------------------------------------------------------------
/course_section/course_lesson/programming_task/invisible_main.py:
--------------------------------------------------------------------------------
1 | # This file will be hidden in the student mode
2 | # Since this file is invisible, it can be changed between tasks
3 |
4 | def say_hello() -> str:
5 | return "Hello"
6 |
7 |
8 | if __name__ == '__main__':
9 | say_hello()
10 |
--------------------------------------------------------------------------------
/course_section/course_lesson/programming_task/main.py:
--------------------------------------------------------------------------------
1 | # This file will be visible for the student
2 | import os
3 |
4 | from invisible_main import say_hello
5 |
6 |
7 | def invoke_say_hello(how_many_times: int):
8 | print(os.linesep.join([say_hello() for _ in range(how_many_times)]))
9 |
10 |
11 | if __name__ == '__main__':
12 | print("How many times should I print Hello?")
13 | how_many_times = int(input())
14 | invoke_say_hello(how_many_times)
15 |
--------------------------------------------------------------------------------
/course_section/course_lesson/programming_task/task-info.yaml:
--------------------------------------------------------------------------------
1 | type: edu
2 | custom_name: Course programming task
3 | files:
4 | - name: main.py
5 | visible: true
6 | placeholders:
7 | - offset: 141
8 | length: 68
9 | placeholder_text: pass
10 | - name: invisible_main.py
11 | visible: false
12 | - name: tests/test.py
13 | visible: false
14 | - name: __init__.py
15 | visible: false
16 |
--------------------------------------------------------------------------------
/course_section/course_lesson/programming_task/task.md:
--------------------------------------------------------------------------------
1 | This task asks the user to implement something and runs tests from the [test.py](tests/test.py) file.
2 | You need to add _placeholders_ into the places where the user needs to implement something (see [task-info.yaml](task-info.yaml)).
3 |
4 |
--------------------------------------------------------------------------------
/course_section/course_lesson/programming_task/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_lesson/programming_task/tests/__init__.py
--------------------------------------------------------------------------------
/course_section/course_lesson/programming_task/tests/test.py:
--------------------------------------------------------------------------------
1 | import os
2 | import unittest
3 | from unittest.mock import patch
4 |
5 | from invisible_main import say_hello
6 | from main import invoke_say_hello
7 |
8 |
9 | class TestAddFunction(unittest.TestCase):
10 | test_cases = [2, 4, 20, 1900, 400, 2004, 2000, 2001]
11 |
12 | @staticmethod
13 | def correct_invoke_say_bye(how_many_times: int):
14 | return os.linesep.join([say_hello() for _ in range(how_many_times)])
15 |
16 | @patch('builtins.print')
17 | def test_parametrized(self, mock_print):
18 | for how_many_times in self.test_cases:
19 | with self.subTest(how_many_times):
20 | correct_solution = self.correct_invoke_say_bye(how_many_times)
21 | invoke_say_hello(how_many_times)
22 | mock_print.assert_called_once_with(correct_solution)
23 | mock_print.reset_mock()
24 |
--------------------------------------------------------------------------------
/course_section/course_lesson/quiz_task/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_lesson/quiz_task/__init__.py
--------------------------------------------------------------------------------
/course_section/course_lesson/quiz_task/main.py:
--------------------------------------------------------------------------------
1 | if __name__ == '__main__':
2 | # Write your solution here
3 | pass
4 |
--------------------------------------------------------------------------------
/course_section/course_lesson/quiz_task/task-info.yaml:
--------------------------------------------------------------------------------
1 | type: choice
2 | is_multiple_choice: false
3 | options:
4 | - text: Correct
5 | is_correct: true
6 | - text: Incorrect
7 | is_correct: false
8 | message_incorrect: This text will be shown if the user made a mistake.
9 | files:
10 | - name: main.py
11 | visible: true
12 | - name: __init__.py
13 | visible: true
14 | custom_name: Course quiz task
15 | local_check: true
16 |
--------------------------------------------------------------------------------
/course_section/course_lesson/quiz_task/task.md:
--------------------------------------------------------------------------------
1 | You cannot change the question text **Select one option from the list**; you just need to put your question into this file.
2 | You can set up all quiz options in the [task-info](task-info.yaml) file.
3 |
--------------------------------------------------------------------------------
/course_section/course_lesson/theory_task/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jetbrains-academy/python-course-template/2bdd1b1871f665020e07687bc69fc02aaf332445/course_section/course_lesson/theory_task/__init__.py
--------------------------------------------------------------------------------
/course_section/course_lesson/theory_task/invisible_main.py:
--------------------------------------------------------------------------------
1 | # This file will be hidden in the student mode
2 | # Since this file is invisible, it can be changed between tasks
3 | def say_hello() -> str:
4 | return "Hello"
5 |
6 |
7 | if __name__ == '__main__':
8 | print(say_hello())
9 |
--------------------------------------------------------------------------------
/course_section/course_lesson/theory_task/main.py:
--------------------------------------------------------------------------------
1 | if __name__ == '__main__':
2 | # Write your solution here
3 | pass
4 |
--------------------------------------------------------------------------------
/course_section/course_lesson/theory_task/task-info.yaml:
--------------------------------------------------------------------------------
1 | type: theory
2 | custom_name: Course theory task
3 | files:
4 | - name: main.py
5 | visible: true
6 | - name: invisible_main.py
7 | visible: false
8 | - name: __init__.py
9 | visible: true
10 |
--------------------------------------------------------------------------------
/course_section/course_lesson/theory_task/task.md:
--------------------------------------------------------------------------------
1 | This is an example of a theory lesson.
2 |
3 |
4 |
5 | You can use hints to explain something to the students.
6 | Please leave an empty line to be able to apply markdown formatting, like **this**.
7 |
8 | Invisible files are hidden in the student mode.
9 | You can use them to define, for example, the helper functions in the course.
10 |
11 | To mark a file as invisible, you need to set up the `false` value for the corresponding file in the [task-info](task-info.yaml) file.
12 |
13 |
14 | Theory tasks do not contain any tests.
15 |
--------------------------------------------------------------------------------
/course_section/section-info.yaml:
--------------------------------------------------------------------------------
1 | custom_name: Course section
2 | content:
3 | - course_lesson
4 | - course_guided_project
5 |
--------------------------------------------------------------------------------