Skip to content

Commit

Permalink
Many fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
vncpetrov committed Aug 17, 2018
1 parent 924752a commit 6ab429f
Showing 1 changed file with 33 additions and 38 deletions.
71 changes: 33 additions & 38 deletions chapter-06-nested-loops.md
Expand Up @@ -317,7 +317,7 @@ result2 = 3 // 2 # резултат 1

### Пример: диамант

Да се напише програма, която приема цяло число **n** (1 ≤ **n** ≤ 100) и печата диамант с размер **n**, като в следните примери:
Да се напише програма, която приема цяло число **n** (1 ≤ **n** ≤ 100) и печата диамант с размер **N**, като в следните примери:

|Вход|Изход|Вход|Изход|Вход|Изход|
|---|---|---|---|---|---|
Expand All @@ -333,61 +333,62 @@ result2 = 3 // 2 # резултат 1

#### Насоки и подсказки

Това, което знаем от условието на задачата, е че диамантът е с размер **`n` x `n`**.

От примерните вход и изход можем да си направим извода, че всички редове съдържат точно по **`n`** символа и всички редове, с изключение на горните върхове, имат по **2 звезди**. Можем мислено да разделим диаманта на 2 части:
Това, което знаем от условието на задачата, е че диамантът е с размер **`n` x `n`**. От примерните вход и изход можем да си направим извода, че всички редове съдържат точно по **`n`** символа и всички редове, с изключение на горните върхове, имат по **2 звезди**. Можем мислено да разделим диаманта на 2 части:
* **Горна** част. Тя започва от горния връх до средата.
* **Долна** част. Тя започва от реда след средата до най-долния връх включително.

##### Горна част
* Ако **n** е **нечетно**, то тя започва с **1 звезда**.
* Ако **n** е **четно**, то тя започва с **2 звезди**.

* Ако **`n`** е **нечетно**, то тя започва с **1 звезда**.
* Ако **`n`** е **четно**, то тя започва с **2 звезди**.
* С всеки ред надолу звездите се отдалечават една от друга.
* Пространството между, преди и след **звездите** е запълнено с **тирета**.

##### Долна част

* С всеки ред надолу звездите се приближават една към друга. Това означава, че пространството (**тиретата**) между тях намалява, а пространството (**тиретата**) отляво и отдясно се увеличава.
* В най-долната си част е с 1 или 2 **звезди**, спрямо това дали **n** е четно или не.
* В най-долната си част е с 1 или 2 **звезди**, спрямо това дали **`n`** е четно или не.

##### Горна и долна част на диаманта

* На всеки ред звездите са заобиколени от външни **тирета**, с изключение на средния ред.
* На всеки ред има пространство между двете **звезди**, с изключение на първия и последния ред (понякога **звездата е 1**).

Прочитаме стойността на **n** от конзолата и я записваме в променлива от тип **`int`**.
Прочитаме стойността на **`n`** от конзолата, като я конвертираме до тип **`int`**:

![](/assets/chapter-6-1-images/10.Diamond-01.png)

Започваме да печатаме на конзолата горната част на диаманта. Първото нещо, което трябва да направим, е да изчислим началната стойност на външната бройка **тирета `left_right`** (тиретата от външната част на **звездите**). Тя е равна на **`(n - 1) / 2`**, закръглено надолу.
Започваме да печатаме на конзолата горната част на диаманта. Първото нещо, което трябва да направим, е да изчислим началната стойност на външната бройка **тирета `left_right`** (тиретата от външната част на **звездите**). Тя е равна на **`(n - 1) / 2`**, закръглено надолу:

![](/assets/chapter-6-1-images/10.Diamond-02.png)

След като сме изчислили **`left_right`**, започваме да чертаем **горната част** на диаманта. Може да започнем, като завъртим **цикъл** от **`0`** до **`(n + 1) // 2 `** (т.е. закръглено надолу).

При всяко завъртане на цикъла трябва да се изпълнят следните стъпки:

* Печатаме на конзолата левите **тирета** (с дължина **`left_right`**) и веднага след тях първата **звезда**.
* Печатане на левите **тирета** на конзолата (с дължина **`left_right`**) и веднага след тях първата **звезда**.

![](/assets/chapter-6-1-images/10.Diamond-03.png)

* Ще изчислим разстоянието между двете **звезди**. Може да го направим като извадим от **n** дължината на външните **тирета**, както и числото 2 (бройката на **звездите**, т.е. очертанията на диаманта). Резултата от тази разлика записваме в променлива **`mid`**.
* Изчисляване на разстоянието между двете **звезди**. Може да го направим като извадим от **`n`** дължината на външните **тирета**, както и числото 2 (бройката на **звездите**, т.е. очертанията на диаманта). Резултата от тази разлика записваме в променлива **`mid`**.

