0% found this document useful (0 votes)
3 views11 pages

Tutorial Functions

This document provides a comprehensive tutorial on functions in Python programming, emphasizing their importance for reusability, readability, and maintainability. It covers the creation and calling of functions, parameter types, variable scope, and practical use cases, including data validation and processing. Additionally, it introduces lambda functions and their applications in sorting and data manipulation.

Uploaded by

Phương
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views11 pages

Tutorial Functions

This document provides a comprehensive tutorial on functions in Python programming, emphasizing their importance for reusability, readability, and maintainability. It covers the creation and calling of functions, parameter types, variable scope, and practical use cases, including data validation and processing. Additionally, it introduces lambda functions and their applications in sorting and data manipulation.

Uploaded by

Phương
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

PYTHON PROGRAMMING FOR DATA SCIENCE

TUTORIAL: FUNCTIONS

Page 1
1. Why Functions?
Let's start with a real problem: you need to calculate the average score for many students.

1.1. WITHOUT functions


Without functions — Repetitive, error-prone
# Student 1
math_1, phys_1, chem_1 = 8.5, 7.0, 9.0
avg_1 = (math_1 + phys_1 + chem_1) / 3
print(f"S1: {avg_1:.2f}")

# Student 2 - copy-paste again...


math_2, phys_2, chem_2 = 7.0, 8.5, 6.5
avg_2 = (math_2 + phys_2 + chem_2) / 3
print(f"S2: {avg_2:.2f}")

# Student 3 - copy-paste again...


math_3, phys_3, chem_3 = 9.0, 9.5, 8.5
avg_3 = (math_3 + phys_3 + chem_3) / 3
print(f"S3: {avg_3:.2f}")

# 47 more students...

1.2. WITH functions


With functions — Write once, use forever
def calc_average(math, phys, chem):
"""Calculate the average of 3 subjects"""
return (math + phys + chem) / 3

# Clean, readable, no repetition!


print(f"S1: {calc_average(8.5, 7.0, 9.0):.2f}")
print(f"S2: {calc_average(7.0, 8.5, 6.5):.2f}")
print(f"S3: {calc_average(9.0, 9.5, 8.5):.2f}")
# 47 more students - just 1 line each

Why do we need functions?


• Reusability: Write once, call many times
• Readability: Code has clear, descriptive names
• Maintainability: Fix in one place, applied everywhere
• Abstraction: Hide details, expose only what matters
• Testability: Easy to test each part independently

Page 2
2. Creating and calling functions
2.1. Basic Syntax
Function structure
def function_name(param_1, param_2):
"""Docstring: describes what the function does"""
# Function body: processing statements
result = param_1 + param_2
return result # Return the result

• def: keyword to start a function definition


• function_name: use snake_case, describe what the function does
• parameters: input data (can have 0 or many)
• """Docstring""": describes the function (optional but recommended)
• return: sends result back to the caller (optional)

2.2. Functions without return


Functions without return implicitly return None. Used when you only need to perform an action
(print, save file...).
No return
def greet(name):
"""Print a greeting — no return needed"""
print(f"Hello {name}! Happy learning.")

greet("Minh")
greet("Lan")

# Check return value


result = greet("An")
print(f"Return value: {result}") # None

Output:
Hello Minh! Happy learning.
Hello Lan! Happy learning.
Hello An! Happy learning.
Return value: None

2.3. Functions with return


With return
def absolute_value(num):

Page 3
"""Return the absolute value"""
if num < 0:
return -num
return num

a = absolute_value(-7)
b = absolute_value(3)
print(f"|{-7}| = {a}") # 7
print(f"|{3}| = {b}") # 3
print(f"Sum = {a + b}") # 10

Notes
• return ends the function immediately — code after return won't execute.
• A function can have multiple return statements (in different if/else branches).
• A function can return multiple values (as a tuple): return a, b

3. Parameter types
3.1. Positional arguments
Arguments matched by position — order must match the definition.
Positional
def introduce(name, age, major):
print(f"{name}, {age} years old, studying {major}")

introduce("An", 20, "CS") # Correct order


introduce(20, "An", "CS") # WRONG: 20 assigned to name!

3.2. Keyword arguments


Call by parameter name — order doesn't matter.
Keyword arguments
def msg(id, name):
print(f"ID: {id}, Name: {name}")

msg(id=100, name="Hoang") # Clear


msg(name="Hoang", id=101) # Reversed order - also OK!

3.3. Default parameters


Default parameters

