ლექცია 06 · VI კვირაLecture 06 · Week VI

საკუთარი
ფუნქციები
Writing your
own functions

def · პარამეტრიანი და უპარამეტრო ფუნქციები · გაჩუმებით პარამეტრი · ანონიმური ფუნქცია def · functions with and without parameters · default parameters · anonymous functions

დღეს ასევე: პრაქტიკული დავალება #2 Also today: practical assignment #2

მოტივაციაMotivation

რატომ ვქმნით ფუნქციებსWhy we write functions

გამეორებაRepetition

a, b = 3, 4
print((a ** 2 + b ** 2) ** 0.5)

c, d = 6, 8
print((c ** 2 + d ** 2) ** 0.5)

e, f = 5, 12
print((e ** 2 + f ** 2) ** 0.5)

ფორმულა შესაცვლელი რომ იყოს — სამივე ადგილას უნდა შეასწორო. If the formula changes, you must fix it in all three places.

ფუნქციითWith a function

def hypotenuse(a, b):
    return (a ** 2 + b ** 2) ** 0.5

print(hypotenuse(3, 4))
print(hypotenuse(6, 8))
print(hypotenuse(5, 12))
DRYDon't Repeat Yourself — ერთი ლოგიკა ერთ ადგილას უნდა ცხოვრობდეს. DRYDon’t Repeat Yourself — one piece of logic should live in one place.
ხაზი გაუსვი: ფუნქცია მხოლოდ „ხაზების დაზოგვა“ არაა — ეს სახელის მიცემაა აზრისთვის. კარგად დასახელებული ფუნქცია კომენტარს ცვლის. Stress this: a function is not just about saving lines — it is about naming an idea. A well-named function replaces a comment.

სინტაქსიSyntax

def — ფუნქციის აღწერაdef — defining a function

def name(parameters):
    """documentation — optional"""
    body
    return result
def greet():
    print("გამარჯობა!")

greet()          # calling it
greet()

უპარამეტრო ფუნქცია. ფრჩხილები მაინც სავალდებულოა. A function with no parameters. The parentheses are still required.

  • აღწერა ≠ შესრულებაdef მხოლოდ „ასწავლის“ Python-ს. კოდი მხოლოდ გამოძახებისას შესრულდება
  • აღწერა გამოძახებამდეწინააღმდეგ შემთხვევაში — NameError
  • სახელიsnake_case, ზმნით იწყება: calculate_total, is_valid
  • Defining ≠ runningdef only teaches Python the recipe. The body runs only when called
  • Define before you callOtherwise — NameError
  • The namesnake_case, usually starting with a verb: calculate_total, is_valid

გასაღებიThe key idea

returnprint

def add_print(a, b):
    print(a + b)

result = add_print(2, 3)   # on screen: 5
print(result)              # None
print(result * 2)          # TypeError!
def add(a, b):
    return a + b

result = add(2, 3)
print(result)              # 5
print(result * 2)          # 10
print(add(1, 1) + add(2, 2))  # 6
ეს ყველაზე ხშირი გაუგებრობაა დამწყებთანprint — ეკრანზე გამოტანაა (ადამიანისთვის). return — მნიშვნელობის დაბრუნებაა (პროგრამისთვის). თუ return არაა, ფუნქცია None-ს აბრუნებს. The most common beginner confusionprint displays something on screen (for a human). return hands a value back (for the program). Without a return, a function returns None.
def check(n):
    if n > 0:
        return "დადებითი"     # exits the function right here
    return "არადადებითი"      # no else needed

არგუმენტებიArguments

პარამეტრები და არგუმენტებიParameters and arguments

def rectangle_area(width, height):   # width, height — parameters
    return width * height

print(rectangle_area(4, 5))          # 4, 5 — arguments

გადაცემის ორი გზაTwo ways to pass them

def intro(name, city, age):
    print(f"{name}, {city}, {age} წლის")

intro("ნინო", "თბილისი", 20)

თანმიმდევრობა მნიშვნელოვანია.The order matters.

intro(age=20, name="ნინო", city="თბილისი")
intro("ნინო", age=20, city="თბილისი")

თანმიმდევრობა თავისუფალია, კოდი კითხვადი. Order is free and the code reads clearly.

წესიპოზიციური არგუმენტი ვერ დადგება სახელდებულის შემდეგ. RuleA positional argument cannot follow a keyword argument.

არგუმენტებიArguments

გაჩუმებით (ნაგულისხმევი) პარამეტრიDefault parameters

def greet(name, greeting="გამარჯობა"):
    print(f"{greeting}, {name}!")

