├── README.md ├── common └── shower │ ├── shower.min.js │ └── themes │ ├── .DS_Store │ ├── material │ ├── LICENSE.md │ ├── README.md │ ├── fonts │ │ ├── COPYRIGHT.txt │ │ ├── LICENSE.txt │ │ ├── roboto-bold-italic.woff │ │ ├── roboto-bold.woff │ │ ├── roboto-italic.woff │ │ ├── roboto-light.woff │ │ ├── roboto-mono-regular.woff │ │ └── roboto-regular.woff │ ├── images │ │ ├── github.svg │ │ ├── grid.png │ │ └── grid@2x.png │ ├── index.html │ ├── pictures │ │ ├── canvas.png │ │ ├── exact.png │ │ ├── square.png │ │ ├── tall.png │ │ └── wide.png │ └── styles │ │ ├── screen-16x10.css │ │ └── screen-4x3.css │ └── ribbon │ ├── .DS_Store │ ├── LICENSE.md │ ├── README.md │ ├── fonts │ ├── LICENSE.txt │ ├── pt-mono-regular.woff │ ├── pt-sans-bold-italic.woff │ ├── pt-sans-bold.woff │ ├── pt-sans-italic.woff │ ├── pt-sans-narrow-bold.woff │ └── pt-sans-regular.woff │ ├── images │ ├── grid.png │ ├── grid@2x.png │ └── ribbon.svg │ ├── index.html │ ├── pictures │ ├── canvas.png │ ├── exact.png │ ├── square.png │ ├── tall.png │ └── wide.png │ └── styles │ ├── screen-16x10.css │ └── screen-4x3.css └── lections ├── 10 ├── README.md ├── code │ └── simple_forum │ │ ├── Dockerfile │ │ ├── docker-compose.yml │ │ ├── docker-entrypoint.sh │ │ ├── env.txt │ │ ├── forum │ │ ├── __init__.py │ │ ├── admin.py │ │ ├── apps.py │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0002_message_thread.py │ │ │ ├── 0003_message_title.py │ │ │ └── __init__.py │ │ ├── models.py │ │ ├── static │ │ │ └── forum │ │ │ │ ├── css │ │ │ │ ├── bootstrap.min.css │ │ │ │ ├── navbar.css │ │ │ │ └── thread.css │ │ │ │ └── js │ │ │ │ ├── bootstrap.min.js │ │ │ │ ├── jquery.min.js │ │ │ │ └── load_messages.js │ │ ├── templates │ │ │ ├── base.html │ │ │ ├── category.html │ │ │ ├── index.html │ │ │ ├── login.html │ │ │ ├── logout.html │ │ │ ├── register.html │ │ │ └── thread.html │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ │ ├── manage.py │ │ ├── media │ │ └── category_logo │ │ │ ├── info.png │ │ │ └── question.png │ │ ├── requirements.txt │ │ └── simple_forum │ │ ├── __init__.py │ │ ├── settings.py │ │ ├── urls.py │ │ └── wsgi.py └── slides │ ├── index.html │ └── pictures │ ├── architecture.png │ └── cover.jpg ├── 11 ├── README.md ├── code │ └── src │ │ ├── circle │ │ └── circle.go │ │ ├── defer │ │ └── defer.go │ │ ├── fib │ │ └── fib.go │ │ ├── for │ │ └── for.go │ │ ├── func │ │ └── func.go │ │ ├── generator │ │ └── fib_generator.go │ │ ├── hello │ │ └── hello.go │ │ ├── if │ │ └── if.go │ │ └── panic │ │ └── panic.go └── slides │ ├── index.html │ └── pictures │ └── cover.jpg ├── 12 ├── README.md ├── code │ └── src │ │ ├── channels │ │ └── main.go │ │ ├── goroutines │ │ └── main.go │ │ ├── package │ │ ├── exmaple │ │ │ └── example.go │ │ └── main │ │ │ └── main.go │ │ ├── pool │ │ └── main.go │ │ ├── select │ │ └── main.go │ │ ├── tests │ │ ├── example.go │ │ └── example_test.go │ │ └── web │ │ ├── main.go │ │ └── templates │ │ └── index.tpl └── slides │ ├── index.html │ └── pictures │ ├── cover.jpg │ └── goroutines.png ├── 01 ├── README.md └── slides │ ├── img │ ├── 8cfb76c8af04b72de1096c55862ae518.png │ ├── Telegram_logo.svg.png │ ├── bad_version.png │ ├── cover.jpg │ ├── history.svg │ ├── logo.png │ ├── logo.svg │ ├── picture.jpg │ ├── structure.png │ ├── term.png │ ├── us.jpg │ ├── us.pxm │ ├── us1.jpg │ ├── us2.jpg │ └── vcs.png │ └── index.html ├── 02 ├── README.md ├── code │ └── news │ │ ├── index.html │ │ └── styles.css └── slides │ ├── index.html │ └── pictures │ ├── after.png │ ├── before.png │ ├── boxdim.png │ ├── cover.jpg │ ├── cover1.jpg │ ├── css_layout.svg │ ├── history.jpg │ ├── logo.png │ ├── logo.svg │ ├── picture.jpg │ └── сss_awesome.png ├── 03 ├── README.md └── slides │ ├── index.html │ └── pictures │ └── cover.jpg ├── 04 ├── README.md ├── examples │ ├── flask │ │ ├── app.py │ │ └── templates │ │ │ ├── index.html │ │ │ └── login.html │ └── http_server.cpp └── slides │ ├── index.html │ └── pictures │ └── cover.jpg ├── 05 ├── README.md ├── examples │ └── tasktracker │ │ ├── app.py │ │ ├── db.py │ │ ├── db.pyc │ │ ├── static │ │ └── styles.css │ │ ├── tasks.json │ │ ├── templates │ │ ├── index.html │ │ └── login.html │ │ ├── users.json │ │ └── utils.py └── slides │ ├── index.html │ └── pictures │ └── cover.jpg ├── 06 ├── README.md └── slides │ ├── index.html │ └── pictures │ └── cover.jpg ├── 07 ├── README.md ├── code │ ├── create.sql │ ├── fill.sql │ ├── select.py │ ├── select.sql │ └── update.sql └── slides │ ├── index.html │ └── pictures │ └── cover.jpg ├── 08 ├── README.md ├── code │ └── testingplatform │ │ ├── .DS_Store │ │ ├── db.sqlite3 │ │ ├── lessons │ │ ├── .DS_Store │ │ ├── __init__.py │ │ ├── __init__.pyc │ │ ├── admin.py │ │ ├── admin.pyc │ │ ├── migrations │ │ │ ├── 0001_initial.py │ │ │ ├── 0001_initial.pyc │ │ │ ├── 0002_auto_20170226_2056.py │ │ │ ├── 0002_auto_20170226_2056.pyc │ │ │ ├── __init__.py │ │ │ └── __init__.pyc │ │ ├── models.py │ │ ├── models.pyc │ │ ├── submission_testing.py │ │ ├── submission_testing.pyc │ │ ├── templates │ │ │ ├── index.html │ │ │ ├── lesson.html │ │ │ └── problem.html │ │ ├── tests.py │ │ ├── urls.py │ │ ├── urls.pyc │ │ ├── views.py │ │ └── views.pyc │ │ ├── manage.py │ │ └── testingplatform │ │ ├── __init__.py │ │ ├── __init__.pyc │ │ ├── settings.py │ │ ├── settings.pyc │ │ ├── urls.py │ │ ├── urls.pyc │ │ ├── wsgi.py │ │ └── wsgi.pyc └── slides │ ├── .DS_Store │ ├── index.html │ └── pictures │ ├── architecture.jpg │ └── cover.jpg └── 09 ├── README.md └── code └── simple_forum ├── db.sqlite3 ├── forum ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_message_thread.py │ ├── 0003_message_title.py │ └── __init__.py ├── models.py ├── static │ └── forum │ │ ├── css │ │ ├── bootstrap.min.css │ │ ├── navbar.css │ │ └── thread.css │ │ └── js │ │ ├── bootstrap.min.js │ │ ├── jquery.min.js │ │ └── load_messages.js ├── templates │ ├── base.html │ ├── category.html │ ├── index.html │ ├── login.html │ ├── logout.html │ ├── register.html │ └── thread.html ├── tests.py ├── urls.py └── views.py ├── manage.py ├── media └── category_logo │ ├── info.png │ └── question.png └── simple_forum ├── __init__.py ├── settings.py ├── urls.py └── wsgi.py /README.md: -------------------------------------------------------------------------------- 1 | # Курс "Web-программирование", МФТИ 2016 2 | 3 | 1. [Основы UNIX для разработчика. Cисметы контроля версий на примере git.](lections/01) 4 | 2. [HTML & CSS](lections/02) 5 | 3. [JavaScript & jQuery](lections/03) 6 | 4. [HTTP. Основы Python. Flask](lections/04) 7 | 5. [SimpleTaskTracker на Flask](lections/05) 8 | 6. [Deployment](lections/06) 9 | 7. [Базы данных. SQL](lections/07) 10 | 8. [Введение в Django. Django.ORM ](lections/08) 11 | 9. [SimpleForum на Django](lections/09) 12 | 10. [Развертывание проектов с использованием Docker](lections/10) 13 | 11. [Введение в Go](lections/11) 14 | 12. [Введение в Go (продолжение)](lections/12) 15 | -------------------------------------------------------------------------------- /common/shower/themes/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/.DS_Store -------------------------------------------------------------------------------- /common/shower/themes/material/LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright © 2010–2015 Vadim Makeev, http://pepelsbey.net/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | --- 12 | 13 | # Лицензия MIT 14 | 15 | Copyright © 2010–2015 Вадим Макеев, http://pepelsbey.net/ 16 | 17 | Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, добавление, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, также как и лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий: 18 | 19 | Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения. 20 | 21 | ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ. 22 | -------------------------------------------------------------------------------- /common/shower/themes/material/README.md: -------------------------------------------------------------------------------- 1 | # Material theme for Shower [![Build Status](https://travis-ci.org/shower/material.svg?branch=master)](https://travis-ci.org/shower/material) 2 | 3 | ![Ribbon screen shot](pictures/canvas.png) 4 | 5 | Default theme for the [Shower](https://github.com/shower/shower/) presentation engine. Doesn’t include engine itself. [See it in action](http://shwr.me/shower/themes/material/). Follow [@shower_me](https://twitter.com/shower_me) for support and updates, [file an issue](https://github.com/shower/shower/issues/new) if you have any. 6 | 7 | ## Usage 8 | 9 | Get the Shower template where Material is already included. Download the [template archive](http://shwr.me/shower.zip) or install the package: 10 | 11 | npm install shower 12 | 13 | If you want to install Material separately you can download the [theme archive](http://shwr.me/material.zip) or install the package: 14 | 15 | npm install shower-material 16 | 17 | ## Features 18 | 19 | All theme’s features are demonstrated in the [index.html](index.html) file. Use it as a reference while building your presentation. See more detailed [features overview](https://github.com/shower/shower/blob/master/docs/features-en.md). 20 | 21 | ## Ratios 22 | 23 | Material theme supports two slide ratios: wide 16×10 (default) and taller 4×3. To change the slide’s ratio include one of the pre-built `screen-16x10.css` or `screen-4x3.css` files in the `` of your presentation. 24 | 25 | ## PDF 26 | 27 | Ribbon could be exported to PDF by printing it from the list mode in Chrome or Opera browsers. See [printing documentation](https://github.com/shower/shower/blob/master/docs/printing-en.md) for more options. 28 | 29 | ## Development 30 | 31 | If you want to adjust theme for your needs: 32 | 33 | 1. Fork this repository and clone it to your local machine. 34 | 2. Install dependencies: `npm install`. 35 | 3. Start a local server with watcher: `npm run dev` or just `gulp` if you have it installed globally. 36 | 4. Edit your files and see changes in the opened browser. 37 | 38 | To take part in Material development please read [contributing guidelines](CONTRIBUTING.md) first and [file an issue](https://github.com/shower/shower/issues/new) before sending any pull request. 39 | 40 | --- 41 | Licensed under [MIT License](LICENSE.md). 42 | -------------------------------------------------------------------------------- /common/shower/themes/material/fonts/COPYRIGHT.txt: -------------------------------------------------------------------------------- 1 | Copyright 2011 Google Inc. All Rights Reserved. -------------------------------------------------------------------------------- /common/shower/themes/material/fonts/roboto-bold-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/fonts/roboto-bold-italic.woff -------------------------------------------------------------------------------- /common/shower/themes/material/fonts/roboto-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/fonts/roboto-bold.woff -------------------------------------------------------------------------------- /common/shower/themes/material/fonts/roboto-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/fonts/roboto-italic.woff -------------------------------------------------------------------------------- /common/shower/themes/material/fonts/roboto-light.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/fonts/roboto-light.woff -------------------------------------------------------------------------------- /common/shower/themes/material/fonts/roboto-mono-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/fonts/roboto-mono-regular.woff -------------------------------------------------------------------------------- /common/shower/themes/material/fonts/roboto-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/fonts/roboto-regular.woff -------------------------------------------------------------------------------- /common/shower/themes/material/images/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /common/shower/themes/material/images/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/images/grid.png -------------------------------------------------------------------------------- /common/shower/themes/material/images/grid@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/images/grid@2x.png -------------------------------------------------------------------------------- /common/shower/themes/material/pictures/canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/pictures/canvas.png -------------------------------------------------------------------------------- /common/shower/themes/material/pictures/exact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/pictures/exact.png -------------------------------------------------------------------------------- /common/shower/themes/material/pictures/square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/pictures/square.png -------------------------------------------------------------------------------- /common/shower/themes/material/pictures/tall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/pictures/tall.png -------------------------------------------------------------------------------- /common/shower/themes/material/pictures/wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/material/pictures/wide.png -------------------------------------------------------------------------------- /common/shower/themes/ribbon/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/.DS_Store -------------------------------------------------------------------------------- /common/shower/themes/ribbon/LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright © 2010–2016 Vadim Makeev, http://pepelsbey.net/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | --- 12 | 13 | # Лицензия MIT 14 | 15 | Copyright © 2010–2016 Вадим Макеев, http://pepelsbey.net/ 16 | 17 | Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, добавление, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, также как и лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий: 18 | 19 | Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения. 20 | 21 | ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ. 22 | -------------------------------------------------------------------------------- /common/shower/themes/ribbon/README.md: -------------------------------------------------------------------------------- 1 | # Ribbon theme for Shower [![Build Status](https://travis-ci.org/shower/ribbon.svg?branch=master)](https://travis-ci.org/shower/ribbon) 2 | 3 | ![Ribbon screen shot](pictures/canvas.png) 4 | 5 | Default theme for the [Shower](https://github.com/shower/shower/) presentation engine. Doesn’t include engine itself. [See it in action](http://shwr.me/shower/themes/ribbon/). Follow [@shower_me](https://twitter.com/shower_me) for support and updates, [file an issue](https://github.com/shower/shower/issues/new) if you have any. 6 | 7 | ## Usage 8 | 9 | Get the Shower template where Ribbon is already included. Download the [template archive](http://shwr.me/shower.zip) or install the package: 10 | 11 | npm install shower 12 | 13 | If you want to install Ribbon separately you can download the [theme archive](http://shwr.me/ribbon.zip) or install the package: 14 | 15 | npm install shower-ribbon 16 | 17 | ## Features 18 | 19 | All theme’s features are demonstrated in the [index.html](index.html) file. Use it as a reference while building your presentation. See more detailed [features overview](https://github.com/shower/shower/blob/master/docs/features-en.md). 20 | 21 | ## Ratios 22 | 23 | Ribbon theme supports two slide ratios: wide 16×10 (default) and taller 4×3. To change the slide’s ratio include one of the pre-built `screen-16x10.css` or `screen-4x3.css` files in the `` of your presentation. 24 | 25 | ## PDF 26 | 27 | Ribbon could be exported to PDF by printing it from the list mode in Chrome or Opera browsers. See [printing documentation](https://github.com/shower/shower/blob/master/docs/printing-en.md) for more options. 28 | 29 | ## Development 30 | 31 | If you want to adjust theme for your needs: 32 | 33 | 1. Fork this repository and clone it to your local machine. 34 | 2. Install dependencies: `npm install`. 35 | 3. Start a local server with watcher: `npm run dev` or just `gulp` if you have it installed globally. 36 | 4. Edit your files and see changes in the opened browser. 37 | 38 | To take part in Ribbon development please read [contributing guidelines](CONTRIBUTING.md) first and [file an issue](https://github.com/shower/shower/issues/new) before sending any pull request. 39 | 40 | --- 41 | Licensed under [MIT License](LICENSE.md). 42 | -------------------------------------------------------------------------------- /common/shower/themes/ribbon/fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, ParaType Ltd. All Rights Reserved. 2 | 3 | LICENSING AGREEMENT 4 | for the fonts with Original Name: PT Sans, PT Serif, PT Mono. 5 | Version 1.3 - January 20, 2012 6 | 7 | GRANT OF LICENSE 8 | ParaType Ltd grants you the right to use, copy, modify the fonts and distribute 9 | modified and unmodified copies of the fonts by any means, including placing 10 | on Web servers for free downloading, embedding in documents and Web pages, 11 | bundling with commercial and non commercial products, if it does not conflict 12 | with the conditions listed below: 13 | 14 | - You may bundle the font with commercial software, but you may not sell the 15 | fonts by themselves. They are free. 16 | 17 | - You may distribute the fonts in modified or unmodified version only together 18 | with this Licensing Agreement and with above copyright notice. You have no 19 | right to modify the text of Licensing Agreement. It can be placed in a separate 20 | text file or inserted into the font file, but it must be easily viewed by users. 21 | 22 | - You may not distribute modified version of the font under the Original name 23 | or � combination of Original name with any other words without explicit written 24 | permission from ParaType. 25 | 26 | TERMINATION & TERRITORY 27 | This license has no limits on time and territory, but it becomes null and void 28 | if any of the above conditions are not met. 29 | 30 | DISCLAIMER 31 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 32 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY 33 | WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 34 | PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, 35 | OR OTHER RIGHT. IN NO EVENT SHALL PARATYPE BE LIABLE FOR ANY 36 | CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, 37 | INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN 38 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 39 | OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER 40 | DEALINGS IN THE FONT SOFTWARE. 41 | 42 | ParaType Ltd 43 | http://www.paratype.ru 44 | 45 | -------------------------------------------------------------------------------- /common/shower/themes/ribbon/fonts/pt-mono-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/fonts/pt-mono-regular.woff -------------------------------------------------------------------------------- /common/shower/themes/ribbon/fonts/pt-sans-bold-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/fonts/pt-sans-bold-italic.woff -------------------------------------------------------------------------------- /common/shower/themes/ribbon/fonts/pt-sans-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/fonts/pt-sans-bold.woff -------------------------------------------------------------------------------- /common/shower/themes/ribbon/fonts/pt-sans-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/fonts/pt-sans-italic.woff -------------------------------------------------------------------------------- /common/shower/themes/ribbon/fonts/pt-sans-narrow-bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/fonts/pt-sans-narrow-bold.woff -------------------------------------------------------------------------------- /common/shower/themes/ribbon/fonts/pt-sans-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/fonts/pt-sans-regular.woff -------------------------------------------------------------------------------- /common/shower/themes/ribbon/images/grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/images/grid.png -------------------------------------------------------------------------------- /common/shower/themes/ribbon/images/grid@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/images/grid@2x.png -------------------------------------------------------------------------------- /common/shower/themes/ribbon/images/ribbon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /common/shower/themes/ribbon/pictures/canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/pictures/canvas.png -------------------------------------------------------------------------------- /common/shower/themes/ribbon/pictures/exact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/pictures/exact.png -------------------------------------------------------------------------------- /common/shower/themes/ribbon/pictures/square.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/pictures/square.png -------------------------------------------------------------------------------- /common/shower/themes/ribbon/pictures/tall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/pictures/tall.png -------------------------------------------------------------------------------- /common/shower/themes/ribbon/pictures/wide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/common/shower/themes/ribbon/pictures/wide.png -------------------------------------------------------------------------------- /common/shower/themes/ribbon/styles/screen-16x10.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Ribbon theme for Shower HTML presentation engine 3 | * shower-ribbon v2.0.8, https://github.com/shower/ribbon 4 | * @copyright 2010–2016 Vadim Makeev, http://pepelsbey.net/ 5 | * @license MIT 6 | */ 7 | @charset "UTF-8";@font-face{font-family:PT Sans;src:url(../fonts/pt-sans-regular.woff) format("woff")}@font-face{font-weight:700;font-family:PT Sans;src:url(../fonts/pt-sans-bold.woff) format("woff")}@font-face{font-style:italic;font-family:PT Sans;src:url(../fonts/pt-sans-italic.woff) format("woff")}@font-face{font-style:italic;font-weight:700;font-family:PT Sans;src:url(../fonts/pt-sans-bold-italic.woff) format("woff")}@font-face{font-family:PT Sans Narrow;font-weight:700;src:url(../fonts/pt-sans-narrow-bold.woff) format("woff")}@font-face{font-family:PT Mono;src:url(../fonts/pt-mono-regular.woff) format("woff")}*,::after,::before{box-sizing:border-box}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section{display:block}.caption p,body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote::after,blockquote::before,q::after,q::before{content:none}table{border-collapse:collapse;border-spacing:0}a{text-decoration:none}@page{margin:0;size:1024px 640px}.shower{color:#000;counter-reset:slide;font:25px/2 PT Sans,sans-serif;-webkit-print-color-adjust:exact;-webkit-text-size-adjust:none;-moz-text-size-adjust:none;-ms-text-size-adjust:none}@media print{.shower{text-rendering:geometricPrecision}}.caption{font-size:25px;display:none;margin-top:-.2em;padding:0 1em .93em;width:100%;color:#3c3d40;text-shadow:0 1px 0 #8d8e90}@media (min-width:1174px){.caption{font-size:50px}}@media (min-width:2348px){.caption{font-size:100px}}.caption h1{padding-bottom:.15em;font:700 1em/1 PT Sans Narrow,sans-serif}.caption p{font-size:.6em}.caption a{color:#4b86c2;text-shadow:0 -1px 0 #1f3f60}.slide{position:relative;z-index:1;overflow:hidden;padding:106px 100px 0;width:1024px;height:640px;background:#fff;font-size:25px}.slide::after{position:absolute;top:0;right:100px;padding-top:15px;width:50px;height:100px;background:url(../images/ribbon.svg) no-repeat;color:#fff;counter-increment:slide;content:counter(slide);text-align:center}.slide h2{margin-bottom:34px;color:#585a5e;font:700 50px/1 PT Sans Narrow,sans-serif}.slide p{margin-bottom:1em}.slide p.note{color:#979a9e}.slide a{background:-webkit-linear-gradient(bottom,currentColor .09em,transparent .09em) repeat-x;background:linear-gradient(to top,currentColor .09em,transparent .09em) repeat-x;color:#4b86c2}.slide b,.slide strong{font-weight:700}.slide blockquote,.slide dfn,.slide em,.slide i{font-style:italic}.slide code,.slide kbd,.slide mark,.slide samp{padding:.1em .3em;border-radius:.2em}.slide code,.slide kbd,.slide samp{background:rgba(88,90,94,.1);line-height:1;font-family:PT Mono,monospace,monospace}.slide mark{background:#fafaa2}.slide sub,.slide sup{position:relative;line-height:0;font-size:75%}.slide sub{bottom:-.25em}.slide sup{top:-.5em}.slide blockquote::before{position:absolute;margin:-.15em 0 0 -.43em;color:#ccc;line-height:1;font-size:8em;content:'\201C'}.slide blockquote+figcaption{margin:-1em 0 1em;font-style:italic;font-weight:700}.slide ol,.slide ul{margin-bottom:1em;counter-reset:list}.slide ol li,.slide ul li{page-break-inside:avoid;text-indent:-2em}.slide ol li::before,.slide ul li::before{display:inline-block;width:2em;color:#979a9e;text-align:right}.slide ol ol,.slide ol ul,.slide ul ol,.slide ul ul{margin-bottom:0;margin-left:2em}.slide ul>li::before{padding-right:.5em;content:'•'}.slide ul>li:lang(ru)::before{content:'—'}.slide ol>li::before{padding-right:.4em;counter-increment:list;content:counter(list) "."}.slide table{margin-left:-100px;margin-bottom:1em;width:calc(100% + 100px + 100px)}.slide table td:first-child,.slide table th:first-child{padding-left:96px}.slide table td:last-child,.slide table th:last-child{padding-right:96px}.slide table th{text-align:left;font-weight:700}.slide table tr:not(:last-of-type)>*{background:-webkit-linear-gradient(bottom,rgba(88,90,94,.5) .055em,transparent .055em) repeat-x;background:linear-gradient(to top,rgba(88,90,94,.5) .055em,transparent .055em) repeat-x}.slide table.striped tr:nth-child(even){background:rgba(88,90,94,.1)}.slide table.striped tr>*{background-image:none}.slide pre{margin-bottom:1em;counter-reset:code;white-space:normal}.slide pre code{display:block;margin-left:-100px;padding:0 0 0 100px;width:calc(100% + 100px + 100px);border-radius:0;background:0 0;line-height:2;white-space:pre;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.slide pre code:not(:only-child).mark{background:rgba(88,90,94,.1)}.slide pre code:not(:only-child)::before{position:absolute;margin-left:-2em;color:#979a9e;counter-increment:code;content:counter(code,decimal-leading-zero) "."}.slide pre mark{position:relative;z-index:-1;margin:0 -.3em}.slide pre mark.important{background:#c00;color:#fff}.slide pre .comment{color:#999}.slide footer{position:absolute;right:0;bottom:-640px;left:0;display:none;padding:41px 100px 8px;background:#fbfbba;box-shadow:0 1px 0 #fafaa2 inset;-webkit-transition:bottom .3s;transition:bottom .3s}.slide footer mark{background:rgba(255,255,255,.8)}.slide:hover>footer{bottom:0}.slide.grid{background-image:url(../images/grid.png);-ms-interpolation-mode:nearest-neighbor;image-rendering:-webkit-optimize-contrast;image-rendering:-moz-crisp-edges;image-rendering:pixelated}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){.slide.grid{background-image:url(../images/grid@2x.png);background-size:1024px auto}}.slide.black{background-color:#000}.slide.black::after,.slide.white::after{visibility:hidden}.slide.white{background-color:#fff}.slide .double,.slide .triple{-webkit-column-gap:75px;-moz-column-gap:75px;column-gap:75px;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.slide .double{-webkit-column-count:2;-moz-column-count:2;column-count:2}.slide .triple{-webkit-column-count:3;-moz-column-count:3;column-count:3}.slide .shout{position:absolute;top:50%;left:0;width:100%;text-align:center;line-height:1;font-size:150px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.slide .shout a{background:-webkit-linear-gradient(bottom,currentColor .11em,transparent .11em) repeat-x;background:linear-gradient(to top,currentColor .11em,transparent .11em) repeat-x}.slide .cover{z-index:-1;max-width:100%;max-height:100%}.slide .cover.w,.slide .cover.width{width:100%;max-height:none}.slide .cover.h,.slide .cover.height{height:100%;max-width:none}.slide .cover+figcaption{position:absolute;bottom:20px;right:10px;font-size:12px;opacity:.7;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:translateX(100%) rotate(-90deg);transform:translateX(100%) rotate(-90deg)}.slide .cover+figcaption.white{color:#fff}.slide .cover+figcaption a{color:currentcolor}.slide .cover,.slide .place{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.slide .place.b.l,.slide .place.b.r,.slide .place.bottom.left,.slide .place.bottom.right,.slide .place.t.l,.slide .place.t.r,.slide .place.top.left,.slide .place.top.right{-webkit-transform:none;transform:none}.slide .place.b,.slide .place.bottom,.slide .place.t,.slide .place.top{-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}.slide .place.l,.slide .place.left,.slide .place.r,.slide .place.right{-webkit-transform:translate(0,-50%);transform:translate(0,-50%)}.slide .place.t,.slide .place.t.r,.slide .place.top,.slide .place.top.left,.slide .place.top.right{top:0}.slide .place.r,.slide .place.right{right:0;left:auto}.slide .place.b,.slide .place.b.l,.slide .place.b.r,.slide .place.bottom,.slide .place.bottom.left,.slide .place.bottom.right{top:auto;bottom:0}.slide .place.l,.slide .place.left{left:0}.progress{left:-20px;bottom:0;z-index:1;display:none;width:0;height:0;box-sizing:content-box;border:10px solid #4b86c2;border-right-color:transparent;-webkit-transition:width .2s linear;transition:width .2s linear;clip:rect(10px,1044px,20px,20px)}.progress[style*='100%']{padding-left:10px}.badge,.badge a,.progress{position:absolute}.badge{font-size:10px;top:0;z-index:1;overflow:hidden;display:none;width:9em;height:9em;right:0;visibility:hidden}@media (min-width:1174px){.badge{font-size:20px}}@media (min-width:2348px){.badge{font-size:40px}}.badge a{right:-50%;bottom:50%;left:-50%;visibility:visible;background:#4b86c2;color:#fff;text-align:center;line-height:2;-webkit-transform-origin:50% 100%;transform-origin:50% 100%;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.region{display:none}@media screen{.shower.list{padding-top:25px;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;background:#585a5e;position:absolute;clip:rect(0,auto,auto,0)}}@media screen and (min-width:1174px){.shower.list{padding-top:50px}}@media screen and (min-width:2348px){.shower.list{padding-top:100px}}@media screen{.shower.list .caption{display:block}.shower.list .slide{-webkit-transform-origin:0 0;transform-origin:0 0;margin:0 -768px -455px 25px;-webkit-transform:scale(.25);transform:scale(.25);border-radius:2px;box-shadow:0 20px 50px rgba(0,0,0,.3)}}@media screen and (min-width:1174px){.shower.list .slide{margin:0 -512px -270px 50px;-webkit-transform:scale(.5);transform:scale(.5)}}@media screen and (min-width:2348px){.shower.list .slide{margin:0 0 100px 100px;-webkit-transform:scale(1);transform:scale(1)}}@media screen{.shower.list .slide:hover{box-shadow:0 0 0 20px rgba(0,0,0,.1),0 20px 50px rgba(0,0,0,.3)}.shower.list .slide:target{box-shadow:0 0 0 1px #376da3,0 0 0 20px #4b86c2,0 20px 50px rgba(0,0,0,.3)}.shower.list .slide *{pointer-events:none}.shower.list .badge,.shower.list .slide footer{display:block}.shower.full{position:absolute;top:50%;left:50%;overflow:hidden;margin:-320px 0 0 -512px;width:1024px;height:640px;background:#000}.shower.full .slide{position:absolute;top:0;left:0;margin-left:-150%;visibility:hidden}.shower.full .slide:target{margin:0;visibility:visible}.shower.full .slide pre code:not(:only-child).mark.next{visibility:visible;background:0 0}.shower.full .slide pre code:not(:only-child).mark.next.active{background:rgba(88,90,94,.1)}.shower.full .slide .next{visibility:hidden}.shower.full .slide .next.active{visibility:visible}.shower.full .slide .shout.grow,.shower.full .slide .shout.shrink{opacity:0;-webkit-transition:.4s ease-out;transition:.4s ease-out;-webkit-transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}.shower.full .slide .shout.grow{-webkit-transform:scale(.1) translateY(-50%);transform:scale(.1) translateY(-50%)}.shower.full .slide .shout.shrink{-webkit-transform:scale(10) translateY(-50%);transform:scale(10) translateY(-50%)}.shower.full .slide:target .shout.grow,.shower.full .slide:target .shout.shrink{opacity:1;-webkit-transform:scale(1) translateY(-50%);transform:scale(1) translateY(-50%)}.shower.full .progress{display:block;-webkit-transform:translateZ(0);transform:translateZ(0)}.shower.full .region{position:absolute;clip:rect(0 0 0 0);overflow:hidden;margin:-1px;padding:0;width:1px;height:1px;border:none;display:block}} -------------------------------------------------------------------------------- /common/shower/themes/ribbon/styles/screen-4x3.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Ribbon theme for Shower HTML presentation engine 3 | * shower-ribbon v2.0.8, https://github.com/shower/ribbon 4 | * @copyright 2010–2016 Vadim Makeev, http://pepelsbey.net/ 5 | * @license MIT 6 | */ 7 | @charset "UTF-8";@font-face{font-family:PT Sans;src:url(../fonts/pt-sans-regular.woff) format("woff")}@font-face{font-weight:700;font-family:PT Sans;src:url(../fonts/pt-sans-bold.woff) format("woff")}@font-face{font-style:italic;font-family:PT Sans;src:url(../fonts/pt-sans-italic.woff) format("woff")}@font-face{font-style:italic;font-weight:700;font-family:PT Sans;src:url(../fonts/pt-sans-bold-italic.woff) format("woff")}@font-face{font-family:PT Sans Narrow;font-weight:700;src:url(../fonts/pt-sans-narrow-bold.woff) format("woff")}@font-face{font-family:PT Mono;src:url(../fonts/pt-mono-regular.woff) format("woff")}*,::after,::before{box-sizing:border-box}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0;font:inherit;vertical-align:baseline}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section{display:block}.caption p,body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote::after,blockquote::before,q::after,q::before{content:none}table{border-collapse:collapse;border-spacing:0}a{text-decoration:none}@page{margin:0;size:1024px 768px}.shower{color:#000;counter-reset:slide;font:25px/2 PT Sans,sans-serif;-webkit-print-color-adjust:exact;-webkit-text-size-adjust:none;-moz-text-size-adjust:none;-ms-text-size-adjust:none}@media print{.shower{text-rendering:geometricPrecision}}.caption{font-size:25px;display:none;margin-top:-.2em;padding:0 1em .93em;width:100%;color:#3c3d40;text-shadow:0 1px 0 #8d8e90}@media (min-width:1174px){.caption{font-size:50px}}@media (min-width:2348px){.caption{font-size:100px}}.caption h1{padding-bottom:.15em;font:700 1em/1 PT Sans Narrow,sans-serif}.caption p{font-size:.6em}.caption a{color:#4b86c2;text-shadow:0 -1px 0 #1f3f60}.slide{position:relative;z-index:1;overflow:hidden;padding:106px 100px 0;width:1024px;height:768px;background:#fff;font-size:25px}.slide::after{position:absolute;top:0;right:100px;padding-top:15px;width:50px;height:100px;background:url(../images/ribbon.svg) no-repeat;color:#fff;counter-increment:slide;content:counter(slide);text-align:center}.slide h2{margin-bottom:34px;color:#585a5e;font:700 50px/1 PT Sans Narrow,sans-serif}.slide p{margin-bottom:1em}.slide p.note{color:#979a9e}.slide a{background:-webkit-linear-gradient(bottom,currentColor .09em,transparent .09em) repeat-x;background:linear-gradient(to top,currentColor .09em,transparent .09em) repeat-x;color:#4b86c2}.slide b,.slide strong{font-weight:700}.slide blockquote,.slide dfn,.slide em,.slide i{font-style:italic}.slide code,.slide kbd,.slide mark,.slide samp{padding:.1em .3em;border-radius:.2em}.slide code,.slide kbd,.slide samp{background:rgba(88,90,94,.1);line-height:1;font-family:PT Mono,monospace,monospace}.slide mark{background:#fafaa2}.slide sub,.slide sup{position:relative;line-height:0;font-size:75%}.slide sub{bottom:-.25em}.slide sup{top:-.5em}.slide blockquote::before{position:absolute;margin:-.15em 0 0 -.43em;color:#ccc;line-height:1;font-size:8em;content:'\201C'}.slide blockquote+figcaption{margin:-1em 0 1em;font-style:italic;font-weight:700}.slide ol,.slide ul{margin-bottom:1em;counter-reset:list}.slide ol li,.slide ul li{page-break-inside:avoid;text-indent:-2em}.slide ol li::before,.slide ul li::before{display:inline-block;width:2em;color:#979a9e;text-align:right}.slide ol ol,.slide ol ul,.slide ul ol,.slide ul ul{margin-bottom:0;margin-left:2em}.slide ul>li::before{padding-right:.5em;content:'•'}.slide ul>li:lang(ru)::before{content:'—'}.slide ol>li::before{padding-right:.4em;counter-increment:list;content:counter(list) "."}.slide table{margin-left:-100px;margin-bottom:1em;width:calc(100% + 100px + 100px)}.slide table td:first-child,.slide table th:first-child{padding-left:96px}.slide table td:last-child,.slide table th:last-child{padding-right:96px}.slide table th{text-align:left;font-weight:700}.slide table tr:not(:last-of-type)>*{background:-webkit-linear-gradient(bottom,rgba(88,90,94,.5) .055em,transparent .055em) repeat-x;background:linear-gradient(to top,rgba(88,90,94,.5) .055em,transparent .055em) repeat-x}.slide table.striped tr:nth-child(even){background:rgba(88,90,94,.1)}.slide table.striped tr>*{background-image:none}.slide pre{margin-bottom:1em;counter-reset:code;white-space:normal}.slide pre code{display:block;margin-left:-100px;padding:0 0 0 100px;width:calc(100% + 100px + 100px);border-radius:0;background:0 0;line-height:2;white-space:pre;-moz-tab-size:4;-o-tab-size:4;tab-size:4}.slide pre code:not(:only-child).mark{background:rgba(88,90,94,.1)}.slide pre code:not(:only-child)::before{position:absolute;margin-left:-2em;color:#979a9e;counter-increment:code;content:counter(code,decimal-leading-zero) "."}.slide pre mark{position:relative;z-index:-1;margin:0 -.3em}.slide pre mark.important{background:#c00;color:#fff}.slide pre .comment{color:#999}.slide footer{position:absolute;right:0;bottom:-768px;left:0;display:none;padding:41px 100px 8px;background:#fbfbba;box-shadow:0 1px 0 #fafaa2 inset;-webkit-transition:bottom .3s;transition:bottom .3s}.slide footer mark{background:rgba(255,255,255,.8)}.slide:hover>footer{bottom:0}.slide.grid{background-image:url(../images/grid.png);-ms-interpolation-mode:nearest-neighbor;image-rendering:-webkit-optimize-contrast;image-rendering:-moz-crisp-edges;image-rendering:pixelated}@media (-webkit-min-device-pixel-ratio:2),(min-resolution:2dppx){.slide.grid{background-image:url(../images/grid@2x.png);background-size:1024px auto}}.slide.black{background-color:#000}.slide.black::after,.slide.white::after{visibility:hidden}.slide.white{background-color:#fff}.slide .double,.slide .triple{-webkit-column-gap:75px;-moz-column-gap:75px;column-gap:75px;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.slide .double{-webkit-column-count:2;-moz-column-count:2;column-count:2}.slide .triple{-webkit-column-count:3;-moz-column-count:3;column-count:3}.slide .shout{position:absolute;top:50%;left:0;width:100%;text-align:center;line-height:1;font-size:150px;-webkit-transform:translateY(-50%);transform:translateY(-50%)}.slide .shout a{background:-webkit-linear-gradient(bottom,currentColor .11em,transparent .11em) repeat-x;background:linear-gradient(to top,currentColor .11em,transparent .11em) repeat-x}.slide .cover{z-index:-1;max-width:100%;max-height:100%}.slide .cover.w,.slide .cover.width{width:100%;max-height:none}.slide .cover.h,.slide .cover.height{height:100%;max-width:none}.slide .cover+figcaption{position:absolute;bottom:20px;right:10px;font-size:12px;opacity:.7;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:translateX(100%) rotate(-90deg);transform:translateX(100%) rotate(-90deg)}.slide .cover+figcaption.white{color:#fff}.slide .cover+figcaption a{color:currentcolor}.slide .cover,.slide .place{position:absolute;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.slide .place.b.l,.slide .place.b.r,.slide .place.bottom.left,.slide .place.bottom.right,.slide .place.t.l,.slide .place.t.r,.slide .place.top.left,.slide .place.top.right{-webkit-transform:none;transform:none}.slide .place.b,.slide .place.bottom,.slide .place.t,.slide .place.top{-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}.slide .place.l,.slide .place.left,.slide .place.r,.slide .place.right{-webkit-transform:translate(0,-50%);transform:translate(0,-50%)}.slide .place.t,.slide .place.t.r,.slide .place.top,.slide .place.top.left,.slide .place.top.right{top:0}.slide .place.r,.slide .place.right{right:0;left:auto}.slide .place.b,.slide .place.b.l,.slide .place.b.r,.slide .place.bottom,.slide .place.bottom.left,.slide .place.bottom.right{top:auto;bottom:0}.slide .place.l,.slide .place.left{left:0}.progress{left:-20px;bottom:0;z-index:1;display:none;width:0;height:0;box-sizing:content-box;border:10px solid #4b86c2;border-right-color:transparent;-webkit-transition:width .2s linear;transition:width .2s linear;clip:rect(10px,1044px,20px,20px)}.progress[style*='100%']{padding-left:10px}.badge,.badge a,.progress{position:absolute}.badge{font-size:10px;top:0;z-index:1;overflow:hidden;display:none;width:9em;height:9em;right:0;visibility:hidden}@media (min-width:1174px){.badge{font-size:20px}}@media (min-width:2348px){.badge{font-size:40px}}.badge a{right:-50%;bottom:50%;left:-50%;visibility:visible;background:#4b86c2;color:#fff;text-align:center;line-height:2;-webkit-transform-origin:50% 100%;transform-origin:50% 100%;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.region{display:none}@media screen{.shower.list{padding-top:25px;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;background:#585a5e;position:absolute;clip:rect(0,auto,auto,0)}}@media screen and (min-width:1174px){.shower.list{padding-top:50px}}@media screen and (min-width:2348px){.shower.list{padding-top:100px}}@media screen{.shower.list .caption{display:block}.shower.list .slide{-webkit-transform-origin:0 0;transform-origin:0 0;margin:0 -768px -551px 25px;-webkit-transform:scale(.25);transform:scale(.25);border-radius:2px;box-shadow:0 20px 50px rgba(0,0,0,.3)}}@media screen and (min-width:1174px){.shower.list .slide{margin:0 -512px -334px 50px;-webkit-transform:scale(.5);transform:scale(.5)}}@media screen and (min-width:2348px){.shower.list .slide{margin:0 0 100px 100px;-webkit-transform:scale(1);transform:scale(1)}}@media screen{.shower.list .slide:hover{box-shadow:0 0 0 20px rgba(0,0,0,.1),0 20px 50px rgba(0,0,0,.3)}.shower.list .slide:target{box-shadow:0 0 0 1px #376da3,0 0 0 20px #4b86c2,0 20px 50px rgba(0,0,0,.3)}.shower.list .slide *{pointer-events:none}.shower.list .badge,.shower.list .slide footer{display:block}.shower.full{position:absolute;top:50%;left:50%;overflow:hidden;margin:-384px 0 0 -512px;width:1024px;height:768px;background:#000}.shower.full .slide{position:absolute;top:0;left:0;margin-left:-150%;visibility:hidden}.shower.full .slide:target{margin:0;visibility:visible}.shower.full .slide pre code:not(:only-child).mark.next{visibility:visible;background:0 0}.shower.full .slide pre code:not(:only-child).mark.next.active{background:rgba(88,90,94,.1)}.shower.full .slide .next{visibility:hidden}.shower.full .slide .next.active{visibility:visible}.shower.full .slide .shout.grow,.shower.full .slide .shout.shrink{opacity:0;-webkit-transition:.4s ease-out;transition:.4s ease-out;-webkit-transition-property:opacity,-webkit-transform;transition-property:opacity,transform;transition-property:opacity,transform,-webkit-transform}.shower.full .slide .shout.grow{-webkit-transform:scale(.1) translateY(-50%);transform:scale(.1) translateY(-50%)}.shower.full .slide .shout.shrink{-webkit-transform:scale(10) translateY(-50%);transform:scale(10) translateY(-50%)}.shower.full .slide:target .shout.grow,.shower.full .slide:target .shout.shrink{opacity:1;-webkit-transform:scale(1) translateY(-50%);transform:scale(1) translateY(-50%)}.shower.full .progress{display:block;-webkit-transform:translateZ(0);transform:translateZ(0)}.shower.full .region{position:absolute;clip:rect(0 0 0 0);overflow:hidden;margin:-1px;padding:0;width:1px;height:1px;border:none;display:block}} -------------------------------------------------------------------------------- /lections/01/README.md: -------------------------------------------------------------------------------- 1 | # Основы UNIX для разработчика. Системы контроля версий на примере git. 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/01/slides/)** 4 | 5 | **[Скринкаст](https://youtu.be/2aQ0JLFlpEU)** 6 | 7 | * [Ubuntu 16.04](http://releases.ubuntu.com/16.04/) 8 | * [VirtualBox](https://www.virtualbox.org) 9 | * [Знакомство с UNIX](https://ru.wikibooks.org/wiki/Введение_в_администрирование_UNIX/Командная_строка_UNIX) 10 | 11 | **Команда для установки дополниней в Ubuntu для virtualbox:** 12 | ``` 13 | sudo apt-get install virtualbox-guest-additions-iso 14 | ``` 15 | 16 | Маны на русском для наиболее важных комманд: 17 | * [ls](http://citforum.ru/operating_systems/manpages/LS.1.shtml) 18 | * [cd](http://citforum.ru/operating_systems/manpages/CD.1.shtml) 19 | * [pwd](http://citforum.ru/operating_systems/manpages/PWD.1.shtml) 20 | * [cat](http://citforum.ru/operating_systems/manpages/CAT.1.shtml) 21 | * [grep](http://citforum.ru/operating_systems/manpages/GREP.1.shtml) 22 | * [egrep](http://citforum.ru/operating_systems/manpages/EGREP.1.shtml) 23 | * [fgrep](http://citforum.ru/operating_systems/manpages/FGREP.1.shtml) 24 | * [rm](http://citforum.ru/operating_systems/manpages/RM.1.shtml) 25 | * [mv](http://citforum.ru/operating_systems/manpages/MV.1.shtml) 26 | * [cp](http://citforum.ru/operating_systems/manpages/CP.1.shtml) 27 | 28 | Введение в команды Git: [learngitbranching.js.org](http://learngitbranching.js.org) 29 | -------------------------------------------------------------------------------- /lections/01/slides/img/8cfb76c8af04b72de1096c55862ae518.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/8cfb76c8af04b72de1096c55862ae518.png -------------------------------------------------------------------------------- /lections/01/slides/img/Telegram_logo.svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/Telegram_logo.svg.png -------------------------------------------------------------------------------- /lections/01/slides/img/bad_version.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/bad_version.png -------------------------------------------------------------------------------- /lections/01/slides/img/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/cover.jpg -------------------------------------------------------------------------------- /lections/01/slides/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/logo.png -------------------------------------------------------------------------------- /lections/01/slides/img/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lections/01/slides/img/picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/picture.jpg -------------------------------------------------------------------------------- /lections/01/slides/img/structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/structure.png -------------------------------------------------------------------------------- /lections/01/slides/img/term.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/term.png -------------------------------------------------------------------------------- /lections/01/slides/img/us.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/us.jpg -------------------------------------------------------------------------------- /lections/01/slides/img/us.pxm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/us.pxm -------------------------------------------------------------------------------- /lections/01/slides/img/us1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/us1.jpg -------------------------------------------------------------------------------- /lections/01/slides/img/us2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/us2.jpg -------------------------------------------------------------------------------- /lections/01/slides/img/vcs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/01/slides/img/vcs.png -------------------------------------------------------------------------------- /lections/02/README.md: -------------------------------------------------------------------------------- 1 | # HTML & CSS 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/02/slides/)** 4 | 5 | **[Скринкаст](https://youtu.be/64hkvLPb7Yg)** 6 | 7 | **[Код сайта с новостями](code/news)** 8 | 9 | Полезные ресурсы: 10 | * [Codeacademy](https://www.codecademy.com/learn/web) 11 | * [Udacity](https://www.udacity.com/course/intro-to-html-and-css--ud304) 12 | * [Shayhowe](http://learn.shayhowe.com/html-css/building-your-first-web-page/) 13 | * [HtmlAcademy (на русском)](https://htmlacademy.ru) 14 | * [Избегаем распространенных ошибок в HTML5 разметке](https://habrahabr.ru/post/124993/) 15 | * [Minifier - 1](http://www.willpeavy.com/minifier/) 16 | * [Minifier - 2](https://kangax.github.io/html-minifier/) 17 | * [HtmlMinifier](https://github.com/kangax/html-minifier) 18 | * [CSS units](https://developer.mozilla.org/ru/docs/Web/CSS/размер) 19 | * [FlexBox](http://habrahabr.ru/post/242545/) 20 | -------------------------------------------------------------------------------- /lections/02/code/news/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Новости курса 8 | 9 | 10 |
11 | 12 | Новости курса "Web-программирование" 13 |
14 | 15 |
16 | 17 | 24 | 25 |
26 | 27 |
28 |
29 |
Занятие 3 ноября
30 |
31 |
02.10.2016
32 | 33 |
34 |
35 |
36 |

