четверг, 24 ноября 2016 г.

Використання власних функцій

Заняття 6
На цьому занятті я розгляну створення власних функцій, які використовуватимуться у програмах.
Нагадаю, що мова PYTHON є функціональною, тобто використовує для роботи з даними функції. До цього часу ми використовували стандартні функції, наприклад, int(), input(), print(), abs(), range(), map() тощо. Як видно із запису, всі вони після свого ім’я мають дужки, в яких записується їх аргумент чи аргументи, тобто ті величини, для яких визначається функція (якщо аргумент відсутній, то для функції береться той, що за замовчуванням). При звертанні до функції у програмний код підставляється її значення, наприклад, при виконанні запису
a=abs(b)
у змінну а записується значення модуля числа b.
Саме наявність великої кількості стандартних функцій зробило цю мову програмування зручною до використання і навчання. Крім цього є можливість підключення цілих модулів, кожен з яких містить від декількох до кількох десятків різноманітних функцій. Підключення цих модулів буде розглянуто пізніше, бо вони не входять до шкільної програми, але можуть використовуватися в олімпіадних завданнях. Але яка б не була кількість стандартних функцій завжди знайдеться та, яка потрібна до конкретної задачі, але вона не належить до них. Наприклад, для знаходження площі опуклого багатокутника шляхом розбивання його на трикутники з відомими сторонами, приводить до того, що потрібно використовувати формулу Герона кілька разів. Якщо буде відповідна функція, яка б за відомими трьома сторонами обчислюватиме площу трикутника, то вона значно полегшить розвязання цієї задачі. До того ж використання функцій розбиває велику задачу на менші підзадачі, які розвязуватимуть вже функції. Взагалі, використання функцій приводить до кращого розуміння ходу її розвязку і «читання» програмного коду, що є дуже важливим фактором майбутнього програміста, який буде працювати в команді.
Функцію до використання у програмі потрібно написати, причому у будь-якому місці програми, але до місця її виклику. Розглянемо написання функції Geron:
def Geron(a,b,c):
    p=(a+b+c)/2
s=(p*(p-a)*(p-b)*(p-c))**0.5
return s
      Перший рядок – це заголовок (назва) функції, що містить у дужках аргументи (довжини сторін трикутника).Починається рядок зі слова def. В кінці рядка ставиться двокрапка, а всі наступні рядки, що належать до функції, зміщені праворуч.
  Другий рядок містить обчислення півпериметра трикутника, а третій – обчислення площі трикутника.
     Четвертий рядок надає функції значення s (площі).
    Використаємо цю функції для розв’язання наступної задачі. У одному рядку дано 5 натуральних чисел: сторони чотирикутнка і довжина діагоналі, проведеної з вершини, спільної до перших двох сторін, до вершини, спільної для третьої і четвертої. Знайти площу паралелограма (див. рисунок).
     Весь програмний код матиме такий вигляд:

def Geron(a,b,c):
          p=(a+b+c)/2
s=(p*(p-a)*(p-b)*(p-c))**0.5
return s
a,b,c,d,m=map(int,input().split())
s=Geron(a,m,d)+Geron(b,m,c)
print(s)
     Кількість функцій, що можуть використовуватися в програмі необмежена, причому з однієї функції може викликатися інша. Якщо функція викликає саму себе, то вона називається рекурсивною, а сам спосіб такого виклику – рекурсією. Найпростіший приклад рекурсії є обчислення факторіалу n! (де n– невід’ємне число). Нагадаю, що n!=1∙2∙3∙…∙(n-1)∙n, або n!= (n-1)!∙n
    Запишемо програму, яка для даного числа визначає його факторіал
def fact(x):
         if x==1:
                   return 1
         else:
                   return fact(x-1)*x
n=int(input())
print(fact(n))
    У рекурсивній функції повинна бути прописана умова виходу з рекурсії (в нашому випадку при х=0). Поки не досягнута умова виходу, значення функції набуває значення, яке береться з наступного значення функції при іншому аргументі. Розглянемо покроково виконання цієї програми при n=4.
Після зчитування змінної n одразу викликається функція виведення значення print(), аргументом якої є значення функції fact(). Функція fact() викликається перший раз із аргументом 4, тобто значення змінної х у функції набуває значення 4. Пройшовши перевірку умови, значення цієї функції повинне набути значення fact(3)*4, але значення fact(3) ще треба обчислити, тому знову викликається ця сама функція, але вже з аргументом 3. Після перевірки умови значення функції стане рівним fact(2)*3, тобто fact(3)= fact(2)*3, а fact(4)= fact(2)*3*4. Наступний виклик функції відбувається з аргументом 1, тобто  fact(2)= fact(1)*2 або fact(4)= fact(1)*2*3*4. Останній крок завершує виклик функції (перериває рекурсію) і замість fact(1) виводить 1. Глибина рекурсії в даному випадку становить 4, бо стільки разів викликається функція. Для людини цей процес важко втримати в голові, а для комп’ютера просто, та і записується програма не досить складно.
       Ще одним із важливих прикладів використання рекурсії є знаходження найбільшого спільного дільника (НСД) двох чисел за алгоритмом Евкліда.  Дійсно, якщо число с є дільником чисел а і b, то він є дільником і їх різниці, тому НСД(а, b)= НСД(а, a-b) або НСД(а, b)= НСД(а, a % b). Якщо перший аргумент більший за другий, то можна записати так: НСД(а, b)= НСД(b, a % b). Так щоразу значення аргументів будуть зменшуватися, поки другий із них не стане дорівнювати 0. Отже, перший аргумент і буде відповіддю. Тому функція буде мати такий вигляд:
def nsd(a,b):
         if b!=0:
                   return nsd(b, a%b)
         else:
                   return а
Розглянемо кілька прикладів.

   Приклад 1.
   Знайти периметр багатокутника, заданого координатами своїх вершин. У першому рядку дано натуральне число n(n<100). У наступних n рядках дано по два цілих числа – координати наступної вершини багатокутника.
Вивести одне дійсне число, округлене до сотих, – периметр багатокутника.
Вхід                         Вихід
4                               19.79
-2 4
2 6
3 3
0 -2
def dist(x1,y1,x2,y2):                                #  опис функції з ім’ям dist                
    return ((x1-x2)**2+(y1-y2)**2)**0.5  # обчислення функції
n=int(input())                                            # зчитування кількості вершин
x1,y1=map(int,input().split())                  # зчитування координат першої вершини
x0=x1                                                       # запам’ятовуємо під іншими змінними
y0=y1                                                       #
p=0.0                                                 # початкове значення периметру в дійсному типі
for i in range(n-1):                                    #запуск циклу для решти n-1 вершин
    x2,y2=map(int,input().split())              # зчитування координат
    p+=dist(x1,y1,x2,y2)                            # збільшення периметру на значення функції
    x1=x2                          # тепер друга координата стане першою для наступної вершини
    y1=y2                                                  #
p+=dist(x1,y1,x0,y0) #додавання до периметру відстані між останньою вершиною і першою
print(round(p,2)) # виведення округленого до 2 знаків після коми значення периметра

      Приклад 2
    Знайти найменше спільне кратне (НСК) двох чисел. У двох рядках дано по одному натуральному числу. Вивести одне натуральне число – НСК цих чисел.
     Вхід             Вихід
     6                   24
     8
    Скористаємося відомим співвідношенням a*b=НСД(a,b)*НСК(a,b).
def nsd(a,b):
    if b!=0:
        return nsd(b, a%b)
    else:
        return a
x=int(input())
y=int(input())
print(x*y//nsd(x,y))
    
         Приклад 3.
     Опуклий п’ятикутник заданий координатами своїх вершин. Знайти його площу. У п’ятьох рядках дано по два дійсних числа – координати вершин п’ятикутника. Вивести значення площі п’ятикутника з точністю до тисячних.
       Вхід                       Вихід
       -2 4                        68.985
       -4 0.9
       0.42 -7.83
       5.5 -0.34
       2.34 5.3

      Приклад 4.
     Чотири бігуни бігають по колу довжиною 100 м. Перший пробігає одне коло за а секунд, другий – за b секунд, третій – за с секунд, а четвертий – за d секунд. Всі четверо починають бігти одночасно і не змінюють свою швидкість. Скільки метрів пробіжить перший спортсмен, коли вони знову зустрінуться всі в точці старту?
     У одному рядку через пробіл дано 4 натуральних числа, що не менші за 10 і не більші за 100, – час, за яких пробігає одне коло кожен спортсмен. Вивести одне натуральне число – відповідь на задачу.
     Вхід                       Вихід
    10 20 25 50            1000
    Пояснення прикладу: бігуни зустрінуться в точці старту через 100 секунд, бо за цей час перший спортсмен пробіжить рівно 10 кіл, другий – 5, третій – 4, а четвертий – 2. Тому перший спортсмен пробіжить 10*100=1000 метрів.
def nsd(a,b):
    if b!=0:
        return nsd(b, a%b)
    else:
        return a
def nsk(a,b):
    return a*b//nsd(a,b)
a,b,c,d=map(int,input().split())
s=nsk(nsk(nsk(a,b),c),d)          # час, за який одночасно досягнуть точки старту
print(s//a*100)


     Наступного разу я розгляну у статті використання списків, які більш відомі як масиви. До зустрічі.

1 комментарий:

  1. Шановні відвідувачі блогу. Автор щиро вдячний Вам за схвальні відгуки цього блогу, але маю Вам повідомити, що втратив можливість надалі вести цей блог. Тому його робота продовжиться за новою адресою pythonforschool.blogspot.com, де викладений матеріал по вивченню PYTHON саме для учнів 8 класу з розбивкою задач на теми, викладенням теоретичного матеріалу з прикладами, списком задач для класної та домашньої роботи та підтримкої їх онлайн-перевірки. Буду радий Вас всіх бачити на оновленому блозі.

    ОтветитьУдалить