greet("ნინო")                      # გამარჯობა, ნინო!
greet("გიორგი", "სალამი")          # სალამი, გიორგი!
greet("ანა", greeting="დილა მშვიდობისა")

def power(base, exp=2):
    return base ** exp

print(power(5))        # 25  — squared by default
print(power(5, 3))     # 125
წესინაგულისხმევიანი პარამეტრები ყოველთვის ბოლოში იწერება.
def f(a=1, b):SyntaxError
RuleParameters with defaults always come last.
def f(a=1, b):SyntaxError
ხაფანგი, რომელიც უნდა იცოდენაგულისხმევ მნიშვნელობად არასდროს გამოიყენო ცვალებადი ობიექტი (სია, ლექსიკონი): def f(items=[]) — ის ერთხელ იქმნება და ყველა გამოძახებას შორის ინახება. სწორია def f(items=None). A trap worth knowingNever use a mutable object (list, dict) as a default: def f(items=[]) — it is created once and shared across every call. The correct form is def f(items=None).

არგუმენტებიArguments

ცვალებადი რაოდენობა: *args და **kwargsA variable number: *args and **kwargs

def total(*numbers):
    result = 0
    for n in numbers:
        result += n
    return result

print(total(1, 2))            # 3
print(total(1, 2, 3, 4, 5))   # 15
print(total())                # 0
def profile(**info):
    for key, value in info.items():
        print(f"{key}: {value}")

profile(name="ნინო", age=20, city="ბათუმი")

name: ნინო age: 20 city: ბათუმი

მნიშვნელოვანია ვარსკვლავი, არა სახელიargs და kwargs უბრალოდ მიღებული სახელებია. * აგროვებს პოზიციურს, ** — სახელდებულს. The asterisk matters, not the nameargs and kwargs are just conventional names. * collects positional arguments, ** collects keyword ones.

დაბრუნებაReturning

რამდენიმე მნიშვნელობის დაბრუნებაReturning several values

def stats(a, b, c):
    return min(a, b, c), max(a, b, c), (a + b + c) / 3

low, high, avg = stats(4, 9, 2)
print(low, high, avg)          # 2 9 5.0

result = stats(4, 9, 2)
print(result)                  # (2, 9, 5.0)
print(type(result))            # <class 'tuple'>
print(result[0])               # 2
რა მოხდა სინამდვილეშიPython ერთ ობიექტს აბრუნებს — tuple-ს (X კვირა). მისი „დაშლა“ ცალკე ცვლადებად ეწოდება unpacking. What actually happenedPython returns one object — a tuple (week X). Splitting it into separate variables is called unpacking.
def divide(a, b):
    return a // b, a % b

whole, rest = divide(17, 5)
print(f"{whole} მთელი, {rest} ნაშთი")   # 3 მთელი, 2 ნაშთი

ცნებაConcept

ხილვადობის არე (scope)Scope

counter = 10          # global

def show():
    counter = 5       # local — a brand new variable!
    print("შიგნით:", counter)

show()                # შიგნით: 5
print("გარეთ:", counter)   # გარეთ: 10

ლოკალურიLocal

იბადება ფუნქციის გამოძახებისას, კვდება დასრულებისას. გარედან მიუწვდომელია.

Born when the function is called, gone when it ends. Not reachable from outside.

გლობალურიGlobal

ცხოვრობს მთელი პროგრამის განმავლობაში. ფუნქციას წაკითხვა შეუძლია, შეცვლა — მხოლოდ global-ით.

Lives for the whole program. A function can read it; to change it you need global.

global-ს მოერიდეის აკავშირებს ერთმანეთთან კოდის შორეულ ნაწილებს და შეცდომების პოვნას ართულებს. სუფთა გზაა: მიიღე არგუმენტად, დააბრუნე return-ით. Avoid globalIt couples distant parts of the code and makes bugs harder to find. The clean way: take it as an argument, hand it back with return.
დაფაზე დახატე ორი „ყუთი“ — გლობალური და ლოკალური სივრცე. ეს ვიზუალი კარგად მუშაობს. Draw two boxes on the board — the global and the local space. That visual works well.

დოკუმენტაციაDocumentation

Docstring — ფუნქციის აღწერაDocstrings — describing a function

def bmi(weight, height):
    """სხეულის მასის ინდექსის გამოთვლა.
    Body mass index.

    weight — წონა კილოგრამებში / weight in kilograms
    height — სიმაღლე მეტრებში / height in metres
    """
    return weight / height ** 2


