Skip to content
This repository was archived by the owner on Feb 27, 2026. It is now read-only.

Commit 2c63cfb

Browse files
Merge branch 'main' into edit-user-persona
2 parents 6ed0dde + ce2dc13 commit 2c63cfb

6 files changed

Lines changed: 595 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
Title: 'join()'
3+
Description: 'Combines columns from another DataFrame into the calling DataFrame based on the index or a key column.'
4+
Subjects:
5+
- 'Code Foundations'
6+
- 'Computer Science'
7+
Tags:
8+
- 'DataFrame'
9+
- 'Join'
10+
- 'Pandas'
11+
- 'Python'
12+
CatalogContent:
13+
- 'learn-python-3'
14+
- 'paths/computer-science'
15+
---
16+
17+
In Pandas, **`DataFrame.join()`** combines columns from another DataFrame (or multiple DataFrames) into the calling DataFrame based on the index or a key column. It’s mainly used for merging DataFrames with different sets of columns but shared row indices.
18+
19+
## Syntax
20+
21+
```pseudo
22+
DataFrame.join(other, on=None, how='left', lsuffix='', rsuffix='', sort=False, validate=None)
23+
```
24+
25+
**Parameters:**
26+
27+
- `other`: Objects to join with the caller DataFrame.
28+
- `on`: Column(s) in the caller DataFrame to join on; must match the index in `other` if provided.
29+
- `how`: Type of join to perform — 'left', 'right', 'outer', or 'inner'.
30+
- `lsuffix`: Suffix to add to overlapping column names from the left DataFrame.
31+
- `rsuffix`: Suffix to add to overlapping column names from the right DataFrame.
32+
- `sort`: Sort the result DataFrame by the join keys if True.
33+
- `validate`: Checks if the join is of a specific type ('one_to_one', 'one_to_many', 'many_to_one', 'many_to_many').
34+
35+
**Return value:**
36+
37+
Returns a new DataFrame with columns of both joined DataFrames combined according to the join logic.
38+
39+
## Example
40+
41+
In this example, a list of words is joined into a single string separated by spaces:
42+
43+
```py
44+
words = ['Codecademy', 'is', 'awesome']
45+
result = ' '.join(words)
46+
print(result)
47+
```
48+
49+
This code produces the following output:
50+
51+
```shell
52+
Codecademy is awesome
53+
```
54+
55+
## Codebyte Example
56+
57+
In this example, a list of characters is joined into a single string separated by commas:
58+
59+
```codebyte/python
60+
print(','.join(['a', 'b', 'c']))
61+
```
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
Title: 'singledispatch()'
3+
Description: 'Turn a function into a single-dispatch generic function, allowing different implementations to be registered based on the type of the first argument.'
4+
Subjects:
5+
- 'Computer Science'
6+
- 'Data Science'
7+
Tags:
8+
- 'Function'
9+
- 'Decorators'
10+
CatalogContent:
11+
- 'learn-python-3'
12+
- 'paths/data-science'
13+
---
14+
15+
In Python, **`functools.singledispatch`** is a [decorator](https://www.codecademy.com/resources/docs/python/decorators) that converts a [function](https://www.codecademy.com/resources/docs/python/functions) into a generic function(a type single function that can perform different actions depending on the data type of the input it receives) with behavior varying by the type of its first argument. It simplifies type-specific logic by allowing separate implementations to be registered instead of relying on multiple [if statements](https://www.codecademy.com/resources/docs/python/conditionals).
16+
17+
## Syntax
18+
19+
The `singledispatch()` function is included in the `functools` [module](https://www.codecademy.com/resources/docs/python/functools-module):
20+
21+
```py
22+
@functools.singledispatch
23+
def func(arg, ...):
24+
...
25+
```
26+
27+
**Parameters:**
28+
29+
- Takes a single callable (function) as the argument when used as a decorator.
30+
- The decorated function must accept at least one argument (the one whose type determines dispatch).
31+
32+
**Return value:**
33+
34+
- `singledispatch()` returns a single-dispatch generic function object.
35+
- Additional implementations can be registered for different types using the .register(type) method on the generic function.
36+
37+
## Example 1: Creat a generic function `process`
38+
39+
This example uses the `singledispatch` decorator to handle different input types in a custom way:
40+
41+
```py
42+
from functools import singledispatch
43+
44+
@singledispatch
45+
def process(value):
46+
print("Processing:", value)
47+
48+
@process.register(int)
49+
def _(value):
50+
print("Processing an integer:", value)
51+
52+
@process.register(str)
53+
def _(value):
54+
print("Processing a string:", value)
55+
56+
# Function calls
57+
process(10)
58+
process("Hello")
59+
```
60+
61+
Here is the output for this code:
62+
63+
```shell
64+
Processing an integer: 10
65+
Processing a string: Hello
66+
```
67+
68+
## Codebyte Example: Basic type-based greeting
69+
70+
This minimal example shows how `singledispatch()` changes behavior based on the type of its first argument:
71+
72+
```codebyte/python
73+
from functools import singledispatch
74+
75+
@singledispatch
76+
def greet(value):
77+
print("Hello!")
78+
79+
@greet.register(str)
80+
def _(value):
81+
print(f"Hello, {value}!")
82+
83+
greet("Alice")
84+
greet(42)
85+
```
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
---
2+
Title: 'update_wrapper()'
3+
Description: 'Updates a wrapper function to look like the wrapped function by copying attributes like `__name__`, `__doc__`, and `__module__`.'
4+
Subjects:
5+
- 'Computer Science'
6+
- 'Data Science'
7+
- 'Web Development'
8+
Tags:
9+
- 'Best Practices'
10+
- 'Decorators'
11+
- 'Functions'
12+
- 'Metadata'
13+
CatalogContent:
14+
- 'learn-python-3'
15+
- 'paths/computer-science'
16+
---
17+
18+
The **`update_wrapper()`** function from the `functools` module updates a wrapper function to look like the wrapped function by copying attributes such as `__name__`, `__doc__`, and `__module__`. This is essential for creating decorators that preserve the original function's metadata, making debugging and introspection much easier.
19+
20+
## Syntax
21+
22+
```pseudo
23+
from functools import update_wrapper
24+
25+
update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
26+
```
27+
28+
**Parameters:**
29+
30+
- `wrapper`: The function that is acting as a wrapper (e.g., inside a decorator).
31+
- `wrapped`: The original function being wrapped.
32+
- `assigned`: A tuple of attribute names to copy (defaults to `WRAPPER_ASSIGNMENTS`).
33+
- `updated`: A tuple of attribute names to update (defaults to `WRAPPER_UPDATES`).
34+
35+
**Return value:**
36+
37+
The `update_wrapper()` function returns the `wrapper` function itself, after updating it with the attributes of `wrapped`.
38+
39+
## Example
40+
41+
This example demonstrates how `update_wrapper()` preserves the original function's metadata when creating a decorator:
42+
43+
```py
44+
from functools import update_wrapper
45+
46+
def my_decorator(func):
47+
def wrapper(*args, **kwargs):
48+
print(f"Calling {func.__name__}")
49+
return func(*args, **kwargs)
50+
51+
# Update the wrapper to look like the original function
52+
update_wrapper(wrapper, func)
53+
return wrapper
54+
55+
@my_decorator
56+
def greet(name):
57+
"""A simple greeting function."""
58+
return f"Hello, {name}!"
59+
60+
# Check that metadata is preserved
61+
print(f"Function name: {greet.__name__}")
62+
print(f"Function docstring: {greet.__doc__}")
63+
```
64+
65+
Here is the output:
66+
67+
```shell
68+
Function name: greet
69+
Function docstring: A simple greeting function.
70+
```
71+
72+
## Codebyte Example
73+
74+
This codebyte example shows the difference between using and not using `update_wrapper()`:
75+
76+
```codebyte/python
77+
from functools import update_wrapper
78+
79+
def decorator_without_update(func):
80+
def wrapper(*args, **kwargs):
81+
print(f"Executing {func.__name__}")
82+
return func(*args, **kwargs)
83+
return wrapper
84+
85+
def decorator_with_update(func):
86+
def wrapper(*args, **kwargs):
87+
print(f"Executing {func.__name__}")
88+
return func(*args, **kwargs)
89+
90+
# This preserves the original function's metadata
91+
update_wrapper(wrapper, func)
92+
return wrapper
93+
94+
@decorator_without_update
95+
def function1():
96+
"""This is function1."""
97+
return "Hello from function1"
98+
99+
@decorator_with_update
100+
def function2():
101+
"""This is function2."""
102+
return "Hello from function2"
103+
104+
# Check metadata preservation
105+
print("Without update_wrapper:")
106+
print(f"Name: {function1.__name__}")
107+
print(f"Docstring: {function1.__doc__}")
108+
109+
print("\nWith update_wrapper:")
110+
print(f"Name: {function2.__name__}")
111+
print(f"Docstring: {function2.__doc__}")
112+
113+
# Call the functions
114+
print(f"\nResult: {function1()}")
115+
print(f"Result: {function2()}")
116+
```
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
---
2+
Title: 'Hierarchical Inheritance'
3+
Description: 'Allows multiple subclasses to inherit from the same parent class, enabling shared behavior across different child classes.'
4+
Subjects:
5+
- 'Code Foundations'
6+
- 'Computer Science'
7+
Tags:
8+
- 'Classes'
9+
- 'Inheritance'
10+
- 'OOP'
11+
CatalogContent:
12+
- 'learn-python-3'
13+
- 'paths/computer-science'
14+
---
15+
16+
**Hierarchical inheritance** is a type of [object-oriented programming (OOP)](https://www.codecademy.com/resources/blog/object-oriented-programming) structure where multiple subclasses inherit from a single parent class. Each child class gets access to the shared attributes and methods of the base class, while also defining its own specific behavior.
17+
18+
This approach promotes code reuse and consistency, especially when different classes share core functionality but need their own specialized features.
19+
20+
## Syntax
21+
22+
```pseudo
23+
class Parent:
24+
# Base class with shared behavior
25+
26+
class ChildA(Parent):
27+
# Inherits from Parent
28+
29+
class ChildB(Parent):
30+
# Also inherits from Parent
31+
```
32+
33+
Here:
34+
35+
- `Parent`: The superclass that defines common functionality.
36+
- `ChildA` and `ChildB`: Independent subclasses that derive from the same base.
37+
38+
Each subclass can use the base functionality or override it as needed.
39+
40+
## Example
41+
42+
In this example, `Bird` and `Fish` inherit from the `Animal` class and override the `move()` method to define specific behaviors:
43+
44+
```py
45+
class Animal:
46+
def move(self):
47+
return "Moves in some way"
48+
49+
class Bird(Animal):
50+
def move(self):
51+
return "Flies"
52+
53+
class Fish(Animal):
54+
def move(self):
55+
return "Swims"
56+
57+
b = Bird()
58+
f = Fish()
59+
60+
print(b.move())
61+
print(f.move())
62+
```
63+
64+
The output of this code is:
65+
66+
```shell
67+
Flies
68+
Swims
69+
```
70+
71+
In this code:
72+
73+
- `Bird` and `Fish` both inherit from the `Animal` class.
74+
- The `move()` method is overridden in each subclass to define movement specific to that type of animal.
75+
- This demonstrates how each child can provide its own interpretation of a shared method.
76+
77+
An illustration of how hierarchical inheritance is structured:
78+
79+
```plaintext
80+
+-------------+
81+
| Animal |
82+
|-------------|
83+
| move() |
84+
+------+------+
85+
/ \
86+
▼ ▼
87+
+-------------+ +-------------+
88+
| Bird | | Fish |
89+
|-------------| |-------------|
90+
| move() | | move() |
91+
+-------------+ +-------------+
92+
```
93+
94+
## Codebyte Example
95+
96+
In this example, `Laptop` and `Desktop` inherit shared functionality from the `Device` class while adding their own unique methods:
97+
98+
```codebyte/python
99+
class Device:
100+
def power(self):
101+
return "Powered on"
102+
103+
class Laptop(Device):
104+
def feature(self):
105+
return "Portable computing"
106+
107+
class Desktop(Device):
108+
def feature(self):
109+
return "High-performance workstation"
110+
111+
l = Laptop()
112+
d = Desktop()
113+
114+
print(l.power()) # Inherited from Device
115+
print(l.feature()) # Specific to Laptop
116+
print(d.power()) # Inherited from Device
117+
print(d.feature()) # Specific to Desktop
118+
```
119+
120+
## Benefits of Hierarchical Inheritance
121+
122+
- **Efficient reuse**: Shared logic is centralized in the parent class.
123+
- **Cleaner structure**: Each subclass can focus on its unique behavior.
124+
- **Expandable design**: New types can be introduced without modifying existing code.
125+
126+
> Choose hierarchical inheritance when multiple types share standard features but diverge in implementation.

0 commit comments

Comments
 (0)