├── .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 | 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 | [![official project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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 | Logo 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 | Logo 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 | ![Expected behaviour](../../../common/resources/images/files-order.gif) 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 | --------------------------------------------------------------------------------