Всем привет! 37 | Завтрашнее занятие состоится в физтех-парке в 20.15. Подходить можно к 20.00, обсудить вопросы и другие интересующие вещи. 38 |

39 | 40 |

С собой иметь паспорт для прохода в здание.

41 | 42 | 43 |
44 |
45 | 46 | 47 | 48 |
49 |
50 |
Занятие 27 октября отменяется
51 |
52 |
27.10.2016
53 | 56 |
57 |
58 |
59 |

60 | Всем привет! 61 | К сожалению, в будние дни на физтехе найти аудиторию даже в 8 часов вечера - непосильная задача (по крайней мере, со стороны учебного отдела). Поэтому есть две новости: хорошая и плохая. 62 | Хорошая заключается в том, что нас любезно согласился приютить физтех-парк. Поэтому занятия будут проходить там в 8 вечера. 63 | Плохая же новость заключается в том, что впустить нас они смогут только со следующей недели. Поэтому первое занятие состоится через неделю, 3 ноября. 64 | Лекция, которая планировалась быть сегодня, должна была быть посвящена знакомству с системой Ubuntu, разворачиванию ее на виртуальной машине и работе с ней. Кроме этого, планировалось рассказать про git и GitHub (который активно понадобится нам в качестве хостинга на ближайших занятиях). Это должно было быть вводное занятие для знакомства с базовыми инструментами, чтобы не останавливаться на них при знакомстве с технологиями. На все возникающие вопросы будут даны ответы либо на следующем занятии, либо в общем чате telegram (ссылка будет отдельным постом). 65 |

