diff --git a/images/python-thernary operator-meme.webp b/images/python-thernary operator-meme.webp new file mode 100644 index 0000000..256d6dd Binary files /dev/null and b/images/python-thernary operator-meme.webp differ diff --git a/images/string-methods-meme.webp b/images/string-methods-meme.webp new file mode 100644 index 0000000..f0028ed Binary files /dev/null and b/images/string-methods-meme.webp differ diff --git "a/images/\320\243\321\200\320\276\320\272_16_\320\234\320\260\320\272\320\265\321\202\321\203\320\262\320\260\320\275\320\275\321\217_\320\240\320\276\320\267\321\200\320\276\320\261\320\272\320\260_\320\264\320\270\320\267\320\260\320\271\320\275\321\203.pdf" "b/images/\320\243\321\200\320\276\320\272_16_\320\234\320\260\320\272\320\265\321\202\321\203\320\262\320\260\320\275\320\275\321\217_\320\240\320\276\320\267\321\200\320\276\320\261\320\272\320\260_\320\264\320\270\320\267\320\260\320\271\320\275\321\203.pdf" new file mode 100644 index 0000000..2247487 Binary files /dev/null and "b/images/\320\243\321\200\320\276\320\272_16_\320\234\320\260\320\272\320\265\321\202\321\203\320\262\320\260\320\275\320\275\321\217_\320\240\320\276\320\267\321\200\320\276\320\261\320\272\320\260_\320\264\320\270\320\267\320\260\320\271\320\275\321\203.pdf" differ diff --git a/lesson01.md b/lesson01.md index b1115ec..97749e3 100644 --- a/lesson01.md +++ b/lesson01.md @@ -21,6 +21,7 @@ Для побудови алгоритмів рекомендується використати блок-схеми. Спочатку студентам настійно рекомендується будувати блок-схеми навіть для найпростіших завдань, далі - тільки для тих, які здаються їм складними. + ## Блок-схеми **Блок-схемою** називають графічне придставлення алгоритму. У блок-схемі крок чи послідовність кроків алгоритму представляються у вигляді блоку, а між блоками встановлюють зв'язки. @@ -34,6 +35,7 @@ ![решение котика](https://cs7.pikabu.ru/post_img/2018/04/23/6/1524471868135292777.jpg) + ## Змінні в Python: визначення, типи даних. **Змінною** називається найменована область у пам'яті, де зберігаються дані. Змінна має тип та ім'я. @@ -56,6 +58,7 @@ my_bool = True #правда чи брехня, булеви значенн ``` + ## Типизация **Статична типізація** означає, що тип змінної визначається спочатку і залишається незмінним остаточно програми. Якщо змінна спочатку оголошена контейнером для цілих чисел, у ній можуть бути лише цілі числа. diff --git a/lesson03.md b/lesson03.md index c3b5cb0..a817d89 100644 --- a/lesson03.md +++ b/lesson03.md @@ -44,7 +44,7 @@ while True: У цій можливості оператору `while` криється його небезпека: якщо неграмотно скласти обробку умови та її зміну всередині тіла циклу, то вн легко увійде у режим вічного повтору і програма може просто підвиснути. Також у цикла `while`, завдяки факту перевірки умови ПЕРЕД здійсненням дій з інформацією є можливість, при неграмотному складанні алгоритму вчинити одну лишню ітерацію (повтора тіла циклу) і видати результат відмінний від очікуваного. Цих нелоліків позбавлений наступний оператор циклу, який деякі ортодоксальні програмісти також прирівнюють до "синтаксичного цукру". -## Оператор циклу for +## Оператор циклу for і чому його називають синтаксичним цукром. На відміну від `while` оператор циклу `for` має явно вказану кінечність, оскільки здійснює повтори виклюно згідно кількості елементів ітерованого об'єкта, який йому передається. Те саме підсумовування перших 10 елементів, що й за допомогою циклу `while`, але за допомогою `for`: @@ -65,10 +65,104 @@ for i in 'word': sum += i print(sum) ``` -Бувають ситуації, коли виникає необхідність не просто поелементного перебору ітерованого об'єкту, але й встановлення індексу кожного його елемента. У цьому випадку використовуєтсья метод `enumerate()`, котрий додає до ітерованого об'єкту лічильник і повертає його у вигляді нумерованого об'єкту. Цей нумерований об'єкт у подальшому може бути використаний напряму у циклах `for` або конвертований у список, кожен елемент якого є кортежем за допомогою функції `list()`. + +Насправді. +Внутрішня реалізація циклу `for` у пайтоні виглядає наступним чином: +```python +num_iterator = iter(numbers)while True: +try: + # get the next item + number = next(num_iterator) +except StopIteration: + break +``` +Іронічно, але цикл `for` є лише нескінченним циклом `while` з ітератором. Саме тому, його і називають синтаксичним цукром. + +# Повне розгалудення у циклах. Команди else, break, continue + +У пайтоні існує одна досить дивна конструкція, яка відрізняє його від інших мов програмування. А саме: конструкція `else` у циклах. + +Трошки історії. +Коли мова Пайтон створювалась у 1991-му році, використання `else` було доречним, оскільки у ті часи реалізація циклів з передумовою передбачала алгоритм "Якщо цикл не завершено - переходи до тіла циклу": +```С +/* Simulating a while-else contruct with gotos and an if-else */ +goto looptest; +body: { + /* code for the loop body goes here + "continue" translates to "goto looptest;" + "break" translates to "goto done;" + */ +} +looptest: + if (condition) { + goto body; + } else { + /* code for the else-clause goes here */ + } +done: +``` +Ідея саме цього алгоритму належить Дональду Кнуту, а не Гвідо Ван Россуму. У подальшому Гвідо вважав подібну імплементацію помилкою, але код інструкції `else` не стали видаляти з мови Пайтон, щоб зберегти сумісність з попередніми версіями. + +Отже, що саме відбувається при застосуванні інструкції `else`? + +Гілка відгалудження циклу `else` виконується саме у разі штатного завершення циклу шляхом проходження всіх його повторів, доки умова його виконання не стане 'False'. Вона використовується виключно у тих рідкісних випадках, коли потрібно передбачити окремий ряд інструкці для обов'язкового виконання і разі нормального завершення циклу. +```python +inputList = [10, 20, 30, 40, 50] +print("Input list elements:") +for element in inputList: + print(element) +else: + print('iteration ended') +``` +у цьому випадку команда `print('iteration ended')` буде виконуватись ЗАВЖДИ, при штатному завершенні циклу без виникнення виключень. + +Слід відзначити, що гілка `else` все ще залишається частиною циклу. Саме тому, команда `break`, яка перериває виконання циклу, передає управління наступній команді ПІСЛЯ гілки `else`. +```python +inputList = [11, 22, 33, 44, 55] +for element in inputList: + if not element%5: + break + else: + print(element) +else: + print('iteration ended') +print('end of program') +``` +У даному випадку, коли опрацьовувана у циклі величина буде ділитись на 5, спрацює команда `break`, яка переведе виконання на строку `print('end of program')` + +Інакше працює команда `continue` - вона передає виконання на інструкцію, яка цикл починає. Будь то `for` чи `while`: +```python +inputList = [11, 22, 33, 44, 55] +for element in inputList: + if not element%4: + continue + else: + print(element) +else: + print('iteration ended') +print('end of program') +``` +У цьому прикладі, у разі настання умови "опрацьовувана величина ділиться на 4" всі наступні команди будуть проігноровані, а цикл почнеться з наступного повтору. + +Слід відмітити, що завдяки особливостям реалізації, при одних і тих самих умовах цикл `for` виконається приблизно на 20-50% щвидше за цикл `while`. Тим не менше, якщо швидкість виконання для вас є критичною, то варто уникати використання будь-яких циклів, і користуватись вбудованими функціями і методами мови Пайтон (наприклад мета-функцією `map()`, чи функціями типу `max()`,`min()`,`sort()` та ін.), оскільки вони будуть набагато швидші за будь-який цикл реалізований на самій мові Пайтон. + +# Використання функції enumerate() у циклах + +Завдяки наведеній вище структурі цикла `for` стає зрозумілим, що у випадку, якщо вам потрібно перебрати елементи ітерованого об'єкту по індексам, то писати код накшталт: +```python +inputList = [11, 20, 33, 40, 55] +for element in range(len(inputList)): + if not inputList[element]%5: + else: + print(inputList[element]) +print('end of program') +``` +буде помилкою. Створення генератора, параметром якого є результат роботи функції, що обробляє ітератор - це лишні дії, які можуть сповільнити код. + +Тому, коли виникає необхідність не просто поелементного перебору ітерованого об'єкту, але й встановлення індексу кожного його елемента варто використовувати функцію `enumerate()`, котра додає до ітерованого об'єкту лічильник і повертає його у вигляді нумерованого об'єкту. Цей нумерований об'єкт у подальшому може бути використаний напряму у циклах `for` або конвертований у список, кожен елемент якого є кортежем за допомогою функції `list()`. Синтаксис функції: enumerate(iterable, start=0) -де: iterable - ітерований об'єкт; start - початкове значення індексу (0 за замовчуванням) +де: iterable - ітерований об'єкт; start - початкове значення лічильника (0 за замовчуванням) ```python a = [10, 20, 30, 40] @@ -92,8 +186,16 @@ print (list(enumerate(l1))) #[(0, 'eat'), (1, 'sleep'), (2, 'repeat')] # замінюємо початковий індекс на 2 print (list(enumerate(s1, 2))) #[(2, 'g'), (3, 'e'), (4, 'e'), (5, 'k')] ``` +Досить часто функція `enumerate()` використовується для перетворення списків чи кортежів у словники, перетворюючи індекси елементів на ключі словника. -Слід відмітити, що внутрішня реалізація у пайтоні циклу `for` є швидшою за код циклу `while`. І при одних і тих самих умовах цикл `for` виконається приблизно на 20-50% щвидше. Тим не менше, якщо швидкість виконання для вас є критичною, то варто уникати використання будь-яких циклів і користуватись вбудованими функціями і методами мови Пайтон (наприклад мета-функцією `map()`, чи функцыями типу `max()`,`min()`,`sort()` та ін.), оскільки вони будуть набагато швидші за будь-який цикл реалізований на самій мові. +```python +my_list = ['apple', 'banana', 'orange'] +my_dict = {} +for index, value in enumerate(my_list): + my_dict[index] = value +print(my_dict) #{0: 'apple', 1: 'banana', 2: 'orange'} +``` +Тут ми спочатку ініціалізуємо порожній словник my_dict. Потім ми проходимо по кожному елементу списку my_list за допомогою циклу, використовуючи enumerate(), і додаємо кожен елемент у словник з ключем з індексу елементу списку. ## Базова робота з файлами @@ -116,8 +218,6 @@ for line in f: # для кожного рядка у файлі f.close() # закриття файлу ``` - - Тут треба звернути увагу на такі рядки: **`import sys`** - включення до нашої програми бібліотеки системних функцій, з допомогою якої ми можемо працювати з параметрами командного рядка, наприклад. **`filename = sys.argv[1]`, де sys.argv** - функція системної бібліотеки sys. Вона зчитує перший параметр зі списку параметрів командного рядка. @@ -139,19 +239,19 @@ f.close() ``` Але При використанні даного алгоритму можуть виникати наступні помилки: - 1. Помилка доступу: може виникнути помилка, якщо користувач не має дозволу на запис до файлу. Наприклад, якщо файл вже відкритий у іншому додатку або якщо користувач не має достатніх дозволів на запис до файлу. +1. Помилка доступу: може виникнути помилка, якщо користувач не має дозволу на запис до файлу. Наприклад, якщо файл вже відкритий у іншому додатку або якщо користувач не має достатніх дозволів на запис до файлу. - 2. Помилка шляху до файлу: може виникнути помилка, якщо файл не знайдено в заданому шляху. Перевірте, чи існує файл в заданому шляху, а також чи вірно вказаний шлях до файлу. +2. Помилка шляху до файлу: може виникнути помилка, якщо файл не знайдено в заданому шляху. Перевірте, чи існує файл в заданому шляху, а також чи вірно вказаний шлях до файлу. - 3. Помилка запису: може виникнути помилка, якщо не вдалося записати дані до файлу. Наприклад, якщо недостатньо пам'яті на диску або якщо диск заблокований. +3. Помилка запису: може виникнути помилка, якщо не вдалося записати дані до файлу. Наприклад, якщо недостатньо пам'яті на диску або якщо диск заблокований. - 4. Помилка відкриття файлу: може виникнути помилка, якщо файл не відкривається. Наприклад, якщо файл уже відкритий у іншому процесі або якщо він був переміщений або видалений. +4. Помилка відкриття файлу: може виникнути помилка, якщо файл не відкривається. Наприклад, якщо файл уже відкритий у іншому процесі або якщо він був переміщений або видалений. - 5. Помилка кодування: може виникнути помилка, якщо використовується неправильне кодування файлу. Наприклад, якщо використовується кодування, відмінне від кодування файлу, то можуть виникнути проблеми з відображенням тексту. +5. Помилка кодування: може виникнути помилка, якщо використовується неправильне кодування файлу. Наприклад, якщо використовується кодування, відмінне від кодування файлу, то можуть виникнути проблеми з відображенням тексту. - 6. Помилка відкриття файлу у режимі запису: якщо файл уже відкритий у режимі запису, то виникає помилка, якщо спробувати відкрити його в режимі запису знову. +6. Помилка відкриття файлу у режимі запису: якщо файл уже відкритий у режимі запису, то виникає помилка, якщо спробувати відкрити його в режимі запису знову. -Але якщо під час запису у файл програма впіймає виключення (внаслідок одної з перелічених вище помилок), файл ніколи не буде закритий. Тому варто використовувати контекстний менеджер with: +Якщо під час запису у файл програма впіймає виключення (внаслідок одної з перелічених вище помилок), файл ніколи не буде закритий. Тому варто використовувати контекстний менеджер with: ```python with open('file.txt','w') as f: @@ -160,6 +260,15 @@ with open('file.txt','w') as f: Оператор контекстного менеджера автоматично закриває файл, коли виконання блоку with закінчується. Це означає, що ви більше не маєте проблеми з закриттям файлу вручну, що допомагає уникнути помилок, пов'язаних з відкриттям та закриттям файлів, які можуть виникнути, якщо ви відкриєте файл вручну, і забудете закрити його пізніше. Також його використання робить код більш читабельним. +Цікаво, що використовуючи такий контекстний менеджер, можна одночасно відкривати декілька файлів, наприклад, якщо вам потрібно ось прочитати з одного файлу, змінити дані і записати у інший: + +```python +with open('input_file.txt','r') as inp, open('output_file.txt', 'w') as outp: + text=inp.readlines() + uppercase=[upper(x) for x in text] + outp.writelines(uppercase) +``` + ## Практика - Кожен пише суму списку за допомогою for та while diff --git a/lesson04.md b/lesson04.md index 9a3e5f2..e560f81 100644 --- a/lesson04.md +++ b/lesson04.md @@ -4,7 +4,7 @@ У Python є мінливі (mutable) та незмінні (immutable) типи даних. -Раніше розглядався тип даних int, який є незмінним. Так само незмінними є типи даних tuple (кортеж) і string (рядок). +Раніше розглядався тип даних int, який є незмінним. Так само незмінними є типи даних tuple (кортеж), frozenset (фіксована множина) і string (рядок). Що значить незмінні? Значить, що вже створений рядок ми не можемо змінити. Це легко покажуть подальші приклади із рядками і кортежами. Якщо ж здається, що об'єкт одного з перерахованих даних змінився - значить, тепер ім'я об'єкта просто вказує на нову область пам'яті з новим об'єктом. @@ -25,12 +25,12 @@ S4 = 'This "string" is a bit """crazy"""' ### Прості операції -Прості арифметичні операції складання і множення доступні і з рядками. У прикладі нижче - складання двох рядків (конкатенація), множення рядка на число та взяття конкретного елемента рядка за його індексом. Індекси у всіх послідовностях у програмуванні вважаються від нуля. По негативному індексу - відраховуємо від кінця рядка назад. +Прості арифметичні операції складання (конкатенації) і множення (повторення) доступні і з рядками. У прикладі нижче - складання двох рядків, множення рядка на число та взяття конкретного елемента рядка за його індексом. Індекси у всіх послідовностях у програмуванні вважаються від нуля. По негативному індексу - відраховуємо від кінця рядка назад. ```python S = 'abc' print (len(S)) # 3 -S = S + '12' # В S = 'abc12' +S = S + '12' # S = 'abc12' print (S[2]) # 'c' print ('ab'*2) # 'abab' ``` @@ -66,6 +66,8 @@ Python дозволяє взяти частину рядка або навіть 'Welcome to California!' >>> S[:-3] 'Welcome to Californ' +>>>print(S[-3:]) +'ia!' >>> S[::-1] '!ainrofilaC ot emocleW' >>> S[:5:2] @@ -216,7 +218,9 @@ print(message) В python відсутні масиви в традиційному розумінні цього терміну. Точніше, якщо вам конче необхідно використати саме масиви, то варто імпортувати модуль array: +```python import array +``` Даний модуль визначає тип об'єкта, який може ефективно опрацьовувати масив з базових типів даних: букв, цифр, дробів (str, int, float). Масиви є ітерованим типом даних і ведуть себе дуже схоже на списки, з єдиною відмінністю - всі об'єкти всередині них є однотипними. @@ -262,7 +266,7 @@ L = [1, 2, 's'] ``` -### Деякі функції, що працюють зі списками +### Деякі методи, що працюють зі списками ```python >>> L = list(range(1, 11)) @@ -280,12 +284,15 @@ L = [1, 2, 's'] >>> L.remove(5) # Removes the first 5 appeared >>> L [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14] +>>> L.pop() #takes the last iterable from the list and transfers it +[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13] +>>> print(L.pop()) #takes the last iterable from list and prints it +13 ``` ```python ->>> L -[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +>>> L=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # map function applies the method given to the iterable proposed >>> L = list(map(str, range(1, 11))) >>> L # Here we have casted all integers to strings @@ -362,6 +369,8 @@ say Sparta!! [List comprehensions за 5 хвилин](https://medium.com/nuances-of-programming/list-comprehensions-%D0%B2-python-%D0%B7%D0%B0-5-%D0%BC%D0%B8%D0%BD%D1%83%D1%82-4e5ff3cafd62) +[документацыя по модулю array (англійською))](https://docs.python.org/3/library/array.html#module-array) + [Зрізи](https://habr.com/ru/post/319200/) [Домашка](hw04.md) diff --git a/lesson05.md b/lesson05.md index b5999b8..81dbf34 100644 --- a/lesson05.md +++ b/lesson05.md @@ -47,6 +47,15 @@ def say_hello(): ```python print(say_hello()) # Hello ``` +Іноді, особливо у великих проектах, буває так, що програміст створив функцію, але поки ще не придумав її код. Зазвичай у такому випадку замість коду вставляється команда `pass` чи `...`, які інтерперетатор просо пропускає. Але у цьому випадку, якщо ви пізніше викличете функцію без коду, вона нічого не виконає, а ви не будете розуміти у чому проблема. Тому вважається хорошим тоном заповнювати пусті функції настумпним кодом: + +```python +def func(): + raise NotImplementedError('Code of func() is missing') +``` + +У цьому випадку при виклику не імплементованої функції, у консоль буде виведено повідомлення про помилку з відповідним текстом і вам буде набагато легше зрозуміти у чому проблема. + ### Параметри та аргументи функції diff --git a/lesson06.md b/lesson06.md index f548a3f..33a19db 100644 --- a/lesson06.md +++ b/lesson06.md @@ -141,6 +141,7 @@ from sys import argv as cli_param # >>> programmers - managers {'petrov', 'sidorov'} ``` +Але при роботі з Множинами слід пам'ятати, що вони є неіндексованим типом даних, а отже у разі їх використання у вас не вийде доступитись до якогось окремого їх елемента за індексом. Власне, окремі елементи множин можна отримати або перебравши їх послідовно, або перетворивши у список чи краще кортеж. ## 4. Dict (Словник) @@ -281,6 +282,49 @@ for key, val in d.items(): calculator['minus'](9,3) 6 ``` +Слід відмітити, що дещо подібний з цим метод можна використовувати для прискорення роботи програми, у випадку багатогілкового розгалудження. Даний метод може використовуватись також і у інших мовах програмування, у яких існує тип даних hash table, наприклад С++: +До прикладу - візьмемо код, з розгалуджннями, кожне з яких викликає окрему функцію: + +```python +def do_one(x): + print('one') +def do_two(x): + print('two') +def do_three(x): + print('tree') +def do_default(x): + print(x) + +x=2 +if x==1: + do_one(x) +elif x==2: + do_two(x) +elif x==3: + do_three(x) +else: + do_default(x) +``` +У цьому випадку таку і більшу кількість розгалуджень можна замінити словником, де у якості ключів вказані очікувані значення, а у якості значень - викликані функції: +```python +actions={1: do_one(x), 2: do_two(x), 3: do_three(x)} +``` +Зверніть увагу, що у даному словнику відсутня гілка `else`, яка викликає функцію `do_default(x)`. Але у разі вказання такого значення як вказаного по замовчуванню (дефолтного) для методу .get() застосовуваного до цього словника, де першим аргументом йде оброблювана величина, наступний код буде призводити до того самого результату: + +```python +action=actions.get(x, do_default) +action(x) +``` + + +Цікаво, що при роботі з словниками їх можна сортувати. Але якщо ви їх будете просто сортувати, то відбудеться сортування словника саме за ключами. Якщо ж вам необхідно здійснити сортування словника за значеннями, то варто використати наступний код: + +```python +students={'Mark': 11, 'Alexander': 36, 'Dietrich': 82, 'Gretchen': 29} +sudents=dict(sorted(students.items(), key=lambda x: x[1])) +print(students) #{'Mark': 11, 'Gretchen': 29, 'Alexander': 36, 'Dietrich': 82} +``` + ### Практичні завдання 1. Створити словник оцінок передбачуваних студентів (Ключ – ПІ студента, значення – список оцінок студентів). Знайти найуспішнішого і самого слабенького за середнім балом. diff --git a/lesson07.md b/lesson07.md index a57f285..ad33f29 100755 --- a/lesson07.md +++ b/lesson07.md @@ -286,3 +286,16 @@ git branch # видаляє, створює та перераховує гілк [Восьмий Урок](lesson08.md) +### Для тих, хто ніого не зрозумів: + +# Алгоритм простої роботи з чужим репозиторієм: +1.Зареєструватись на гітхабі. +2.Відкрити чужий репозиторій. +3.Клацнути справа-зверху на кнопку Fork та створити форк проекту собі на репозиторій. +4.Перейти у свій репозиторій та скопіювати посилання на нього. +5.У гіт-баші перейти у папку куди ви хочете клонувати репозиторій та написати: +git clone +6.Внести свої зміни. +7.Ввести у гіт-баші команду git add <імена файлів або . для багатьох> +8.Зберегти зміни у локальний гіт (зробити комміт): git commit -m 'some comment' +9.Відправити все на Гітхаб: git push \ No newline at end of file