print(bmi(70, 1.75))       # 22.857…
help(bmi)
print(bmi.__doc__)
რატომ ღირსVS Code-ში კურსორის გაჩერებისას სწორედ ეს ტექსტი გამოჩნდება. საკუთარ თავს სამი თვის შემდეგ დიდად დაეხმარები. Why it pays offThis is exactly the text VS Code shows when you hover. You are helping your future self three months from now.

დანამატი njpwerner.autodocstring ჩარჩოს ავტომატურად აგენერირებს. The njpwerner.autodocstring extension generates the skeleton for you.

ანონიმურიAnonymous

lambda — ერთხაზიანი ფუნქციაlambda — a one-line function

def square(x):
    return x ** 2

print(square(5))    # 25
square = lambda x: x ** 2
print(square(5))    # 25

add = lambda a, b: a + b
print(add(2, 3))    # 5

სად გამოიყენება რეალურადWhere it is actually used

students = [("ნინო", 92), ("გიორგი", 78), ("ანა", 85)]

# sort by score
students.sort(key=lambda s: s[1], reverse=True)
print(students)
# [('ნინო', 92), ('ანა', 85), ('გიორგი', 78)]

numbers = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda n: n % 2 == 0, numbers))
squares = list(map(lambda n: n ** 2, numbers))
წესიlambda მხოლოდ ერთი გამოსახულებისთვისაა. თუ ცვლადს ანიჭებ — უბრალოდ def დაწერე. მისი ნამდვილი ადგილი sort, map, filter-ის არგუმენტშია. Rulelambda holds one expression only. If you are assigning it to a name, just write def. Its real home is as an argument to sort, map or filter.

სრული მაგალითიFull example

პროგრამა ფუნქციებად დაშლილიA program split into functions

def get_grade(score):
    """ქულა → ასოითი შეფასება (ECTS სკალა).
    Score → letter grade (ECTS scale)."""
    if score >= 91: return "A"
    if score >= 81: return "B"
    if score >= 71: return "C"
    if score >= 61: return "D"
    if score >= 51: return "E"
    return "F"


def is_valid(score):
    """ქულა კორექტულ დიაპაზონშია? / Is the score in range?"""
    return 0 <= score <= 100


def show(name, score):
    if not is_valid(score):
        print(f"{name}: არაკორექტული ქულა")
        return
    print(f"{name}: {score} ქულა → {get_grade(score)}")


show("ნინო", 92)
show("გიორგი", 67)
show("ანა", 150)
აჩვენე, რომ თითოეული ფუნქცია ცალკე იტესტება. ესაა გადასვლა „სკრიპტიდან“ „პროგრამაზე“. Show that each function can be tested on its own. This is the step from “script” to “program”.

შეფასებაAssessment

პრაქტიკული დავალება #2Practical assignment #2

8 ქულა · სრულდება აუდიტორიაში, დამოუკიდებლად 8 points · done in class, independently

  1. is_prime(n)აბრუნებს True/False. გამოიყენე ციკლში 1–50 მარტივი რიცხვების დასაბეჭდად
  2. convert_temp(value, to="F")ნაგულისხმევი პარამეტრით: °C → °F ან °C → K
  3. stats(*numbers)აბრუნებს მინიმუმს, მაქსიმუმს, ჯამსა და საშუალოს (რამდენიმე მნიშვნელობა)
  4. count_vowels(text)ითვლის ხმოვნებს; დაუმატე docstring და შეამოწმე help()-ით
  5. ყველა ფუნქციას უნდა ჰქონდეს return, არა print
  1. is_prime(n)Returns True/False. Use it in a loop to print the primes from 1 to 50
  2. convert_temp(value, to="F")With a default parameter: °C → °F or °C → K
  3. stats(*numbers)Returns the minimum, maximum, sum and average (several values at once)
  4. count_vowels(text)Counts vowels; add a docstring and check it with help()
  5. Every function must use return, not print
შემოწმების კრიტერიუმიფუნქცია სწორად უნდა მუშაობდეს სხვადასხვა არგუმენტზე — არა მხოლოდ ერთ მაგალითზე. სცადე კიდურა შემთხვევები: 0, 1, უარყოფითი, ცარიელი ტექსტი. Marking criteriaEach function must work for a range of arguments, not just one example. Try the edge cases: 0, 1, negatives, empty text.

შემაჯამებელიWrap-up

რა უნდა დაგამახსოვრდესWhat to remember

შემდეგი — ლექცია 07სტრიქონები: მეთოდები, ფორმატირება, ძებნა და ჩანაცვლება. შემდეგ კვირას — შუალედური გამოცდა. Next — lecture 07Strings: methods, formatting, searching and replacing. The midterm exam follows the week after.