66 |

67 | В связи с этими обстоятельствами, есть два варианта развития событий: 68 |
    69 |
  1. Просто перенесем лекцию на неделю вперед.
  2. 70 |
  3. Запишем скринкаст по данным темам и выложим его к выходным. Тогда со следующего занятия можно будет начать знакомство с HTML и CSS, таким образом переходя непосредственно к технологиям.
  4. 71 |
72 |

73 |
74 |
75 | 76 |
77 | 78 |
79 | 80 | 81 | -------------------------------------------------------------------------------- /lections/02/code/news/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: rgb(243, 234, 245); 3 | } 4 | 5 | header { 6 | text-align:center; 7 | border: 4px double black; 8 | font-size: 30pt; 9 | font-weight: bold; 10 | margin: 20px 40px; 11 | } 12 | 13 | .navigation { 14 | width: 20%; 15 | vertical-align: top; 16 | position: fixed; 17 | top: 15%; 18 | } 19 | 20 | .articles { 21 | width: 70%; 22 | margin: 0px auto; 23 | position: absolute; 24 | left: 20%; 25 | } 26 | 27 | .article { 28 | background: rgb(200, 202, 245); 29 | border: 1px solid black; 30 | border-radius: 20px; 31 | padding: 10px; 32 | margin: 10px; 33 | } 34 | 35 | .article > .header > .title { 36 | font-size: 18pt; 37 | font-weight: bold; 38 | } 39 | 40 | .article > .header > .subtitle { 41 | font-size: 10pt; 42 | } 43 | 44 | .article > .header > .subtitle > .date { 45 | position: relative; 46 | display: inline-block; 47 | margin-right: 20px; 48 | } 49 | 50 | .article > .header > .subtitle > .link { 51 | position: relative; 52 | display: inline-block; 53 | } 54 | 55 | .article > .body > img { 56 | width: 50%; 57 | } 58 | 59 | .article > .header > .title:hover { 60 | color: red; 61 | } 62 | -------------------------------------------------------------------------------- /lections/02/slides/pictures/after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/after.png -------------------------------------------------------------------------------- /lections/02/slides/pictures/before.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/before.png -------------------------------------------------------------------------------- /lections/02/slides/pictures/boxdim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/boxdim.png -------------------------------------------------------------------------------- /lections/02/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/02/slides/pictures/cover1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/cover1.jpg -------------------------------------------------------------------------------- /lections/02/slides/pictures/css_layout.svg: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | <header> 15 | 16 | 17 | 18 | <footer> 19 | 20 | 21 | 22 | <nav> 23 | 24 | 25 | 26 | <article> 27 | 28 | 29 | 30 | <aside> 31 | 32 | -------------------------------------------------------------------------------- /lections/02/slides/pictures/history.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/history.jpg -------------------------------------------------------------------------------- /lections/02/slides/pictures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/logo.png -------------------------------------------------------------------------------- /lections/02/slides/pictures/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /lections/02/slides/pictures/picture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/picture.jpg -------------------------------------------------------------------------------- /lections/02/slides/pictures/сss_awesome.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/02/slides/pictures/сss_awesome.png -------------------------------------------------------------------------------- /lections/03/README.md: -------------------------------------------------------------------------------- 1 | # HTML & CSS 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/03/slides/)** 4 | 5 | **[Скринкаст](https://youtu.be/jL4_A9URkQ4)** 6 | 7 | 8 | Полезные ресурсы: 9 | * [ECMAScript standart](http://www.ecma-international.org/ecma-262/6.0/) 10 | * [ES6 compatibility table](https://kangax.github.io/compat-table/es6/) 11 | * [Asm.js](https://en.wikipedia.org/wiki/Asm.js) 12 | * [Eloquent JavaScript, русский перевод](https://habrahabr.ru/post/240219/) 13 | * [Курс по jQuery на CodeAcademy](https://www.codecademy.com/learn/jquery) 14 | 15 | -------------------------------------------------------------------------------- /lections/03/slides/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Веб-программирование на Физтехе 2016-2017 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Веб-программирование на Физтехе 2016-2017