![](/assets/chapter-6-1-images/10.Diamond-04.png)

* Ако **`mid`** е по-малко от 0, то тогава знаем, че на реда трябва да има 1 звезда. Ако е по-голямо или равно на 0, то тогава трябва да начертаем **тирета** с дължина **`mid`** и една **звезда** след тях.
* Ако стойността на **`mid`** е по-малка от 0, то тогава знаем, че на този ред трябва да има 1 звезда. Ако е по-голяма или равно на 0, то тогава трябва да начертаем **тирета** с дължина **`mid`** и една **звезда** след тях.
* Печатаме на конзолата десните външни **тирета** с дължина също **`left_right`**.

![](/assets/chapter-6-1-images/10.Diamond-05.png)

* В края на цикъла намаляваме **`left_right`** с 1 (**звездите** се отдалечават).
* В края на цикъла намаляваме стойността на **`left_right`** с 1 (**звездите** се отдалечават).

Готови сме с горната част.

Чертането на долната част е доста подобно на това на горната част. Разликата е, че вместо да намаляваме **`left_right`** с 1 към края на цикъла, ще увеличаваме **`left_right`** с 1 в началото на цикъла. Също така **цикълът ще е от 0 до `(n - 1) // 2`**.
Чертането на долната част е доста подобно на това на горната част. Разликата е, че вместо да намаляме стойността на **`left_right`** с 1 към края на цикъла, ще я увеличаваме с 1 в началото на цикъла. Също така **цикълът ще се върти от 0 до `(n - 1) // 2`**:

![](/assets/chapter-6-1-images/10.Diamond-06.png)

<table><tr><td><img src="/assets/alert-icon.png" style="max-width:50px" /></td>
<td><b>Повторението на код се смята за лоша практика</b>, защото кодът става доста труден за поддръжка. Нека си представим, че имаме парче код (напр. логиката за чертането на ред от диаманта) на още няколко места и решаваме да направим промяна. За целта би било необходимо да минем през всичките места и да направим промените. А сега нека си представим, че трябва да използвате код не 1, 2 или 3 пъти, а десетки пъти. Начин за справяне с този проблем е като се използват <b>методи</b>. Можете да потърсите допълнителна информация за тях в Интернет или да прегледате <a href="/chapter-10-methods.md">глава “10” (Методи)</a>.</td>
<td><b>Повторението на код се смята за лоша практика</b>, защото кодът става доста труден за поддръжка. Нека си представим, че имаме парче код (напр. логиката за чертането на ред от диаманта) на още няколко места и решаваме да направим промяна. За целта би било необходимо да минем през всичките места и да направим промените. А сега нека си представим, че трябва да използвате код не 1, 2 или 3 пъти, а десетки пъти. Начин за справяне с този проблем е като се използват <b>функции</b>. Можете да потърсите допълнителна информация за тях в Интернет или да прегледате <a href="/chapter-10-methods.md">Глава 10. Функции</a>.</td>
</tr></table>

Ако сме написали всичко коректно, задачата ни е решена.
Expand Down Expand Up @@ -425,58 +426,52 @@ for row in range(5):

### Задача: рейтинги – визуализация в уеб среда

Да се разработи Flask уеб приложение за визуализация на рейтинг (число от 0 до 100). Flask е лека Python библиотека, която служи за създаване на уеб приложения. Чертаят се от 1 до 10 звездички (с половинки). Звездичките да се генерират с **`for`** цикъл.
Да се разработи уеб приложение за визуализация на рейтинг (число от 0 до 100). Чертаят се от 1 до 10 звездички (с половинки). Звездичките да се генерират с **`for`** цикъл.

![](assets/chapter-6-1-images/11.Ratings-01.png)

Във PyCharm създаваме ново Flask уеб приложение с езика Python.
Добавяме нов проект от [**File**] -> [**New Project**].
#### Насоки и подсказки

Започваме като създаваме нов проект в **PyCharm** от [**File**] -> [**New Project**] (или от началния прозорец):

![](assets/chapter-6-1-images/11.Ratings-02.png)

Даваме смислено име, например "Ratings". Избираме тип на текущия **Python интерпретатор**. Нека да е този по подразбиране.
Даваме смислено име на проекта, например "Ratings". Избираме тип на текущия **Python интерпретатор**. Нека да е този по подразбиране:

![](assets/chapter-6-1-images/11.Ratings-03.png)