Page 4
def hello(name, loud=False):
"""loud is optional, defaults to False"""
if loud:
print(f"HELLO, {[Link]()}!")
else:
print(f"Hello, {name}")

hello("Hoang") # No loud arg -> False


hello("Hoang", loud=True) # Explicit loud = True

Output:
Hello, Hoang
HELLO, HOANG!

3.4. Returning multiple values


Return multiple values
def statistics(numbers):
"""Return min, max, average of a list"""
smallest = min(numbers)
largest = max(numbers)
average = sum(numbers) / len(numbers)
return smallest, largest, average

# Call and unpack multiple values


scores = [8.5, 7.0, 9.2, 6.5, 8.0]
mn, mx, avg = statistics(scores)
print(f"Min: {mn}, Max: {mx}, Avg: {avg:.2f}")

Output:
Min: 6.5, Max: 9.2, Avg: 7.84

4. Variable scope
Scope determines where a variable "lives".

4.1. Local vs Global


Local vs Global
x = 20 # GLOBAL variable

def my_func():
x = 10 # LOCAL variable (different from global x!)
print("Inside:", x)

my_func() # Prints: 10

Page 5
print("Outside:", x) # Prints: 20 (unaffected)

Output:
Inside: 10
Outside: 20

4.2. Pass by Value vs Reference


Numbers/Strings: COPY Lists/Dicts: REFERENCE
def change(x): def add_item(lst):
x = 6 [Link](9)

x = 5 my_list = [5, 6, 7]
change(x) add_item(my_list)
print(x) # Still 5! print(my_list) # [5,6,7,9]

Remember
• Numbers, strings, tuples: function receives a COPY → changes inside don't affect outside.
• Lists, dicts: function receives a REFERENCE → changes inside DO affect outside!
• This is a common source of bugs. Be careful when passing lists/dicts to functions.

5. Use cases
Use case 1: Data validation
Validation
def validate_score(score):
if not isinstance(score, (int, float)):
return False, "Score must be a number"
if score < 0 or score > 10:
return False, "Score must be 0-10"
return True, "Valid"

print(validate_score(8.5)) # (True, "Valid")


print(validate_score(15)) # (False, "Score must be 0-10")
print(validate_score("abc")) # (False, "Score must be a number")

Use case 2: Data processing


Data processing
def clean_name(raw):
return [Link]().title()

Page 6
def make_email(full_name, domain="[Link]"):
parts = clean_name(full_name).lower().split()
if len(parts) < 2: return None
given = parts[-1]
family = "".join(parts[:-1])
return f"{given}.{family}@{domain}"

names = [" nguyen van AN ", "TRAN binh", " le thi chi "]
for raw in names:
print(f"{clean_name(raw):20s} -> {make_email(raw)}")

Output:
Nguyen Van An -> [Link]@[Link]
Tran Binh -> [Link]@[Link]
Le Thi Chi -> [Link]@[Link]

Use case 3: Function composition


Composition
def classify(score):
if score >= 8.5: return "Excellent"
if score >= 7.0: return "Good"
if score >= 5.5: return "Average"
return "Weak"

def process_student(name, scores):


avg = sum(scores) / len(scores)
grade = classify(avg) # Calling another function!
return {"name": name, "avg": avg, "grade": grade}

sv = process_student("An", [8.5, 9.0, 7.5])


print(f"{sv[\"name\"]}: {sv[\"avg\"]:.1f} - {sv[\"grade\"]}")

Output:
An: 8.3 - Good

6. Lambda — Anonymous functions


6.1. What is Lambda?
Lambda is a "one-line" function without a name. Used when you need a small, quick function
that's only used once or twice.

Page 7
Regular function (def) Lambda equivalent
def square(x): square = lambda x: x ** 2
return x ** 2

print(square(5)) # 25 print(square(5)) # 25

When to use Lambda?


Simple functions with a single expression, used 1–2 times
As a key for sorted(), max(), min()
As an argument for map(), filter()
NOT for complex logic (multiple lines, nested if/else)

6.2. Lambda with sorted()


This is the most common use case for lambda — sorting data by a custom criterion.
Lambda + sorted()
students = [("An", 8.5), ("Binh", 7.0), ("Chi", 9.2), ("Dung", 6.8)]

# Sort by score (2nd element of tuple)


by_score = sorted(students, key=lambda s: s[1])
print("Ascending:", by_score)

# Sort descending
by_score_desc = sorted(students, key=lambda s: s[1], reverse=True)
print("Descending:", by_score_desc)