13 |

Занятие 3. Знакомство с JavaScript и jQuery

14 |
15 |
16 |

Занятие 3. JavaScript & jQuery

17 |

Web Programming @ MIPT, 2016-2017

18 | 19 | 23 | 41 |
42 |
43 |

What is JavaScript

44 | 53 |
54 | 55 |
56 |

Languages compiled to JS

57 | 62 |
63 | 64 |
65 |

History

66 | 74 |
75 | 76 |
77 |

Engines

78 | 84 |

Modern JS engines use just-in-time compilation to achieve better performance.

85 |

There is asm.js subset of JS, 86 | normally generated by special tools, which may be slower 1.5-2x than C.

87 |
88 | 89 |
90 |

JavaScript Demos

91 | 95 |
96 | 97 |
98 |

DomContentReady - not working

99 | 100 |
<script type="text/javascript">
101 |     document.getElementById('press').addEventListener('click', function() {
102 | 		alert('Hi!');
103 | 	});
104 | </script>
105 | 
106 | <input type="button" id='press' value="Press me">
107 |
108 | 109 |
110 |

DomContentReady - possible solution

111 | 112 |

113 | <input type="button" id='press' value="Press me">
114 | 
115 | <script type="text/javascript">
116 |     document.getElementById('press').addEventListener('click', function() {
117 | 		alert('Hi!');
118 | 	});
119 | </script>
120 | 
121 |
122 | 123 |
124 |

DomContentReady - solution

125 | 126 |

127 | <script type="text/javascript">
128 |     document.addEventListener('DOMContentLoaded', function() {
129 |   	    document.getElementById('press').addEventListener('click', function() {
130 |   		    alert('Hi!');
131 |   	    });
132 |     });
133 | </script>
134 | 
135 | <input type="button" id='press' value="Press me">
136 | 
137 |
138 | 139 |
140 |

JavaScript Events

141 | 146 |
147 | 148 |
149 |

jQuery

150 | 157 |
158 | 159 |
160 |

jQuery Demos

161 | 167 |
168 | 169 |
170 |

Minification

171 | 181 |
182 | 183 |
184 |

Lightweight jQuery alternatives

185 | 190 |
191 | 192 |
193 |

JavaScript & jQuery resources

194 | 201 |
202 | 203 |
204 |

Homework

205 | 208 | 209 |
210 | 211 |
212 |

Вопросы?

213 |
214 | 218 |
219 | 220 | 221 | 222 | 223 | 224 | -------------------------------------------------------------------------------- /lections/03/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/03/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/04/README.md: -------------------------------------------------------------------------------- 1 | ## HTTP. Основы Python. Flask 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/04/slides/)** 4 | 5 | **[Скринкаст](https://youtu.be/9uANAf9w0aE)** 6 | 7 | * [HTTP сервер на сокетах](examples/http_server.cpp) 8 | * [Простое flask-приложение](examples/flask) 9 | 10 | * [Интерактивный учебник по Python](http://pythontutor.ru) 11 | * [Flask](http://flask.pocoo.org) 12 | -------------------------------------------------------------------------------- /lections/04/examples/flask/app.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Flask, render_template, send_from_directory, request, abort, session, redirect 4 | 5 | app = Flask("Simple app") 6 | 7 | template_dir = 'templates' 8 | 9 | @app.route('/', methods=['GET']) 10 | def index(): 11 | username = session.get('username', None) 12 | if username is None: 13 | return redirect("/login") 14 | return render_template('index.html', username=username) 15 | 16 | @app.route('/login', methods=['GET', 'POST']) 17 | def login(): 18 | if request.method == 'GET': 19 | return render_template('login.html') 20 | elif request.method == 'POST': 21 | username = request.form.get('username', None) 22 | password = request.form.get('password', None) 23 | if username is None or password is None or username != password: 24 | return render_template('login.html', error=u"Некорректные данные для входа") 25 | session['username'] = username 26 | session.modified = True 27 | return redirect("/") 28 | else: 29 | abort(501) 30 | 31 | if __name__ == "__main__": 32 | app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' 33 | app.run(port=8001) 34 | -------------------------------------------------------------------------------- /lections/04/examples/flask/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Главная страница 6 | 7 | 8 |

Привет, {{ username }}!

9 | 10 | 11 | -------------------------------------------------------------------------------- /lections/04/examples/flask/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Login 6 | 7 | 8 |
9 |

Войдите, пожалуйста

10 |
11 | 12 |
13 | 14 |
15 | 16 |
17 | 18 | {% if error %} 19 |

{{ error }}