Преди да започнем да пишем код, трябва да инсталираме Flask. Отиваме в настройките на PyCharm [**File**] -> [**Settings**] и след това в [**Project: Ratings**] -> [**Project Interpreter**]. Там, натискаме бутона **`+`**:
Ще използваме отново библиотеката Flask, която служи за създаване на уеб приложения. Преди да започнем да пишем код, трябва да инсталираме Flask. Нека си припомним как ставаше това. Отиваме в настройките на PyCharm [**File**] -> [**Settings**] -> [**Project: Ratings**] -> [**Project Interpreter**]. Там, натискаме бутона **`+`**:

![](assets/chapter-6-1-images/11.Ratings-04.png)

Търсим **`Flask`** в прозореца, който излиза и натискаме бутона [**Install Package**]:
Търсим **Flask** в прозореца, който излиза и натискаме бутона [**Install Package**]:

![](assets/chapter-6-1-images/11.Ratings-05.png)

Ако всичко мине успешно, ще получим следното съобщение в същия екран:
Сега добавяме **структурата** на проекта (файловете със заданието за този проект могат да бъдат свалени от [тук](https://github.com/SoftUni/Programming-Basics-Book-Python-BG/tree/chapter-06-nested-loops/assets/chapter-6-1-assets)). Копираме ги от Windows Explorer и ги поставяме в папката на проекта **Ratings** с Copy/Paste:

![](assets/chapter-6-1-images/11.Ratings-06.png)

Сега добавяме **структурата** на проекта (файловете със заданието за този проект могат да бъдат свалени от [тук](https://github.com/SoftUni/Programming-Basics-Book-Python-BG/tree/master/assets/chapter-6-1-assets)). Копираме ги от Windows Explorer и ги поставяме в папката ни на проекта **Ratings** с copy/paste.
За да заработи всичко, трябва да допишем кода. Първо отиваме във файла **index.html** (от папка templates) и търсим **TODO** секциите. На тяхно място въвеждаме следния код:

![](assets/chapter-6-1-images/11.Ratings-07.png)

За да заработи всичко, трябва да допишем малко код. Първо отиваме във файла **index.html** и търсим **TODO** секции. Въвеждаме следния код:
Горният код създава уеб форма **`<form>`** с едно поле **`"rating"`** за въвеждане на число в интервала [**0 … 100**] и бутон [**Rate**] за изпращане на данните от формата към сървъра. След което, рисува с три отделни **for** цикъла съответния брой звездички - запълнени, полупразни и празни.

![](assets/chapter-6-1-images/11.Ratings-08.png)
Действието, което ще обработи данните, се казва **`/DrawRatings`**, което означава функция **`draw_ratings()`** във файла **`app.py`**:

Това създава уеб форма **`<form>`** с едно поле **`"rating"`** за въвеждане на число в интервала [**0 … 100**] и бутон [**Rate**] за изпращане на данните от формата към сървъра. След което рисува с три отделни **for** цикъла съответния брой звездички - запълнени, полупразни и празни.
![](assets/chapter-6-1-images/11.Ratings-08.png)

Действието, което ще обработи данните, се казва **`/DrawRatings`**, което означава метод **`draw_ratings`** в route **`/DrawRating`**, който се намира във файла **`app.py`**.
Кодът от функцията **`draw_ratings()`** взима въведеното число **`rating`** от формата и го подава на функцията **`calc_rating(…)`**. Функцията **`calc_rating(…)`** извършва пресмятания и изчислява броя **пълни звездички**, броя **празни звездички** и броя **половинки звездички**, след което зарежда отново страницата, но вече с подадени нови стойности на променливите за звездичките. Имплементираме я по следния начин:

![](assets/chapter-6-1-images/11.Ratings-09.png)

Горният код взима въведеното число **`rating`** и го подава на функцията **calc_rating**.
Стартираме проекта с [**Ctrl+Shift+F10**] (или с [**Десен бутон**] -> [**Run 'app'**]) и изчакваме да се зареди:

![](assets/chapter-6-1-images/11.Ratings-10.png)

Тя прави малко пресмятания и изчислява броя **пълни звездички**, броя **празни звездички** и броя **половинки звездички**, след което зарежда отново страницата, но вече с подадени нови стойности на променливите.

Стартираме проекта с [**Ctrl+Shift+F10**] и изчакваме да се зареди:

![](assets/chapter-6-1-images/11.Ratings-11.png)

![](assets/chapter-6-1-images/11.Ratings-12.png)

Отиваме на посочения адрес и се наслаждаваме на готовия проект:

![](assets/chapter-6-1-images/11.Ratings-13.png)
![](assets/chapter-6-1-images/11.Ratings-11.png)

Ако имате проблеми с примерния проект по-горе, питайте във **форума на СофтУни**: https://softuni.bg/forum.
Ако имате проблеми с примерния проект по-горе, може да задавате въпроси във **форума на СофтУни**: [https://softuni.bg/forum](https://softuni.bg/forum).

0 comments on commit 6ab429f

Please sign in to comment.