# Sort by name length


by_len = sorted(students, key=lambda s: len(s[0]))
print("By name length:", by_len)

Output:
Ascending: [('Dung', 6.8), ('Binh', 7.0), ('An', 8.5), ('Chi', 9.2)]
Descending: [('Chi', 9.2), ('An', 8.5), ('Binh', 7.0), ('Dung', 6.8)]
By name length: [('An', 8.5), ('Chi', 9.2), ('Binh', 7.0), ('Dung', 6.8)]

6.3. Lambda with map() and filter()


map() applies a function to every element. filter() keeps elements that satisfy a condition.
map() & filter()
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# map: apply function to each element


squares = list(map(lambda x: x ** 2, numbers))

Page 8
print("Squares:", squares)

# filter: keep elements matching condition


evens = list(filter(lambda x: x % 2 == 0, numbers))
print("Even numbers:", evens)

# Combine: square of even numbers


even_sq = list(map(lambda x: x**2, filter(lambda x: x%2==0, numbers)))
print("Squared evens:", even_sq)

Output:
Squares: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Even numbers: [2, 4, 6, 8, 10]
Squared evens: [4, 16, 36, 64, 100]

Lambda+map vs List comprehension


Both produce the same result:
• list(map(lambda x: x**2, nums)) → lambda style
• [x**2 for x in nums] → list comprehension

List comprehension is generally preferred for readability.


Lambda+map is useful when you already have a function to pass in.

7. Practice with lambda


7.1. Filtering product data
Filter products
products = [
{"name": "Laptop", "price": 15000000, "stock": 5},
{"name": "Mouse", "price": 200000, "stock": 0},
{"name": "Monitor", "price": 5000000, "stock": 12},
{"name": "Keyboard","price": 500000, "stock": 0},
{"name": "Headset", "price": 800000, "stock": 8},
]

# In-stock products
in_stock = list(filter(lambda p: p["stock"] > 0, products))
print("In stock:", [p["name"] for p in in_stock])

# Cheap + available
cheap = list(filter(
lambda p: p["price"] < 1000000 and p["stock"] > 0, products))
print("Cheap + available:", [p["name"] for p in cheap])

Page 9
Output:
In stock: ['Laptop', 'Monitor', 'Headset']
Cheap + available: ['Headset']

7.2. Currency conversion with map()


map() for conversion
prices_usd = [10.5, 25.0, 7.99, 42.0, 15.75]

prices_vnd = list(map(lambda usd: usd * 25000, prices_usd))


formatted = list(map(lambda v: f"{v:,.0f} VND", prices_vnd))
print(formatted)

Output:
['262,500 VND', '625,000 VND', '199,750 VND', '1,050,000 VND', '393,750 VND']

7.3. Scale function


scale() + lambda + map()
def scale(val, src, dst=(-1, 1)):
"""Map value from source range to destination range"""
return (val - src[0]) / (src[1] - src[0]) \
* (dst[1] - dst[0]) + dst[0]

print(scale(49, (-100, 100), (-50, 50))) # 24.5


print(scale(49, (-100, 100))) # 0.49

# Application: normalize scores to 0-1


scores = [65, 80, 45, 92, 73]
normalized = list(map(lambda s: scale(s, (0, 100), (0, 1)), scores))
print([f"{x:.2f}" for x in normalized])

Output:
24.5
0.49
['0.65', '0.80', '0.45', '0.92', '0.73']

Page 10
8. Exercises
Exercise 1:
Requirements
Write and test the following functions:
a) is_even(n) — returns True if n is even
b) count_vowels(text) — counts vowels (a,e,i,o,u) in text
c) celsius_to_all(c) — returns tuple (Fahrenheit, Kelvin)

Exercise 2:
Requirements
Write format_price(amount, currency='VND', decimals=0):
• format_price(1500000) → '1,500,000 VND'
• format_price(49.99, 'USD', 2) → '49.99 USD'

Exercise 3: Sorting
Requirements
products = [("Laptop",15000000), ("Mouse",200000), ("Monitor",5000000)]
Sort using lambda:
a) By price ascending b) By name length descending c) Alphabetically

Exercise 4: Data pipeline


Requirements
Build a mini pipeline with these functions:
1. load_data() — return list of 10 student dicts
2. calculate_averages(data) — add 'avg' key
3. classify_all(data) — add 'grade' key
4. filter_by_grade(data, grade) — filter by classification
5. generate_report(data) — print formatted report

Page 11

You might also like