20 | {% endif %} 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /lections/04/examples/http_server.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | 7 | using namespace boost::asio; 8 | using boost::system::error_code; 9 | 10 | io_service service; 11 | 12 | std::string handle(const std::string& req) 13 | { 14 | std::stringstream response_body; 15 | response_body << "Test C++ HTTP Server\n" 16 | << "

Test page

\n" 17 | << "

This is body of the test page...

\n" 18 | << "

Request headers

\n" 19 | << "
" << req << "
\n" 20 | << "Test C++ Http Server\n"; 21 | 22 | std::stringstream response; 23 | response << "HTTP/1.1 200 OK\r\n" 24 | << "Version: HTTP/1.1\r\n" 25 | << "Content-Type: text/html; charset=utf-8\r\n" 26 | << "Content-Length: " << response_body.str().length() 27 | << "\r\n\r\n" 28 | << response_body.str(); 29 | 30 | return response.str(); 31 | } 32 | 33 | size_t read_complete(char * buff, const error_code & err, size_t bytes) { 34 | if (err) return 0; 35 | for (char* b = buff; b < buff + bytes - 3; ++b) { 36 | if (*b == '\r' && *(b + 1) == '\n' 37 | && *(b + 2) == '\r' && *(b + 3) == '\n') { 38 | return 0; 39 | } 40 | } 41 | return 1; 42 | } 43 | 44 | void handle_connections() { 45 | ip::tcp::acceptor acceptor(service, ip::tcp::endpoint(ip::tcp::v4(), 8001)); 46 | char buff[1024]; 47 | while (true) { 48 | ip::tcp::socket sock(service); 49 | acceptor.accept(sock); 50 | int bytes = read(sock, buffer(buff), 51 | boost::bind(read_complete, buff, _1, _2)); 52 | std::string msg(buff, bytes); 53 | sock.write_some(buffer(handle(msg))); 54 | sock.close(); 55 | } 56 | } 57 | 58 | int main() 59 | { 60 | handle_connections(); 61 | return 0; 62 | } 63 | -------------------------------------------------------------------------------- /lections/04/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/04/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/05/README.md: -------------------------------------------------------------------------------- 1 | ## SimpleTaskTracker на Flask 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/05/slides/)** 4 | 5 | **[Скринкаст](https://youtu.be/lh0EKMfHZP0)** 6 | 7 | * [Исходный код SimpleTaskTracker](examples/tasktracker) 8 | -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/app.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from flask import Flask, abort, render_template, request, jsonify, session, redirect 4 | from utils import * 5 | from db import * 6 | 7 | app = Flask("SimpleTaskTracker") 8 | template_dir = 'templates' 9 | 10 | @app.route('/', methods=['GET']) 11 | @authorized 12 | def index(): 13 | return render_template('index.html') 14 | 15 | @app.route('/login', methods=["GET"]) 16 | @not_authorized 17 | def login(): 18 | return render_template('login.html') 19 | 20 | @app.route('/api/login', methods=["POST"]) 21 | @not_authorized 22 | def api_login(): 23 | login = request.form.get('login', None) 24 | password = request.form.get('password', None) 25 | if login is None or password is None: 26 | return jsonify({'status': 'error', 'message': 'Неверные данные для входа'}) 27 | user = authorize(login, password) 28 | if user.is_authorized(): 29 | session['user_login'] = login 30 | return jsonify({'status': 'ok'}) 31 | return jsonify({'status': 'error', 'message': 'Неверные данные для входа'}) 32 | 33 | @app.route('/logout', methods=["GET"]) 34 | @authorized 35 | def logout(): 36 | session.clear() 37 | return redirect('/login') 38 | 39 | @app.route('/api/tasks', methods=["GET"]) 40 | @authorized 41 | def api_tasks(): 42 | login = session['user_login'] 43 | return jsonify({"tasks": get_tasks(login)}) 44 | 45 | @app.route('/api/remove_task/', methods=["GET"]) 46 | @authorized 47 | def api_remove_task(task_id): 48 | login = session['user_login'] 49 | remove_task(login, task_id) 50 | return jsonify({'status': 'ok'}) 51 | 52 | @app.route('/api/add_task', methods=["POST"]) 53 | @authorized 54 | def api_add_task(): 55 | login = session['user_login'] 56 | text = request.form.get('text', None) 57 | if text is None: 58 | return jsonify({'status': 'error', 'message': 'Некорректный запрос'}) 59 | task_id = add_task(login, text) 60 | return jsonify({'status': 'ok', 'task_id': task_id}) 61 | 62 | if __name__ == "__main__": 63 | app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT' 64 | app.run(port=8001) 65 | -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/db.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | def get_tasks(login): 4 | with open('tasks.json') as f: 5 | tasks = json.load(f) 6 | if not login in tasks: 7 | return [] 8 | return tasks[login] 9 | 10 | def add_task(login, text): 11 | with open('tasks.json') as f: 12 | tasks = json.load(f) 13 | if not login in tasks: 14 | tasks[login] = [] 15 | task_id = 1 16 | else: 17 | if len(tasks[login]) == 0: 18 | task_id = 1 19 | else: 20 | task_id = tasks[login][-1]["id"] + 1 21 | tasks[login].append({"id": task_id, "text": text}) 22 | with open('tasks.json', 'w') as f: 23 | json.dump(tasks, f) 24 | return task_id 25 | 26 | def remove_task(login, id): 27 | with open('tasks.json') as f: 28 | tasks = json.load(f) 29 | if not login in tasks: 30 | return 31 | for i, task in enumerate(tasks[login]): 32 | if task['id'] == id: 33 | del tasks[login][i] 34 | break 35 | with open('tasks.json', 'w') as f: 36 | json.dump(tasks, f) 37 | -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/db.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/05/examples/tasktracker/db.pyc -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/static/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 40px; 3 | padding-bottom: 40px; 4 | } 5 | 6 | .container { 7 | background-color: #eee; 8 | width: 500px; 9 | height: 350px; 10 | position: absolute; 11 | top:0; 12 | bottom: 0; 13 | left: 0; 14 | right: 0; 15 | margin: auto; 16 | border: 1px solid black; 17 | border-radius: 10px; 18 | } 19 | 20 | .container_2 { 21 | background-color: #eee; 22 | width: 500px; 23 | margin: 50px auto; 24 | padding: 20px; 25 | border: 1px solid black; 26 | border-radius: 10px; 27 | } 28 | 29 | .header { 30 | margin-left: auto; 31 | margin-right: auto; 32 | width: 50%; 33 | text-align: center; 34 | border-bottom: 1px solid grey; 35 | } 36 | 37 | .form-signin { 38 | max-width: 330px; 39 | padding: 15px; 40 | margin: 0 auto; 41 | } 42 | .form-signin .form-signin-heading, 43 | .form-signin .checkbox { 44 | margin-bottom: 10px; 45 | } 46 | .form-signin .checkbox { 47 | font-weight: normal; 48 | } 49 | .form-signin .form-control { 50 | position: relative; 51 | height: auto; 52 | -webkit-box-sizing: border-box; 53 | -moz-box-sizing: border-box; 54 | box-sizing: border-box; 55 | padding: 10px; 56 | font-size: 16px; 57 | } 58 | .form-signin .form-control:focus { 59 | z-index: 2; 60 | } 61 | .form-signin input[type="email"] { 62 | margin-bottom: -1px; 63 | border-bottom-right-radius: 0; 64 | border-bottom-left-radius: 0; 65 | } 66 | .form-signin input[type="password"] { 67 | margin-bottom: 10px; 68 | border-top-left-radius: 0; 69 | border-top-right-radius: 0; 70 | } 71 | -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/tasks.json: -------------------------------------------------------------------------------- 1 | {"admin": []} -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tasks - SimpleTaskTracker 6 | 10 | 13 | 14 | 15 | 19 | 20 | 21 |
22 |

SimpleTaskTracker

23 |
24 |
25 |
26 | 27 | 28 | 29 | 30 |
31 | 32 |
33 |
34 |
35 | 36 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Sign in - SimpleTaskTracker 6 | 10 | 13 | 14 | 15 | 19 | 20 | 21 |
22 |

SimpleTaskTracker

23 |
24 |
25 | 35 | 36 |
37 | 38 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/users.json: -------------------------------------------------------------------------------- 1 | { 2 | "admin": { 3 | "password": "123" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lections/05/examples/tasktracker/utils.py: -------------------------------------------------------------------------------- 1 | import json 2 | from flask import redirect, session 3 | from functools import wraps 4 | 5 | with open('users.json') as users_file: 6 | g_users = json.load(users_file) 7 | 8 | class User(object): 9 | def __init__(self, login): 10 | if login is not None and login in g_users: 11 | self.login = login 12 | self.anonymous = False 13 | self.password = g_users[login]["password"] 14 | else: 15 | self.anonymous = True 16 | 17 | def is_anonymous(self): 18 | return self.anonymous 19 | 20 | def is_authorized(self): 21 | return not self.anonymous 22 | 23 | 24 | def authorize(login, password): 25 | user = User(login) 26 | if not user.is_authorized(): 27 | return user 28 | if user.password == password: 29 | return user 30 | return User(None) 31 | 32 | def get_user(login): 33 | return User(login) 34 | 35 | def authorized(fn): 36 | @wraps(fn) 37 | def wrapped(*args, **kwargs): 38 | user = get_user(session.get("user_login", None)) 39 | if user.is_authorized(): 40 | return fn(*args, **kwargs) 41 | else: 42 | return redirect('/login') 43 | return wrapped 44 | 45 | def not_authorized(fn): 46 | @wraps(fn) 47 | def wrapped(): 48 | user = get_user(session.get("user_login", "")) 49 | if not user.is_authorized(): 50 | return fn() 51 | else: 52 | return redirect('/') 53 | return wrapped 54 | -------------------------------------------------------------------------------- /lections/05/slides/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Веб-программирование на Физтехе 2016-2017 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Веб-программирование на Физтехе 2016-2017

13 |

Занятие 5. SimpleTaskTracker на Flask

14 |
15 |
16 |

Занятие 5. SimpleTaskTracker на Flask

17 |

Web Programming @ MIPT, 2016-2017

18 | 19 | 23 | 41 |
42 |
43 |

Demo

44 |
45 | 46 |
47 |

Вопросы?

48 |
49 | 53 |
54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /lections/05/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/05/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/06/README.md: -------------------------------------------------------------------------------- 1 | ## Deployment 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/06/slides/)** 4 | 5 | **[Скринкаст](https://youtu.be/3U6xAMuz3_4)** 6 | 7 | * [DigitalOcean](https://www.digitalocean.com) 8 | * [GitHub Student Developer Pack](https://education.github.com/pack) 9 | * [Byobu](https://en.wikipedia.org/wiki/Byobu_(software)) 10 | * [Byobu shortcuts](https://help.ubuntu.com/community/Byobu) 11 | * [Gunicorn](http://gunicorn.org) 12 | * [Vagrant](https://www.vagrantup.com) 13 | * [VirtualEnv](https://github.com/pypa/virtualenv) 14 | 15 | -------------------------------------------------------------------------------- /lections/06/slides/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Веб-программирование на Физтехе 2016-2017 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Веб-программирование на Физтехе 2016-2017

13 |

Занятие 6. Deployment

14 |
15 |
16 |

Занятие 6. Deployment

17 |

Web Programming @ MIPT, 2016-2017

18 | 19 | 23 | 41 |
42 |
43 |

Where

44 | 56 |
57 | 58 |
59 |

Demo - DigitalOcean

60 | 65 |
66 | 67 |
68 |

Byobu

69 | 74 |
75 | 76 |
77 |

Gunicorn

78 | WSGI HTTP Server for UNIX 79 | 84 |
85 | 86 |
87 |

FileSharing

88 |
    89 |
  • scp 90 |
      91 |
    • scp /file/to/send username@host:/where/to/put
    • 92 |
    • scp username@host:/file/to/send /where/to/put
    • 93 |
    94 |
  • 95 |
  • rsync 96 |
      97 |
    • rsync -azP ~/dir1 username@host:destination
    • 98 |
    99 |
  • 100 |
  • sshfs 101 | 104 |
  • 105 |
106 |
107 | 108 |
109 |

Configuration managment

110 | 115 |
116 | 117 |
118 |

Proccess managment

119 | 122 |
123 | 124 |
125 |

Demo - Vagrant

126 | 130 |
131 | 132 |
133 |

VirtualEnv

134 |
    135 |
  • Создает виртуальные окружения с пакетами
  • 136 |
137 |
    138 |
  1. sudo pip install virtualenv
  2. 139 |
  3. cd my_project_folder
  4. 140 |
  5. virtualenv venv
  6. 141 |
  7. virtualenv -p /usr/bin/python2.7 venv
  8. 142 |
  9. source venv/bin/activate
  10. 143 |
  11. deactivate
  12. 144 |
145 |
146 | 147 |
148 |

Homework

149 |
    150 |
  • Развернуть ваш проект на DigitalOcean
  • 151 |
152 | 153 |
154 | 155 |
156 |

Вопросы?

157 |
158 | 162 |
163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /lections/06/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/06/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/07/README.md: -------------------------------------------------------------------------------- 1 | ## Базы данных. SQL 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/07/slides/)** 4 | 5 | **[Код](code)** 6 | 7 | **[Скринкаст](TBD)** 8 | 9 | * [Учебник по SQL](http://www.mysql.ru/docs/gruber/) 10 | * [Интерактивный учебник по SQL](http://www.sql-tutorial.ru) 11 | 12 | -------------------------------------------------------------------------------- /lections/07/code/create.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE user_types ( 2 | id INTEGER PRIMARY KEY AUTOINCREMENT, 3 | name VARCHAR(255) 4 | ); 5 | 6 | CREATE TABLE users ( 7 | id INTEGER PRIMARY KEY AUTOINCREMENT, 8 | first_name VARCHAR(255), 9 | last_name VARCHAR(255), 10 | active BOOLEAN, 11 | profile INTEGER, 12 | FOREIGN KEY(profile) REFERENCES user_types(id) 13 | ); 14 | 15 | -------------------------------------------------------------------------------- /lections/07/code/fill.sql: -------------------------------------------------------------------------------- 1 | INSERT INTO user_types (name) VALUES ("Student"); 2 | INSERT INTO user_types (name) VALUES ("Teacher"); 3 | 4 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Dmitrii", "Beliakov", 1, (SELECT id FROM user_types WHERE name = "Teacher")); 5 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Kamil", "Talipov", 1, (SELECT id FROM user_types WHERE name = "Teacher")); 6 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Ivan", "Ivanov", 0, (SELECT id FROM user_types WHERE name = "Student")); 7 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Petr", "Petrov", 0, (SELECT id FROM user_types WHERE name = "Student")); 8 | INSERT INTO users (first_name, last_name, active, profile) VALUES ("Petr", "Sidorov", 0, (SELECT id FROM user_types WHERE name = "Student")); 9 | -------------------------------------------------------------------------------- /lections/07/code/select.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import sqlite3 4 | 5 | 6 | connection = sqlite3.connect("test.db") 7 | 8 | 9 | def selectAllStudents(): 10 | query = "SELECT users.first_name, users.last_name FROM users WHERE profile = (SELECT id FROM user_types WHERE name = \"Student\");" 11 | print query 12 | cursor = connection.cursor() 13 | cursor.execute(query) 14 | 15 | rows = cursor.fetchall() 16 | 17 | for row in rows: 18 | print row 19 | 20 | if __name__ == "__main__": 21 | selectAllStudents() 22 | -------------------------------------------------------------------------------- /lections/07/code/select.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM users, user_types; 2 | 3 | SELECT user_types.name, users.first_name, users.last_name FROM users, user_types WHERE users.profile = user_types.id; 4 | 5 | SELECT COUNT(*) FROM users WHERE profile = (SELECT id FROM user_types WHERE name = "Student"); 6 | 7 | SELECT COUNT(*), active FROM users GROUP BY active; 8 | 9 | SELECT COUNT(*), active FROM users GROUP BY active HAVING COUNT(*) > 2; 10 | 11 | SELECT COUNT(*), user_types.name FROM users, user_types WHERE users.profile = user_types.id GROUP BY user_types.name; 12 | -------------------------------------------------------------------------------- /lections/07/code/update.sql: -------------------------------------------------------------------------------- 1 | UPDATE users SET profile = (SELECT id FROM user_types WHERE name = "Student") WHERE first_name = "Dmitrii" AND last_name = "Beliakov"; 2 | -------------------------------------------------------------------------------- /lections/07/slides/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Веб-программирование на Физтехе 2016-2017 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Веб-программирование на Физтехе 2016-2017

13 |

Занятие 7. Базы данных. SQL

14 |
15 |
16 |

Занятие 7. Базы данных. SQL

17 |

Web Programming @ MIPT, 2016-2017

18 | 19 | 23 | 41 |
42 |
43 |

Реляционные базы данных

44 |
    45 |
  • Связанная информация, хранящаяся в двумерных таблицах
  • 46 |
  • Каждая таблица представляет собой набор полей (колонки) и набор объектов (записей)
  • 47 |
  • Порядок записей в таблице произволен, столбцов - фиксирован
  • 48 |
  • Идентификация записей осуществляется с помощью первичных ключей
  • 49 |
50 |
51 | 52 |
53 |

Реляционные базы данных

54 |
55 |

 56 | -----------------------------------------------------------
 57 |     SNUM     SNAME     CITY            COMM
 58 | -----------------------------------------------------------
 59 |     1001       Peel      London          .12
 60 |     1002       Serres    San Jose        .13
 61 |     1004       Motika    London          .11
 62 |     1007       Rifkin    Barcelona       .15
 63 |     1003       Axelrod   New York        .10
 64 | -----------------------------------------------------------
 65 | 		
66 |

 67 | ----------------------------------------------
 68 |  CNUM  |  CNAME     | CITY    | RATING | SNUM
 69 | -------|------------|---------|--------|------
 70 |  2001  |  Hoffman   | London  |   100  | 1001
 71 |  2002  |  Giovanni  | Rome    |   200  | 1003
 72 |  2003  |  Liu       | SanJose |   200  | 1002
 73 |  2004  |  Grass     | Berlin  |   300  | 1002
 74 |  2006  |  Clemens   | London  |   100  | 1001
 75 | ----------------------------------------------
 76 | 		
77 |
78 |

 79 | -----------------------------------------------
 80 |  ONUM  |    AMT    |    ODATE    | CNUM | SNUM
 81 | -------|-----------|-------------|------|------
 82 |  3001  |    18.69  |  10/03/1990 | 2008 | 1007
 83 |  3003  |   767.19  |  10/03/1990 | 2001 | 1001
 84 |  3002  |  1900.10  |  10/03/1990 | 2007 | 1004
 85 | -----------------------------------------------
 86 | 		
87 |
88 | 89 |
90 |

SQL

91 |
    92 |
  • "Язык структурированных запросов"
  • 93 |
  • Ориентирован специально на реляционные базы данных
  • 94 |
  • Стандартизирован, но БД пытаются соответствовать стандарту ANSI не позволяя ему ограничивать их слишком сильно
  • 95 |
96 |
97 | 98 |
99 |

Типы данных в SQL

100 |
    101 |
  • Числа: INTEGER и DECIMAL
  • 102 |
  • Строки: CHAR (фиксированное количество символов) и VARCHAR (любое количество символов, меньшее фиксированного заранее размера)
  • 103 |
  • В большинстве своем БД добавляют свои типы, не стандартизированные, напр. DATE, TIME, MONEY, TEXT
  • 104 |
105 |
106 | 107 |
108 |

Выборка данных из БД

109 |
    110 |
  • Для выборки из БД используется команда SELECT
  • 111 |
  • Пример: SELECT email FROM users;
  • 112 |
  • Чтобы выбрать все поля, можно указать *
  • 113 |
  • Фильтрация: WHERE activated = false
  • 114 |
  • Избыточность: SELECT DISTINCT
  • 115 |
116 |
117 | 118 |
119 |

Ограничение WHERE

120 |
    121 |
  • Реляционные операторы: =, >, <, >=, <=, <>
  • 122 |
  • Булевы операторы: AND, OR, NOT
  • 123 |
  • Специальные операторы: IN, BETWEEN <> AND <>, LIKE (спец: _ и %)
  • 124 |
  • NULL оператор: IS NULL, NOT NULL
  • 125 |
126 |
127 | 128 |
129 |

Аггрегатные функции

130 |
    131 |
  • COUNT, SUM, AVG, MAX, MIN
  • 132 |
  • COUNT (DISTINCT <>)
  • 133 |
  • ALL и * для COUND искл/вкл NULL поля
  • 134 |
  • Можно использовать на скалярных выражениях на столбцах
  • 135 |
  • Способ аггрегации: GROUP BY
  • 136 |
  • Фильтрация групп: HAVING
  • 137 |
138 |
139 | 140 |
141 |

Объединение таблиц

142 |
    143 |
  • Можно делать SELECT из нескольких таблиц, при этом в перечислении полей указывается имя таблицы
  • 144 |
  • Критерий объединения: WHERE
  • 145 |
  • Можно объединять таблицы с собой, используя псевдонимы (нужно помнить о дубликатах)
  • 146 |
147 |
148 | 149 |
150 |

Подзапросы

151 | 152 | SELECT * 153 | FROM Orders 154 | WHERE snum = 155 | ( SELECT snum 156 | FROM Salespeople 157 | WHERE sname = 'Motika' LIMIT 1); 158 | 159 |
160 | 161 | SELECT * 162 | FROM Customers outer 163 | WHERE 10/03/1990 IN 164 | ( SELECT odate 165 | FROM Orders inner 166 | WHERE outer.cnum = inner.cnum ); 167 | 168 |
169 | 170 | SELECT cnum, cname, city 171 | FROM Customers 172 | WHERE EXISTS 173 | ( SELECT * 174 | FROM Customers 175 | WHERE city = " San Jose' ); 176 | 177 |
178 | 179 |
180 |

Команды модификации

181 |
    182 |
  • INSERT INTO Salespeople VALUES (1001, 'Peel', 'London', .12);
  • 183 |
  • DELETE FROM Salespeople WHERE snum = 1003;
  • 184 |
  • UPDATE Salespeople SET sname = 'Gibson',city = 'Boston',comm = .10 WHERE snum = 1004;
  • 185 |
186 |
187 | 188 |
189 |

Создание и удаление таблиц

190 |
    191 |
  • CREATE TABLE Saleepeople ( snum integer, sname char (10), city char (10), comm declmal );
  • 192 |
  • DROP TABLE Saleepeople;
  • 193 |
194 |
195 | 196 |
197 |

DEMO: sqlite3

198 |
    199 |
  • Простейший способ использовать БД
  • 200 |
  • Вся БД хранится в одном файле
  • 201 |
  • Отличный способ иметь БД в мобильных приложениях
  • 202 |
  • Доступ из коммандной строки: sqlite3 filename
  • 203 |
  • Дополнительные команды sqlite3
  • 204 |
205 |
206 | 207 |
208 |

Вопросы?

209 |
210 | 214 |
215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /lections/07/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/07/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/08/README.md: -------------------------------------------------------------------------------- 1 | ## Базы данных. SQL 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/08/slides/)** 4 | 5 | **[Код](code)** 6 | 7 | **[Скринкаст](TBD)** 8 | 9 | * [Официальный туториал](https://docs.djangoproject.com/en/1.10/intro/tutorial01/) 10 | * [DjangoBook.com](http://djangobook.com) 11 | * [DjBook.ru](http://djbook.ru/rel1.9/) 12 | * Книга Antonio Mele - Django by example 13 | * [Awesome Django](https://github.com/rosarior/awesome-django) -------------------------------------------------------------------------------- /lections/08/code/testingplatform/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/.DS_Store -------------------------------------------------------------------------------- /lections/08/code/testingplatform/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/db.sqlite3 -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/.DS_Store -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/__init__.py -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/__init__.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | import lessons.models 3 | 4 | admin.site.register(lessons.models.Lesson) 5 | admin.site.register(lessons.models.Problem) 6 | admin.site.register(lessons.models.Submission) 7 | admin.site.register(lessons.models.Test) 8 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/admin.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/admin.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ] 11 | 12 | operations = [ 13 | migrations.CreateModel( 14 | name='Lesson', 15 | fields=[ 16 | ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)), 17 | ('title', models.TextField()), 18 | ('content', models.TextField()), 19 | ], 20 | options={ 21 | }, 22 | bases=(models.Model,), 23 | ), 24 | migrations.CreateModel( 25 | name='Problem', 26 | fields=[ 27 | ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)), 28 | ('title', models.TextField()), 29 | ('statement', models.TextField()), 30 | ('lesson', models.ForeignKey(to='lessons.Lesson')), 31 | ], 32 | options={ 33 | }, 34 | bases=(models.Model,), 35 | ), 36 | migrations.CreateModel( 37 | name='Submission', 38 | fields=[ 39 | ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)), 40 | ('code', models.TextField()), 41 | ('status', models.TextField(choices=[('OK', 'OK'), ('ER', 'Error')])), 42 | ('problem', models.ForeignKey(to='lessons.Problem')), 43 | ], 44 | options={ 45 | }, 46 | bases=(models.Model,), 47 | ), 48 | migrations.CreateModel( 49 | name='Test', 50 | fields=[ 51 | ('id', models.AutoField(verbose_name='ID', serialize=False, primary_key=True, auto_created=True)), 52 | ('number', models.IntegerField(unique=True)), 53 | ('input', models.TextField()), 54 | ('answer', models.TextField()), 55 | ('problem', models.ForeignKey(to='lessons.Problem')), 56 | ], 57 | options={ 58 | }, 59 | bases=(models.Model,), 60 | ), 61 | ] 62 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/migrations/0001_initial.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/migrations/0001_initial.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/migrations/0002_auto_20170226_2056.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('lessons', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='submission', 16 | name='info', 17 | field=models.TextField(blank=True), 18 | preserve_default=True, 19 | ), 20 | migrations.AlterField( 21 | model_name='submission', 22 | name='status', 23 | field=models.TextField(choices=[('OK', 'Correct'), ('RE', 'Run-time error'), ('WA', 'Wrong answer')]), 24 | preserve_default=True, 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/migrations/0002_auto_20170226_2056.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/migrations/0002_auto_20170226_2056.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/migrations/__init__.py -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/migrations/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/migrations/__init__.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | 3 | 4 | class Lesson(models.Model): 5 | title = models.TextField() 6 | content = models.TextField() 7 | 8 | def __str__(self): 9 | return self.title 10 | 11 | 12 | class Problem(models.Model): 13 | title = models.TextField() 14 | statement = models.TextField() 15 | lesson = models.ForeignKey(Lesson) 16 | 17 | def __str__(self): 18 | return self.title 19 | 20 | 21 | class Test(models.Model): 22 | number = models.IntegerField(unique=True) 23 | input = models.TextField() 24 | answer = models.TextField() 25 | problem = models.ForeignKey(Problem) 26 | 27 | def __str__(self): 28 | return '{0}: {1}'.format(self.number, self.input) 29 | 30 | 31 | class Submission(models.Model): 32 | OK = 'OK' 33 | RE = 'RE' 34 | WA = 'WA' 35 | STATUSES = ( 36 | (OK, 'Correct'), 37 | (RE, 'Run-time error'), 38 | (WA, 'Wrong answer'), 39 | ) 40 | 41 | code = models.TextField() 42 | status = models.TextField(choices=STATUSES) 43 | problem = models.ForeignKey(Problem) 44 | info = models.TextField(blank=True) 45 | 46 | def __str__(self): 47 | return '{0} (status): {1}'.format(self.problem, self.status, self.code) 48 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/models.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/models.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/submission_testing.py: -------------------------------------------------------------------------------- 1 | from lessons.models import Submission 2 | 3 | 4 | def is_correst_answer_on_test(function, test): 5 | output = function(*eval(test.input)) 6 | return str(output) == test.answer 7 | 8 | 9 | def test_submission(problem, source): 10 | info = '' 11 | 12 | try: 13 | sandbox = {} 14 | exec(source, globals(), sandbox) 15 | function = sandbox['action'] 16 | if all(is_correst_answer_on_test(function=function, test=test) 17 | for test in problem.test_set.all()): 18 | status = Submission.OK 19 | else: 20 | status = Submission.WA 21 | except Exception as e: 22 | status = Submission.RE 23 | info = str(e) 24 | 25 | Submission(code=source, status=status, problem=problem, info=info).save() 26 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/submission_testing.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/submission_testing.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/templates/index.html: -------------------------------------------------------------------------------- 1 |

Учебник Питона

2 | 3 | Уроки: 4 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/templates/lesson.html: -------------------------------------------------------------------------------- 1 | Уроки 2 | 3 |

Урок {{ lesson.id }}: {{ lesson.title }}

4 | 5 | {{ lesson.content|safe }} 6 | 7 | Задачи: 8 |
    9 | {% for problem in lesson.problem_set.all %} 10 |
  • {{ problem.title }}
  • 11 | {% endfor %} 12 |
-------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/templates/problem.html: -------------------------------------------------------------------------------- 1 | Урок {{ problem.lesson.id }}: {{ problem.lesson.title }} 2 | 3 |

Задача "{{ problem.title }}"

4 | 5 | {{ problem.statement|safe }} 6 | 7 |
8 | {% csrf_token %} 9 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | {% for submission in problem.submission_set.all %} 24 | 25 | 26 | 27 | 28 | 29 | 30 | {% endfor %} 31 |
#КодСтатусКомментарий
{{ submission.id }}
{{ submission.code }}
{{ submission.get_status_display }}{{ submission.info }}
-------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | 3 | from lessons import views 4 | 5 | urlpatterns = [ 6 | url(r'^$', views.index, name='index'), 7 | url(r'^lessons/(?P\d+)/$', views.lesson, name='lesson'), 8 | url(r'^problems/(?P\d+)/$', views.problem, name='problem'), 9 | url(r'^send_submission/(?P\d+)/$', views.send_submission, name='send_submission'), 10 | ] 11 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/urls.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/urls.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import redirect, render 2 | 3 | from lessons.models import Lesson, Problem 4 | from lessons.submission_testing import test_submission 5 | 6 | 7 | def index(request): 8 | lessons = Lesson.objects.all() 9 | return render(request, 'index.html', {'lessons': lessons}) 10 | 11 | 12 | def lesson(request, lesson_id): 13 | lesson = Lesson.objects.get(id=lesson_id) 14 | return render(request, 'lesson.html', {'lesson': lesson}) 15 | 16 | 17 | def problem(request, problem_id): 18 | problem = Problem.objects.get(id=problem_id) 19 | tests = problem.test_set.order_by('number') 20 | return render(request, 'problem.html', {'problem': problem, 'tests': tests}) 21 | 22 | 23 | def send_submission(request, problem_id): 24 | problem = Problem.objects.get(id=problem_id) 25 | source = request.POST['source'] 26 | test_submission(problem, source) 27 | return redirect('problem', problem_id=problem.id) 28 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/lessons/views.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/lessons/views.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testingplatform.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/testingplatform/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/__init__.py -------------------------------------------------------------------------------- /lections/08/code/testingplatform/testingplatform/__init__.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/__init__.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/testingplatform/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for testingplatform project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.5. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = 'u4fu9&6vfo8#clac*=7q*ut)ie5#^*_g$isnw3h7v3x))@!rl4' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'lessons', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'testingplatform.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'testingplatform.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/1.10/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_L10N = True 114 | 115 | USE_TZ = True 116 | 117 | 118 | # Static files (CSS, JavaScript, Images) 119 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 120 | 121 | STATIC_URL = '/static/' 122 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/testingplatform/settings.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/settings.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/testingplatform/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import include, url 2 | from django.contrib import admin 3 | 4 | urlpatterns = [ 5 | url(r'^', include('lessons.urls')), 6 | url(r'^admin/', include(admin.site.urls)), 7 | ] 8 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/testingplatform/urls.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/urls.pyc -------------------------------------------------------------------------------- /lections/08/code/testingplatform/testingplatform/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for testingplatform project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "testingplatform.settings") 12 | 13 | from django.core.wsgi import get_wsgi_application 14 | application = get_wsgi_application() 15 | -------------------------------------------------------------------------------- /lections/08/code/testingplatform/testingplatform/wsgi.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/code/testingplatform/testingplatform/wsgi.pyc -------------------------------------------------------------------------------- /lections/08/slides/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/slides/.DS_Store -------------------------------------------------------------------------------- /lections/08/slides/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Веб-программирование на Физтехе 2016-2017 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 |

Веб-программирование на Физтехе 2016-2017

13 |

Занятие 8. Введение в Django и Django ORM

14 |
15 |
16 |

Занятие 8. Введение в Django и Django ORM

17 |

Web Programming @ MIPT, 2016-2017

18 | 19 | 23 | 41 |
42 | 43 | 44 |
45 |

Django

46 | 53 |
54 | 55 |
56 |

Django architecture

57 | 58 |
59 | 60 |
61 |

DEMO: start django project

62 |
    63 |
  • django-admin.py startproject my_project
  • 64 |
  • python manage.py migrate
  • 65 |
  • python manage.py runserver
  • 66 |
  • python manage.py startapp main_site
  • 67 |
  • Changes in main_site/models.py 68 |
  • python manage.py makemigrations
  • 69 |
  • python manage.py check
  • 70 |
  • python manage.py createsuperuser
  • 71 |
72 |
73 | 74 |
75 |

DEMO: ORM

76 |
    77 | 78 |
79 |
80 | 81 |
82 |

Django materials

83 | 90 |
91 | 92 |
93 |

Вопросы?

94 |
95 | 99 |
100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /lections/08/slides/pictures/architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/slides/pictures/architecture.jpg -------------------------------------------------------------------------------- /lections/08/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/08/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/09/README.md: -------------------------------------------------------------------------------- 1 | ## SimpleForum на Django 2 | 3 | **[Код](code)** 4 | 5 | * [Официальный туториал](https://docs.djangoproject.com/en/1.10/intro/tutorial01/) 6 | * [DjangoBook.com](http://djangobook.com) 7 | * [DjBook.ru](http://djbook.ru/rel1.9/) 8 | * Книга Antonio Mele - Django by example 9 | * [Awesome Django](https://github.com/rosarior/awesome-django) 10 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/db.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/db.sqlite3 -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/forum/__init__.py -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | import forum.models 3 | 4 | # Register your models here. 5 | 6 | admin.site.register(forum.models.Category) 7 | admin.site.register(forum.models.Thread) 8 | admin.site.register(forum.models.Message) 9 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class ForumConfig(AppConfig): 7 | name = 'forum' 8 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.6 on 2017-03-04 16:41 3 | from __future__ import unicode_literals 4 | 5 | from django.conf import settings 6 | from django.db import migrations, models 7 | import django.db.models.deletion 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | initial = True 13 | 14 | dependencies = [ 15 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 16 | ] 17 | 18 | operations = [ 19 | migrations.CreateModel( 20 | name='Category', 21 | fields=[ 22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 23 | ('title', models.TextField()), 24 | ('extended_info', models.TextField()), 25 | ('logo', models.ImageField(null=True, upload_to='category_logo/')), 26 | ], 27 | ), 28 | migrations.CreateModel( 29 | name='Message', 30 | fields=[ 31 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 32 | ('text', models.TextField()), 33 | ('time', models.DateTimeField(auto_now_add=True)), 34 | ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 35 | ], 36 | ), 37 | migrations.CreateModel( 38 | name='UserProfile', 39 | fields=[ 40 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 41 | ('avatar', models.ImageField(null=True, upload_to='avatar/')), 42 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 43 | ], 44 | ), 45 | migrations.CreateModel( 46 | name='Thread', 47 | fields=[ 48 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 49 | ('title', models.TextField()), 50 | ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Category')), 51 | ], 52 | ), 53 | ] 54 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/migrations/0002_message_thread.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.6 on 2017-03-05 07:39 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('forum', '0001_initial'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='message', 18 | name='thread', 19 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='forum.Thread'), 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/migrations/0003_message_title.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.6 on 2017-03-07 18:03 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('forum', '0002_message_thread'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='message', 17 | name='title', 18 | field=models.TextField(null=True), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/forum/migrations/__init__.py -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.contrib.auth.models import User 5 | 6 | 7 | class UserProfile(models.Model): 8 | user = models.OneToOneField(User) 9 | avatar = models.ImageField(upload_to='avatar/', null=True) 10 | 11 | 12 | class Category(models.Model): 13 | title = models.TextField() 14 | extended_info = models.TextField() 15 | logo = models.ImageField(upload_to='category_logo/', null=True) 16 | 17 | def __unicode__(self): 18 | return self.title 19 | 20 | 21 | class Thread(models.Model): 22 | title = models.TextField() 23 | category = models.ForeignKey(Category) 24 | 25 | def __unicode__(self): 26 | return self.title 27 | 28 | 29 | class Message(models.Model): 30 | thread = models.ForeignKey(Thread, null=True) 31 | title = models.TextField(null=True) 32 | text = models.TextField() 33 | time = models.DateTimeField(auto_now_add=True) 34 | author = models.ForeignKey(User) 35 | 36 | def as_dict(self): 37 | return { 38 | 'text': self.text, 39 | 'author': str(self.author), 40 | } 41 | 42 | def __unicode__(self): 43 | return self.text 44 | 45 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/static/forum/css/navbar.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 20px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | .navbar { 7 | margin-bottom: 20px; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/static/forum/css/thread.css: -------------------------------------------------------------------------------- 1 | .message { 2 | margin-top: 10px; 3 | margin-left: 30px; 4 | } 5 | 6 | .author { 7 | color: red; 8 | } -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/static/forum/js/load_messages.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | function loadMessages() { 3 | $.get('/load_messages', { 4 | 'thread_id': $('#thread_id').val(), 5 | 'page_num': $('#page_num').val() 6 | }).done(function(data) { 7 | data.messages.forEach(function (message) { 8 | var row = $('
  • '); 9 | row.append($('
    ').text(message.author)); 10 | row.append($('
    ').text(message.text)); 11 | 12 | $('#messages_list').append(row); 13 | }); 14 | }); 15 | } 16 | 17 | loadMessages(); 18 | 19 | setInterval(loadMessages, 5000); 20 | }); 21 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/templates/base.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% block head %} 14 | {% endblock %} 15 | 16 | 17 | 18 | 19 |
    20 | 21 | 22 | 47 | 48 | {% block precontent %} 49 | {% endblock %} 50 | 51 | {% block content %} 52 | {% endblock %} 53 | 54 |
    55 | 56 | 57 | 58 | 59 | {% block scripts %} 60 | {% endblock %} 61 | 62 | 63 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | Категории 5 | {% endblock %} 6 | 7 | {% block precontent %} 8 |

    Категория {{category.title}}

    9 | {% endblock %} 10 | 11 | 12 | {% block content %} 13 | Обсуждения: 14 |
      15 | {% for thread in category.thread_set.all %} 16 |
    • {{ thread.title }}
    • 17 | {% endfor %} 18 |
    19 | {% endblock %} -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | Simple django forum 5 | {% endblock %} 6 | 7 | {% block precontent %} 8 |

    Категории:

    9 |
    10 | {% endblock %} 11 | 12 | {% block content %} 13 | 14 | 15 | {% for category in categories %} 16 | 17 | 18 | 19 | 20 | {% endfor %} 21 | 22 |
    {{ category.title }}
    23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 | {% if form.errors %} 6 |

    Your username and password didn't match. Please try again.

    7 | {% endif %} 8 | 9 |
    10 | {% csrf_token %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
    {{ form.username.label_tag }}{{ form.username }}
    {{ form.password.label_tag }}{{ form.password }}
    21 | 22 | 23 | 24 |
    25 | 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/templates/logout.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/forum/templates/logout.html -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/templates/register.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | Create an account 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

    Регистрация пользователя

    9 | 10 |
    11 | {% csrf_token %} 12 | {{ form.as_p }} 13 | 14 |
    15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/templates/thread.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load staticfiles %} 4 | 5 | {% block head %} 6 | 7 | 8 | Обсуждение 9 | {% endblock %} 10 | 11 | {% block precontent %} 12 | 13 | 14 | 15 | 16 |

    Категория {{thread.category.title}}

    17 |

    Обсуждениe {{thread.title}}

    18 | {% endblock %} 19 | 20 | {% block content %} 21 | 22 |
      23 |
    24 | 25 | {% if user.is_authenticated %} 26 |
    27 | {% csrf_token %} 28 | 31 |
    32 | 33 |
    34 | {% endif %} 35 | {% endblock %} 36 | 37 | 38 | {% block scripts %} 39 | 40 | {% endblock %} 41 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from django.conf.urls.static import static 3 | from django.conf import settings 4 | 5 | from forum import views 6 | 7 | urlpatterns = [ 8 | url(r'^$', views.index, name='index'), 9 | url(r'^category/(?P\d+)/$', views.category, name='category'), 10 | url(r'^thread/(?P\d+)/(?P\d+)/$', views.thread, name='thread'), 11 | url(r'^profile/(?P\d+)/$', views.profile, name='profile'), 12 | url(r'^send_message/(?P\d+)/$', views.send_message, name='send_message'), 13 | url(r'^register/$', views.register, name='register'), 14 | url(r'^load_messages/$', views.load_messages, name='load_messages'), 15 | ] 16 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/forum/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import redirect, render 2 | from django.contrib.auth.forms import UserCreationForm 3 | from django.http import HttpResponseRedirect, HttpResponse 4 | from django.contrib.auth.decorators import login_required 5 | 6 | import forum.models 7 | 8 | import math 9 | import json 10 | 11 | _MESSAGES_PER_PAGE = 20 12 | 13 | 14 | def index(request): 15 | categories = forum.models.Category.objects.all() 16 | return render(request, 'index.html', {'categories': categories}) 17 | 18 | 19 | def category(request, category_id): 20 | category = forum.models.Category.objects.get(id=category_id) 21 | return render(request, 'category.html', {'category': category}) 22 | 23 | 24 | def thread(request, thread_id, page_num): 25 | thread = forum.models.Thread.objects.get(id=thread_id) 26 | total_page_count = int(math.ceil(float(len(thread.message_set.all())) / _MESSAGES_PER_PAGE)) 27 | min_message_id = int(page_num) * _MESSAGES_PER_PAGE 28 | max_message_id = min_message_id + _MESSAGES_PER_PAGE + 1 29 | messages = thread.message_set.filter(id__gt=min_message_id).filter(id__lt=max_message_id) 30 | return render(request, 'thread.html', {'thread': thread, 'page_num': page_num, 31 | 'total_page_count': total_page_count}) 32 | 33 | 34 | def profile(request, profile_id): 35 | return render(request, 'profile.html') 36 | 37 | 38 | @login_required 39 | def send_message(request, thread_id): 40 | thread = forum.models.Thread.objects.get(id=thread_id) 41 | message = request.POST['message'] 42 | forum.models.Message(thread=thread, text=message, author=request.user).save() 43 | last_page_num = int(math.ceil(float(len(thread.message_set.all())) / _MESSAGES_PER_PAGE)) - 1 44 | return redirect('thread', thread.id, last_page_num) 45 | 46 | 47 | def register(request): 48 | if request.method == 'POST': 49 | form = UserCreationForm(request.POST) 50 | if form.is_valid(): 51 | new_user = form.save() 52 | return HttpResponseRedirect("/") 53 | else: 54 | form = UserCreationForm() 55 | return render(request, "register.html", { 56 | 'form': form, 57 | }) 58 | 59 | 60 | def load_messages(request): 61 | ''' 62 | Ajax request. 63 | Params: 64 | thread_id, page_num 65 | Return: { 66 | 'messages': ... 67 | } 68 | ''' 69 | 70 | thread = forum.models.Thread.objects.get(id=int(request.GET['thread_id'])) 71 | total_page_count = math.ceil(float(len(thread.message_set.all())) / _MESSAGES_PER_PAGE) 72 | min_message_id = int(request.GET['page_num']) * _MESSAGES_PER_PAGE 73 | max_message_id = min_message_id + _MESSAGES_PER_PAGE + 1 74 | messages = thread.message_set.filter(id__gt=min_message_id).filter(id__lt=max_message_id) 75 | 76 | messages_json = [message.as_dict() for message in messages] 77 | 78 | response_data = { 79 | 'messages': messages_json 80 | } 81 | 82 | return HttpResponse(json.dumps(response_data), content_type='application/json') 83 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "simple_forum.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/media/category_logo/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/media/category_logo/info.png -------------------------------------------------------------------------------- /lections/09/code/simple_forum/media/category_logo/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/media/category_logo/question.png -------------------------------------------------------------------------------- /lections/09/code/simple_forum/simple_forum/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/09/code/simple_forum/simple_forum/__init__.py -------------------------------------------------------------------------------- /lections/09/code/simple_forum/simple_forum/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for simple_forum project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.6. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '0)ky_#*day$(pxpq$p7c8=b=7e&bq8+^zd79e48bf&q2kv0g#$' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = True 27 | 28 | ALLOWED_HOSTS = [] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'forum', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'simple_forum.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'simple_forum.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.sqlite3', 80 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 81 | } 82 | } 83 | 84 | 85 | # Password validation 86 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 87 | 88 | AUTH_PASSWORD_VALIDATORS = [ 89 | { 90 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 91 | }, 92 | { 93 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 94 | }, 95 | { 96 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 97 | }, 98 | { 99 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 100 | }, 101 | ] 102 | 103 | 104 | # Internationalization 105 | # https://docs.djangoproject.com/en/1.10/topics/i18n/ 106 | 107 | LANGUAGE_CODE = 'en-us' 108 | 109 | TIME_ZONE = 'UTC' 110 | 111 | USE_I18N = True 112 | 113 | USE_L10N = True 114 | 115 | USE_TZ = True 116 | 117 | 118 | # Static files (CSS, JavaScript, Images) 119 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 120 | 121 | STATIC_URL = '/static/' 122 | 123 | MEDIA_ROOT = os.path.join(BASE_DIR, 'media') 124 | MEDIA_URL ='/media/' 125 | 126 | LOGIN_REDIRECT_URL = '/' 127 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/simple_forum/urls.py: -------------------------------------------------------------------------------- 1 | """simple_forum URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.10/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url, include 17 | from django.conf.urls.static import static 18 | from django.conf import settings 19 | from django.contrib import admin 20 | from django.contrib.auth import views as auth_views 21 | 22 | 23 | urlpatterns = [ 24 | url(r'^', include('forum.urls')), 25 | url(r'^admin/', admin.site.urls), 26 | 27 | url(r'^accounts/login/$', auth_views.login, { 28 | 'template_name': 'login.html' 29 | }, name='login'), 30 | url(r'^accounts/logout/$', auth_views.logout, { 31 | 'next_page': 'index' 32 | }, name='logout'), 33 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 34 | -------------------------------------------------------------------------------- /lections/09/code/simple_forum/simple_forum/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for simple_forum project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "simple_forum.settings") 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /lections/10/README.md: -------------------------------------------------------------------------------- 1 | ## Развертывание проектов с использованием Docker 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/10/slides/)** 4 | 5 | **[Код](code)** 6 | 7 | * [Понимая Docker](https://habrahabr.ru/post/253877/) 8 | 9 | 10 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################ 2 | # Dockerfile to run a Django-based web application 3 | # Based on an Ubuntu Image 4 | ############################################################ 5 | 6 | # Set the base image to use to Ubuntu 7 | FROM ubuntu:16.04 8 | 9 | # Set the file maintainer (your name - the file's author) 10 | MAINTAINER Dmitrii Beliakov 11 | 12 | # Directory in container for all project files 13 | ENV DOCKYARD_SRVHOME=/srv 14 | # Directory in container for project source files 15 | ENV DOCKYARD_SRVPROJ=/srv/simple_forum 16 | 17 | # Update the default application repository sources list 18 | RUN apt-get update && apt-get install -y python python-pip gunicorn 19 | 20 | # Create application subdirectories 21 | WORKDIR $DOCKYARD_SRVHOME 22 | RUN mkdir media static logs 23 | VOLUME ["$DOCKYARD_SRVHOME/media/", "$DOCKYARD_SRVHOME/logs/"] 24 | 25 | # Copy application source code to SRCDIR 26 | COPY . $DOCKYARD_SRVPROJ 27 | 28 | # Install Python dependencies 29 | RUN pip install -r $DOCKYARD_SRVPROJ/requirements.txt 30 | 31 | # Port to expose 32 | EXPOSE 8000 33 | 34 | # Copy entrypoint script into the image 35 | WORKDIR $DOCKYARD_SRVPROJ 36 | COPY ./docker-entrypoint.sh / 37 | ENTRYPOINT ["/docker-entrypoint.sh"] 38 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | web: 4 | image: dbeliakov/simple-forum:latest 5 | ports: 6 | - "8000:8000" 7 | depends_on: 8 | - db 9 | links: 10 | - db:pgdb 11 | db: 12 | image: postgres 13 | env_file: 14 | - env.txt 15 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | python manage.py migrate # Apply database migrations 3 | python manage.py collectstatic --noinput # Collect static files 4 | 5 | # Prepare log files and start outputting logs to stdout 6 | touch /srv/logs/gunicorn.log 7 | touch /srv/logs/access.log 8 | tail -n 0 -f /srv/logs/*.log & 9 | 10 | # Start Gunicorn processes 11 | echo Starting Gunicorn. 12 | exec gunicorn simple_forum.wsgi:application \ 13 | --name simple_forum \ 14 | --bind 0.0.0.0:8000 \ 15 | --workers 3 \ 16 | --log-level=info \ 17 | --log-file=/srv/logs/gunicorn.log \ 18 | --access-logfile=/srv/logs/access.log \ 19 | "$@" 20 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/env.txt: -------------------------------------------------------------------------------- 1 | POSTGRES_PASSWORD=forum 2 | POSTGRES_USER=forum 3 | POSTGRES_DB=simple_forum 4 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/10/code/simple_forum/forum/__init__.py -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | import forum.models 3 | 4 | # Register your models here. 5 | 6 | admin.site.register(forum.models.Category) 7 | admin.site.register(forum.models.Thread) 8 | admin.site.register(forum.models.Message) 9 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/apps.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.apps import AppConfig 4 | 5 | 6 | class ForumConfig(AppConfig): 7 | name = 'forum' 8 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.6 on 2017-03-04 16:41 3 | from __future__ import unicode_literals 4 | 5 | from django.conf import settings 6 | from django.db import migrations, models 7 | import django.db.models.deletion 8 | 9 | 10 | class Migration(migrations.Migration): 11 | 12 | initial = True 13 | 14 | dependencies = [ 15 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 16 | ] 17 | 18 | operations = [ 19 | migrations.CreateModel( 20 | name='Category', 21 | fields=[ 22 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 23 | ('title', models.TextField()), 24 | ('extended_info', models.TextField()), 25 | ('logo', models.ImageField(null=True, upload_to='category_logo/')), 26 | ], 27 | ), 28 | migrations.CreateModel( 29 | name='Message', 30 | fields=[ 31 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 32 | ('text', models.TextField()), 33 | ('time', models.DateTimeField(auto_now_add=True)), 34 | ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 35 | ], 36 | ), 37 | migrations.CreateModel( 38 | name='UserProfile', 39 | fields=[ 40 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 41 | ('avatar', models.ImageField(null=True, upload_to='avatar/')), 42 | ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), 43 | ], 44 | ), 45 | migrations.CreateModel( 46 | name='Thread', 47 | fields=[ 48 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 49 | ('title', models.TextField()), 50 | ('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='forum.Category')), 51 | ], 52 | ), 53 | ] 54 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/migrations/0002_message_thread.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.6 on 2017-03-05 07:39 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('forum', '0001_initial'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='message', 18 | name='thread', 19 | field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='forum.Thread'), 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/migrations/0003_message_title.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.6 on 2017-03-07 18:03 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('forum', '0002_message_thread'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='message', 17 | name='title', 18 | field=models.TextField(null=True), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/10/code/simple_forum/forum/migrations/__init__.py -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/models.py: -------------------------------------------------------------------------------- 1 | from __future__ import unicode_literals 2 | 3 | from django.db import models 4 | from django.contrib.auth.models import User 5 | 6 | 7 | class UserProfile(models.Model): 8 | user = models.OneToOneField(User) 9 | avatar = models.ImageField(upload_to='avatar/', null=True) 10 | 11 | 12 | class Category(models.Model): 13 | title = models.TextField() 14 | extended_info = models.TextField() 15 | logo = models.ImageField(upload_to='category_logo/', null=True) 16 | 17 | def __unicode__(self): 18 | return self.title 19 | 20 | 21 | class Thread(models.Model): 22 | title = models.TextField() 23 | category = models.ForeignKey(Category) 24 | 25 | def __unicode__(self): 26 | return self.title 27 | 28 | 29 | class Message(models.Model): 30 | thread = models.ForeignKey(Thread, null=True) 31 | title = models.TextField(null=True) 32 | text = models.TextField() 33 | time = models.DateTimeField(auto_now_add=True) 34 | author = models.ForeignKey(User) 35 | 36 | def as_dict(self): 37 | return { 38 | 'text': self.text, 39 | 'author': str(self.author), 40 | } 41 | 42 | def __unicode__(self): 43 | return self.text 44 | 45 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/static/forum/css/navbar.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 20px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | .navbar { 7 | margin-bottom: 20px; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/static/forum/css/thread.css: -------------------------------------------------------------------------------- 1 | .message { 2 | margin-top: 10px; 3 | margin-left: 30px; 4 | } 5 | 6 | .author { 7 | color: red; 8 | } -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/static/forum/js/load_messages.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function() { 2 | function loadMessages() { 3 | $.get('/load_messages', { 4 | 'thread_id': $('#thread_id').val(), 5 | 'page_num': $('#page_num').val() 6 | }).done(function(data) { 7 | data.messages.forEach(function (message) { 8 | var row = $('
  • '); 9 | row.append($('
    ').text(message.author)); 10 | row.append($('
    ').text(message.text)); 11 | 12 | $('#messages_list').append(row); 13 | }); 14 | }); 15 | } 16 | 17 | loadMessages(); 18 | 19 | setInterval(loadMessages, 5000); 20 | }); 21 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/templates/base.html: -------------------------------------------------------------------------------- 1 | {% load staticfiles %} 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% block head %} 14 | {% endblock %} 15 | 16 | 17 | 18 | 19 |
    20 | 21 | 22 | 47 | 48 | {% block precontent %} 49 | {% endblock %} 50 | 51 | {% block content %} 52 | {% endblock %} 53 | 54 |
    55 | 56 | 57 | 58 | 59 | {% block scripts %} 60 | {% endblock %} 61 | 62 | 63 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/templates/category.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | Категории 5 | {% endblock %} 6 | 7 | {% block precontent %} 8 |

    Категория {{category.title}}

    9 | {% endblock %} 10 | 11 | 12 | {% block content %} 13 | Обсуждения: 14 |
      15 | {% for thread in category.thread_set.all %} 16 |
    • {{ thread.title }}
    • 17 | {% endfor %} 18 |
    19 | {% endblock %} -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/templates/index.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | Simple django forum 5 | {% endblock %} 6 | 7 | {% block precontent %} 8 |

    Категории:

    9 |
    10 | {% endblock %} 11 | 12 | {% block content %} 13 | 14 | 15 | {% for category in categories %} 16 | 17 | 18 | 19 | 20 | {% endfor %} 21 | 22 |
    {{ category.title }}
    23 | {% endblock %} 24 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/templates/login.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | 5 | {% if form.errors %} 6 |

    Your username and password didn't match. Please try again.

    7 | {% endif %} 8 | 9 |
    10 | {% csrf_token %} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
    {{ form.username.label_tag }}{{ form.username }}
    {{ form.password.label_tag }}{{ form.password }}
    21 | 22 | 23 | 24 |
    25 | 26 | {% endblock %} 27 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/templates/logout.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/10/code/simple_forum/forum/templates/logout.html -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/templates/register.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block head %} 4 | Create an account 5 | {% endblock %} 6 | 7 | {% block content %} 8 |

    Регистрация пользователя

    9 | 10 |
    11 | {% csrf_token %} 12 | {{ form.as_p }} 13 | 14 |
    15 | {% endblock %} 16 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/templates/thread.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% load staticfiles %} 4 | 5 | {% block head %} 6 | 7 | 8 | Обсуждение 9 | {% endblock %} 10 | 11 | {% block precontent %} 12 | 13 | 14 | 15 | 16 |

    Категория {{thread.category.title}}

    17 |

    Обсуждениe {{thread.title}}

    18 | {% endblock %} 19 | 20 | {% block content %} 21 | 22 |
      23 |
    24 | 25 | {% if user.is_authenticated %} 26 |
    27 | {% csrf_token %} 28 | 31 |
    32 | 33 |
    34 | {% endif %} 35 | {% endblock %} 36 | 37 | 38 | {% block scripts %} 39 | 40 | {% endblock %} 41 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | 3 | # Create your tests here. 4 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import url 2 | from django.conf.urls.static import static 3 | from django.conf import settings 4 | 5 | from forum import views 6 | 7 | urlpatterns = [ 8 | url(r'^$', views.index, name='index'), 9 | url(r'^category/(?P\d+)/$', views.category, name='category'), 10 | url(r'^thread/(?P\d+)/(?P\d+)/$', views.thread, name='thread'), 11 | url(r'^profile/(?P\d+)/$', views.profile, name='profile'), 12 | url(r'^send_message/(?P\d+)/$', views.send_message, name='send_message'), 13 | url(r'^register/$', views.register, name='register'), 14 | url(r'^load_messages/$', views.load_messages, name='load_messages'), 15 | ] 16 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/forum/views.py: -------------------------------------------------------------------------------- 1 | from django.shortcuts import redirect, render 2 | from django.contrib.auth.forms import UserCreationForm 3 | from django.http import HttpResponseRedirect, HttpResponse 4 | from django.contrib.auth.decorators import login_required 5 | 6 | import forum.models 7 | 8 | import math 9 | import json 10 | 11 | _MESSAGES_PER_PAGE = 20 12 | 13 | 14 | def index(request): 15 | categories = forum.models.Category.objects.all() 16 | return render(request, 'index.html', {'categories': categories}) 17 | 18 | 19 | def category(request, category_id): 20 | category = forum.models.Category.objects.get(id=category_id) 21 | return render(request, 'category.html', {'category': category}) 22 | 23 | 24 | def thread(request, thread_id, page_num): 25 | thread = forum.models.Thread.objects.get(id=thread_id) 26 | total_page_count = int(math.ceil(float(len(thread.message_set.all())) / _MESSAGES_PER_PAGE)) 27 | min_message_id = int(page_num) * _MESSAGES_PER_PAGE 28 | max_message_id = min_message_id + _MESSAGES_PER_PAGE + 1 29 | messages = thread.message_set.filter(id__gt=min_message_id).filter(id__lt=max_message_id) 30 | return render(request, 'thread.html', {'thread': thread, 'page_num': page_num, 31 | 'total_page_count': total_page_count}) 32 | 33 | 34 | def profile(request, profile_id): 35 | return render(request, 'profile.html') 36 | 37 | 38 | @login_required 39 | def send_message(request, thread_id): 40 | thread = forum.models.Thread.objects.get(id=thread_id) 41 | message = request.POST['message'] 42 | forum.models.Message(thread=thread, text=message, author=request.user).save() 43 | last_page_num = int(math.ceil(float(len(thread.message_set.all())) / _MESSAGES_PER_PAGE)) - 1 44 | return redirect('thread', thread.id, last_page_num) 45 | 46 | 47 | def register(request): 48 | if request.method == 'POST': 49 | form = UserCreationForm(request.POST) 50 | if form.is_valid(): 51 | new_user = form.save() 52 | return HttpResponseRedirect("/") 53 | else: 54 | form = UserCreationForm() 55 | return render(request, "register.html", { 56 | 'form': form, 57 | }) 58 | 59 | 60 | def load_messages(request): 61 | ''' 62 | Ajax request. 63 | Params: 64 | thread_id, page_num 65 | Return: { 66 | 'messages': ... 67 | } 68 | ''' 69 | 70 | thread = forum.models.Thread.objects.get(id=int(request.GET['thread_id'])) 71 | total_page_count = math.ceil(float(len(thread.message_set.all())) / _MESSAGES_PER_PAGE) 72 | min_message_id = int(request.GET['page_num']) * _MESSAGES_PER_PAGE 73 | max_message_id = min_message_id + _MESSAGES_PER_PAGE + 1 74 | messages = thread.message_set.filter(id__gt=min_message_id).filter(id__lt=max_message_id) 75 | 76 | messages_json = [message.as_dict() for message in messages] 77 | 78 | response_data = { 79 | 'messages': messages_json 80 | } 81 | 82 | return HttpResponse(json.dumps(response_data), content_type='application/json') 83 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "simple_forum.settings") 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError: 10 | # The above import may fail for some other reason. Ensure that the 11 | # issue is really that Django is missing to avoid masking other 12 | # exceptions on Python 2. 13 | try: 14 | import django 15 | except ImportError: 16 | raise ImportError( 17 | "Couldn't import Django. Are you sure it's installed and " 18 | "available on your PYTHONPATH environment variable? Did you " 19 | "forget to activate a virtual environment?" 20 | ) 21 | raise 22 | execute_from_command_line(sys.argv) 23 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/media/category_logo/info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/10/code/simple_forum/media/category_logo/info.png -------------------------------------------------------------------------------- /lections/10/code/simple_forum/media/category_logo/question.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/10/code/simple_forum/media/category_logo/question.png -------------------------------------------------------------------------------- /lections/10/code/simple_forum/requirements.txt: -------------------------------------------------------------------------------- 1 | appdirs==1.4.2 2 | Django==1.10.6 3 | olefile==0.44 4 | packaging==16.8 5 | Pillow==4.0.0 6 | pyparsing==2.1.10 7 | six==1.10.0 8 | psycopg2 9 | WhiteNoise 10 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/simple_forum/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/10/code/simple_forum/simple_forum/__init__.py -------------------------------------------------------------------------------- /lections/10/code/simple_forum/simple_forum/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for simple_forum project. 3 | 4 | Generated by 'django-admin startproject' using Django 1.10.6. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/1.10/ref/settings/ 11 | """ 12 | 13 | import os 14 | 15 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 16 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 | 18 | 19 | # Quick-start development settings - unsuitable for production 20 | # See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/ 21 | 22 | # SECURITY WARNING: keep the secret key used in production secret! 23 | SECRET_KEY = '0)ky_#*day$(pxpq$p7c8=b=7e&bq8+^zd79e48bf&q2kv0g#$' 24 | 25 | # SECURITY WARNING: don't run with debug turned on in production! 26 | DEBUG = False 27 | 28 | ALLOWED_HOSTS = ['*'] 29 | 30 | 31 | # Application definition 32 | 33 | INSTALLED_APPS = [ 34 | 'django.contrib.admin', 35 | 'django.contrib.auth', 36 | 'django.contrib.contenttypes', 37 | 'django.contrib.sessions', 38 | 'django.contrib.messages', 39 | 'django.contrib.staticfiles', 40 | 'forum', 41 | ] 42 | 43 | MIDDLEWARE = [ 44 | 'django.middleware.security.SecurityMiddleware', 45 | 'django.contrib.sessions.middleware.SessionMiddleware', 46 | 'django.middleware.common.CommonMiddleware', 47 | 'django.middleware.csrf.CsrfViewMiddleware', 48 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 49 | 'django.contrib.messages.middleware.MessageMiddleware', 50 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 51 | ] 52 | 53 | ROOT_URLCONF = 'simple_forum.urls' 54 | 55 | TEMPLATES = [ 56 | { 57 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 58 | 'DIRS': [], 59 | 'APP_DIRS': True, 60 | 'OPTIONS': { 61 | 'context_processors': [ 62 | 'django.template.context_processors.debug', 63 | 'django.template.context_processors.request', 64 | 'django.contrib.auth.context_processors.auth', 65 | 'django.contrib.messages.context_processors.messages', 66 | ], 67 | }, 68 | }, 69 | ] 70 | 71 | WSGI_APPLICATION = 'simple_forum.wsgi.application' 72 | 73 | 74 | # Database 75 | # https://docs.djangoproject.com/en/1.10/ref/settings/#databases 76 | 77 | DATABASES = { 78 | 'default': { 79 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 80 | 'NAME': 'simple_forum', 81 | 'USER': 'forum', 82 | 'PASSWORD': 'forum', 83 | 'HOST': 'pgdb', 84 | 'PORT': '5432', 85 | } 86 | } 87 | 88 | 89 | # Password validation 90 | # https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators 91 | 92 | AUTH_PASSWORD_VALIDATORS = [ 93 | { 94 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 95 | }, 96 | { 97 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 98 | }, 99 | { 100 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 101 | }, 102 | { 103 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 104 | }, 105 | ] 106 | 107 | 108 | # Internationalization 109 | # https://docs.djangoproject.com/en/1.10/topics/i18n/ 110 | 111 | LANGUAGE_CODE = 'en-us' 112 | 113 | TIME_ZONE = 'UTC' 114 | 115 | USE_I18N = True 116 | 117 | USE_L10N = True 118 | 119 | USE_TZ = True 120 | 121 | 122 | # Static files (CSS, JavaScript, Images) 123 | # https://docs.djangoproject.com/en/1.10/howto/static-files/ 124 | 125 | STATIC_ROOT = '/srv/simple_forum/static' 126 | STATIC_URL = '/static/' 127 | 128 | MEDIA_ROOT = '/srv/simple_forum/media' 129 | MEDIA_URL ='/media/' 130 | 131 | LOGIN_REDIRECT_URL = '/' 132 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/simple_forum/urls.py: -------------------------------------------------------------------------------- 1 | """simple_forum URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/1.10/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.conf.urls import url, include 14 | 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url, include 17 | from django.conf.urls.static import static 18 | from django.conf import settings 19 | from django.contrib import admin 20 | from django.contrib.auth import views as auth_views 21 | 22 | 23 | urlpatterns = [ 24 | url(r'^', include('forum.urls')), 25 | url(r'^admin/', admin.site.urls), 26 | 27 | url(r'^accounts/login/$', auth_views.login, { 28 | 'template_name': 'login.html' 29 | }, name='login'), 30 | url(r'^accounts/logout/$', auth_views.logout, { 31 | 'next_page': 'index' 32 | }, name='logout'), 33 | ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) 34 | -------------------------------------------------------------------------------- /lections/10/code/simple_forum/simple_forum/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for simple_forum project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.10/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | from whitenoise.django import DjangoWhiteNoise 14 | 15 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "simple_forum.settings") 16 | 17 | application = get_wsgi_application() 18 | application = DjangoWhiteNoise(application) 19 | -------------------------------------------------------------------------------- /lections/10/slides/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Веб-программирование на Физтехе 2016-2017 5 | 6 | 7 | 8 | 9 | 10 | 11 |
    12 |

    Веб-программирование на Физтехе 2016-2017

    13 |

    Занятие 10. Развертывание проектов с использованием Docker

    14 |
    15 |
    16 |

    Занятие 10. Развертывание проектов с использованием Docker

    17 |

    Web Programming @ MIPT, 2016-2017

    18 | 19 | 23 | 41 |
    42 | 43 | 44 |
    45 |

    Виртуализация

    46 | Виртуализа́ция — предоставление набора вычислительных ресурсов или их логического объединения, абстрагированное от аппаратной реализации, и обеспечивающее при этом логическую изоляцию друг от друга вычислительных процессов, выполняемых на одном физическом ресурсе. 47 |
      48 |
    • Виртуализация серверов
    • 49 |
    • Виртуализация приложений
    • 50 |
    51 |
    52 | 53 |
    54 |

    Виртуализация серверов

    55 | Преимущества: 56 |
      57 |
    • Сокращение количества серверов благодаря консолидации
    • 58 |
    • Упрощение администрирования
    • 59 |
    • Слой абстракции между ПО и физическим железом
    • 60 |
    • Безопасность
    • 61 |
    • Отказоустойчивость
    • 62 |
    • Гибкая настройка виртуальных серверов
    • 63 |
    64 |
    65 | 66 |
    67 |

    Виртуализация серверов

    68 | Недостатки: 69 |
      70 |
    • Ресурсоемкость
    • 71 |
    • Разделение ресурсов
    • 72 |
    • Возможная единая точка отказа
    • 73 |
    74 |
    75 | 76 |
    77 |

    Виртуализация приложений

    78 |
      79 |
    • Значительно дешевле виртуализации серверов
    • 80 |
    • Удобство в администрировании
    • 81 |
    • Портируемость
    • 82 |
    • Единое окружение для разработки и продакшена
    • 83 |
    84 |
    85 | 86 |
    87 |

    Docker

    88 | Докер — это открытая платформа для разработки, доставки и эксплуатации приложений. Docker разработан для более быстрого выкладывания ваших приложений. С помощью docker вы можете отделить ваше приложение от вашей инфраструктуры и обращаться с инфраструктурой как управляемым приложением.

    89 | В своем ядре docker позволяет запускать практически любое приложение, безопасно изолированное в контейнере. Безопасная изоляция позволяет вам запускать на одном хосте много контейнеров одновременно. Легковесная природа контейнера, который запускается без дополнительной нагрузки гипервизора, позволяет вам добиваться больше от вашего железа. 90 |
    91 | 92 |
    93 |

    Docker

    94 | 95 |
    96 | 97 |
    98 |

    Docker

    99 |
      100 |
    • Образы (images)
    • 101 |
    • Реестр (registries)
    • 102 |
    • Контейнеры
    • 103 |
    104 |
    105 | 106 |
    107 |

    Docker образы

    108 |
      109 |
    • Read-only шаблон для контейнеров
    • 110 |
    • В основе - UnionFS
    • 111 |
    • Создание образа - это наложении уровней в UnionFS друг на друга
    • 112 |
    • В основе каждого образа - базовый образ
    • 113 |
    114 |
    115 | 116 |
    117 |

    Docker реестр

    118 |
      119 |
    • Хранилище docker образов
    • 120 |
    • Публичный реестр - Docker Hub
    • 121 |
    • Аналог репозиториев для docker-контейнеров
    • 122 |
    123 |
    124 | 125 |
    126 |

    Docker контейнеры

    127 |
      128 |
    • Контейнер работает поверх образа
    • 129 |
    • Создается слой для чтения-записи, в процессе работы контейнер может меняться
    • 130 |
    • Взаимодействие с внешним миром происходит через сеть
    • 131 |
    132 |
    133 | 134 |
    135 |

    Django in Docker: DEMO

    136 |
    137 | 138 |
    139 |

    Вопросы?

    140 |
    141 | 145 |
    146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /lections/10/slides/pictures/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/10/slides/pictures/architecture.png -------------------------------------------------------------------------------- /lections/10/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/10/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/11/README.md: -------------------------------------------------------------------------------- 1 | ## Введение в язык программирования Go 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/11/slides/)** 4 | 5 | **[Код](code)** 6 | 7 | * [Интерактивный учебник по основам языка](https://tour.golang.org/welcome/1) 8 | * [Введение в программирование на Go](http://golang-book.ru) 9 | * [Программирование на языке Go](https://www.ozon.ru/context/detail/id/19954705/) 10 | 11 | -------------------------------------------------------------------------------- /lections/11/code/src/circle/circle.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | type Shape interface { 9 | area() float64 10 | } 11 | 12 | type Circle struct { 13 | x float64 14 | y float64 15 | r float64 16 | } 17 | 18 | func (c Circle) area() float64 { 19 | return math.Pi * c.r*c.r 20 | } 21 | 22 | func (c *Circle) area() float64 { 23 | return 0 24 | } 25 | 26 | func main() { 27 | var c Shape = Circle{x: 0, y: 0, r: 5} 28 | fmt.Println(c.area()) 29 | } 30 | -------------------------------------------------------------------------------- /lections/11/code/src/defer/defer.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func first() { 6 | fmt.Println("1st") 7 | } 8 | func second() { 9 | fmt.Println("2nd") 10 | } 11 | func main() { 12 | defer second() 13 | first() 14 | } 15 | -------------------------------------------------------------------------------- /lections/11/code/src/fib/fib.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | s := make([]int, 2, 10) 7 | s[0] = 1 8 | s[1] = 1 9 | for i := 2; i < 10; i++ { 10 | s = append(s, s[i - 1] + s[i - 2]) 11 | } 12 | fmt.Println(s) 13 | } 14 | -------------------------------------------------------------------------------- /lections/11/code/src/for/for.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | i := 0; 7 | for i < 10 { 8 | fmt.Println(i) 9 | i++ 10 | } 11 | 12 | for i := 0; i < 10; i++ { 13 | fmt.Println(i) 14 | } 15 | 16 | arr := []int{1, 2, 3} 17 | for i := range arr { 18 | fmt.Println(i) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /lections/11/code/src/func/func.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func sum(a... int) (ret int) { 6 | ret = 0 7 | for _, v := range a { 8 | ret += v 9 | } 10 | return 11 | } 12 | 13 | func main() { 14 | fmt.Println(sum(1, 2)) 15 | fmt.Println(sum(1, 2, 3)) 16 | } 17 | -------------------------------------------------------------------------------- /lections/11/code/src/generator/fib_generator.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func FibGenerator() (func() int) { 6 | i1 := 1 7 | i2 := 0 8 | return func() (ret int) { 9 | ret = i1 + i2 10 | i1 = i2 11 | i2 = ret 12 | return 13 | } 14 | } 15 | 16 | func main() { 17 | gen := FibGenerator() 18 | for i := 0; i < 10; i++ { 19 | fmt.Println(gen()) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lections/11/code/src/hello/hello.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // this is a comment 6 | 7 | func main() { 8 | fmt.Println("Hello World") 9 | } 10 | -------------------------------------------------------------------------------- /lections/11/code/src/if/if.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | for i := 0; i < 10; i++ { 7 | if i % 2 == 0 { 8 | fmt.Println(i) 9 | } 10 | } 11 | if i := 2; i % 2 == 0 { 12 | fmt.Println("Should print") 13 | } 14 | if i := 2; i % 2 == 1 { 15 | fmt.Println("Shouldn't print") 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /lections/11/code/src/panic/panic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | // "fmt" 5 | "errors" 6 | ) 7 | 8 | func main() { 9 | //defer func() { 10 | // str := recover() 11 | // fmt.Println(str) 12 | //}() 13 | panic(errors.New("panic")) 14 | } 15 | -------------------------------------------------------------------------------- /lections/11/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/11/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/12/README.md: -------------------------------------------------------------------------------- 1 | ## Введение в язык программирования Go (Продолжение) 2 | 3 | **[Слайды](https://dbeliakov.github.io/mipt-web-2016/lections/12/slides/)** 4 | 5 | **[Код](code)** 6 | 7 | * [Интерактивный учебник по основам языка](https://tour.golang.org/welcome/1) 8 | * [Введение в программирование на Go](http://golang-book.ru) 9 | * [Программирование на языке Go](https://www.ozon.ru/context/detail/id/19954705/) 10 | * [Про горутины](https://habrahabr.ru/post/141853/) 11 | -------------------------------------------------------------------------------- /lections/12/code/src/channels/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func pinger(c chan string) { 9 | for i := 0; ; i++ { 10 | c <- "ping" 11 | } 12 | } 13 | func printer(c chan string) { 14 | for { 15 | msg := <- c 16 | fmt.Println(msg) 17 | time.Sleep(time.Second * 1) 18 | } 19 | } 20 | func main() { 21 | var c chan string = make(chan string) 22 | 23 | go pinger(c) 24 | go printer(c) 25 | 26 | var input string 27 | fmt.Scanln(&input) 28 | } 29 | -------------------------------------------------------------------------------- /lections/12/code/src/goroutines/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func f(n int) { 6 | for i := 0; i < 10; i++ { 7 | fmt.Println(n, ":", i) 8 | } 9 | } 10 | 11 | func main() { 12 | go f(0) 13 | go f(1) 14 | var input string 15 | fmt.Scanln(&input) 16 | } 17 | -------------------------------------------------------------------------------- /lections/12/code/src/package/exmaple/example.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import "fmt" 4 | 5 | func print() { 6 | fmt.Println("Private"); 7 | } 8 | 9 | func callPrintPrivate() { 10 | print(); 11 | } 12 | 13 | func Print() { 14 | fmt.Println("Public"); 15 | } 16 | -------------------------------------------------------------------------------- /lections/12/code/src/package/main/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "package/exmaple" 4 | 5 | func main() { 6 | example.Print(); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /lections/12/code/src/pool/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type Pool struct{} 6 | 7 | func NewPool() Pool { 8 | return Pool{} 9 | } 10 | 11 | func (this *Pool) exec(f func(...interface{}) interface{}, args ...interface{}) chan interface{} { 12 | c := make(chan interface{}) 13 | go func() { 14 | val := f(args...) 15 | c <- val 16 | close(c) 17 | }() 18 | return c 19 | } 20 | 21 | func main() { 22 | p := NewPool() 23 | res := make([]chan interface{}, 0) 24 | for i := 1; i <= 10; i++ { 25 | res = append(res, p.exec(func(args ...interface{}) interface{} { 26 | val := 1 27 | for _, a := range args { 28 | val *= a.(int) 29 | } 30 | return val 31 | }, i, i)) 32 | } 33 | for _, r := range res { 34 | val := <-r 35 | fmt.Println(val) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lections/12/code/src/select/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | func main() { 9 | c1 := make(chan string) 10 | c2 := make(chan string) 11 | 12 | go func() { 13 | for { 14 | c1 <- "from 1" 15 | time.Sleep(time.Second * 2) 16 | } 17 | }() 18 | go func() { 19 | for { 20 | c2 <- "from 2" 21 | time.Sleep(time.Second * 3) 22 | } 23 | }() 24 | go func() { 25 | for { 26 | select { 27 | case msg1 := <- c1: 28 | fmt.Println(msg1) 29 | case msg2 := <- c2: 30 | fmt.Println(msg2) 31 | } 32 | } 33 | }() 34 | 35 | var input string 36 | fmt.Scanln(&input) 37 | } 38 | -------------------------------------------------------------------------------- /lections/12/code/src/tests/example.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | func Average(vals []float64) float64 { 4 | var res float64 = 0 5 | for _, val := range vals { 6 | res += val 7 | } 8 | return res / float64(len(vals)) 9 | } 10 | -------------------------------------------------------------------------------- /lections/12/code/src/tests/example_test.go: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import "testing" 4 | 5 | func TestAverage(t *testing.T) { 6 | var v float64 7 | v = Average([]float64{1,2}) 8 | if v != 1.5 { 9 | t.Error("Expected 1.5, got ", v) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /lections/12/code/src/web/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "html/template" 5 | "net/http" 6 | ) 7 | 8 | func IndexHandler(w http.ResponseWriter, r *http.Request) { 9 | name := r.URL.Query().Get("name") 10 | if len(name) == 0 { 11 | name = "Аноним" 12 | } 13 | t, err := template.ParseFiles("templates/index.tpl") 14 | if err != nil { 15 | w.WriteHeader(http.StatusInternalServerError) 16 | } 17 | t.Execute(w, map[string]string{"Name": name}) 18 | } 19 | 20 | func main() { 21 | http.HandleFunc("/", IndexHandler) 22 | http.ListenAndServe(":8080", nil) 23 | } 24 | -------------------------------------------------------------------------------- /lections/12/code/src/web/templates/index.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Index 6 | 7 | 8 |

    Привет, {{ .Name }}

    9 | 10 | 11 | -------------------------------------------------------------------------------- /lections/12/slides/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Веб-программирование на Физтехе 2016-2017 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
    13 |

    Веб-программирование на Физтехе 2016-2017

    14 |

    Занятие 12. Введение в язык программирования Go (Продолжение)

    15 |
    16 |
    17 |

    Занятие 12. Введение в язык программирования Go (Продолжение)

    18 |

    Web Programming @ MIPT, 2016-2017

    19 | 20 | 24 | 42 |
    43 | 44 | 45 |
    46 |

    Многопоточность в Go

    47 |
      48 |
    • Основные инструменты - горутины и каналы
    • 49 |
    • Горутина (goroutine) — это функция, выполняющаяся конкурентно с другими горутинами в том же адресном пространстве
    • 50 |
    • Горутины очень легковесны
    • 51 |
    52 |
    53 | 54 |
    55 |

    Горутины

    56 |
      57 |
    • G (Goroutine) — Горутина, M (Machine) — Машина
    • 58 |
    • Каждая Машина работает в отдельном потоке и способна выполнять только одну Горутину в момент времени
    • 59 |
    • Максимальное число машин: GOMAXPROCS или runtime.GOMAXPROCS(n int)
    • 60 |
    • Планировщик Go распределяет готовые к исполнению горутины по машинам
    • 61 |
    62 |
    63 | 64 |
    65 |

    Горутины

    66 | 67 | Подробнее 68 |
    69 | 70 |
    71 |

    Горутины

    72 |
    
     73 | package main
     74 | import "fmt"
     75 | func f(n int) {
     76 |     for i := 0; i < 10; i++ {
     77 |         fmt.Println(n, ":", i)
     78 |     }
     79 | }
     80 | 
     81 | func main() {
     82 |     go f(0)
     83 |     var input string
     84 |     fmt.Scanln(&input)
     85 | }
     86 | 		
    87 |
    88 | 89 |
    90 |

    Каналы

    91 |
      92 |
    • Каналы обеспечивают возможность общения нескольких горутин друг с другом, чтобы синхронизировать их выполнение
    • 93 |
    • Фактически, это блокирующая или буферезированная очередь
    • 94 |
    • Создание канала: c := make(chan string), c := make(chan string, 5)
    • 95 |
    • Можно указать направление: chan<- string, <-chan string
    • 96 |
    97 |
    98 | 99 |
    100 |

    Каналы

    101 |
    
    102 | func pinger(c chan string) {
    103 |     for i := 0; ; i++ {
    104 |         c <- "ping"
    105 |     }
    106 | }
    107 | func printer(c chan string) {
    108 |     for {
    109 |         msg := <- c
    110 |         fmt.Println(msg)
    111 |         time.Sleep(time.Second * 1)
    112 |     }
    113 | }
    114 | func main() {
    115 |     var c chan string = make(chan string)
    116 | 
    117 |     go pinger(c)
    118 |     go printer(c)
    119 | 
    120 |     var input string
    121 |     fmt.Scanln(&input)
    122 | }
    123 | 		
    124 |
    125 | 126 |
    127 |

    Select

    128 |
      129 |
    • Позволяет читать или писать из/в нескольких/-o каналов
    • 130 |
    • По синтаксису схож с switch
    • 131 |
    • Можно использовать для таймеров: case <- time.After(time.Second)
    • 132 |
    133 |
    134 | 135 |
    136 |

    Пакеты в Go

    137 |
      138 |
    • Импорт осуществляется по пути в src
    • 139 |
    • Название пакета не обязано совпадать с названием конечной папки
    • 140 |
    • Все, что называется с маленькой буквы (someFunction) доступно на уровне пакета, все, что с большой SomeFunction доступно извне
    • 141 |
    142 |
    143 | 144 |
    145 |

    Тестирование в Go

    146 |
      147 |
    • Тесты пишутся в файлах _test.go
    • 148 |
    • Тесты относятся к тому же пакету
    • 149 |
    • Тесты определяются с помощью добавления Test к имени функции
    • 150 |
    • Запуск тестов: go test
    • 151 |
    152 |
    153 | 154 |
    155 |

    Стандартная библиотека Go

    156 | Основные вещи из стандартной библиотеки
  • 157 | 158 | 159 |
    160 |

    Вопросы?

    161 |
    162 | 166 |
    167 | 168 | 169 | 170 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /lections/12/slides/pictures/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/12/slides/pictures/cover.jpg -------------------------------------------------------------------------------- /lections/12/slides/pictures/goroutines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbeliakov/mipt-web-2016/d7332caffa5e2da9bd43c6aed16e7ae4f3ef0dbc/lections/12/slides/pictures/goroutines.png --------------------------------------------------------------------------------