Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Week02/types_furkan_bulut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
my_int = 2
my_float = 1.03
my_bool = True
my_complex = 6j
34 changes: 34 additions & 0 deletions Week03/pyramid_furkan_bulut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
def calculate_pyramid_height(number_of_blocks):
"""
Calculate the height of a pyramid that can be built with a given number of blocks.

The function determines how many complete layers (height) can be formed
using the provided number of blocks. Each layer requires a number of blocks
equal to the layer number (1 block for the first layer, 2 blocks for the
second layer, etc.).

:param number_of_blocks: The total number of blocks available to build the pyramid.
:type number_of_blocks: int
:return: The maximum height of the pyramid that can be built.
:rtype: int

:raises ValueError: If `number_of_blocks` is less than 0.

Example:

calculate_pyramid_height(6)
3
calculate_pyramid_height(20)
5
"""
if number_of_blocks < 0:
raise ValueError("Number of blocks must be non-negative.")

height_of_pyramid = 0
block_counter = 0

while number_of_blocks >= (block_counter + (height_of_pyramid + 1)):
block_counter += height_of_pyramid + 1
height_of_pyramid += 1

return height_of_pyramid
17 changes: 17 additions & 0 deletions Week03/sequences_furkan_bulut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
def remove_duplicates(seq: list) -> list:
"""
This function removes duplicates from a list.
"""
return list(set(seq))

def list_counts(seq: list) -> dict:
"""
This function counts the number of occurrences of each item in a list.
"""
return {i: seq.count(i) for i in seq}

def reverse_dict(d: dict) -> dict:
"""
This function reverses the keys and values of a dictionary.
"""
return {v: k for k, v in d.items()}
81 changes: 81 additions & 0 deletions Week04/decorators_furkan_bulut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import time
import tracemalloc

def performance(fn):
"""
Decorator to measure performance metrics of a function.

This decorator tracks the execution time and memory usage of the decorated
function, printing the results after each call.

:param fn: The function to be decorated.
:returns: A wrapped function that tracks performance metrics.
:raises Exception: If an error occurs during the execution of the decorated function.
"""

setattr(performance, 'counter', 0)
setattr(performance, 'total_time', 0.0)
setattr(performance, 'total_mem', 0.0)

def _performance(*args, **kwargs):
"""
Wrapper function that measures execution time and memory usage.

:param args: Positional arguments to be passed to the decorated function.
:param kwargs: Keyword arguments to be passed to the decorated function.
"""
counter = getattr(performance, 'counter')
total_time = getattr(performance, 'total_time')
total_mem = getattr(performance, 'total_mem')

counter += 1
setattr(performance, 'counter', counter)

tracemalloc.start()
start_time = time.time()

try:
fn(*args, **kwargs)
except Exception as e:
print(f"Error occurred: {e}")
finally:
end_time = time.time()
current, peak = tracemalloc.get_traced_memory()
tracemalloc.stop()

elapsed_time = end_time - start_time
memory_usage = peak

total_time += elapsed_time
total_mem += memory_usage

setattr(performance, 'total_time', total_time)
setattr(performance, 'total_mem', total_mem)

print_results(fn.__name__, elapsed_time, memory_usage, counter, total_time, total_mem)

return _performance

def print_results(func_name, elapsed_time, memory_usage, counter, total_time, total_mem):
"""
Display the performance results of the decorated function.

This function prints the name of the function being measured, the elapsed time,
memory usage, and the total statistics over all calls.

:param func_name: The name of the function being measured.
:param elapsed_time: The time taken for the function to execute, in seconds.
:param memory_usage: The peak memory usage during the function execution, in bytes.
:param counter: Number of times the decorated function has been called.
:param total_time: Total execution time of the decorated function.
:param total_mem: Total peak memory usage of the decorated function.
"""
results = (
f"Function Name: {func_name}\n"
f"Number of Calls: {counter}\n"
f"Elapsed Time: {elapsed_time:.6f} seconds\n"
f"Memory Usage: {memory_usage / 1024:.2f} KB\n"
f"Total Time: {total_time:.6f} seconds\n"
f"Total Memory Usage: {total_mem / 1024:.2f} KB\n"
)
print(results)
86 changes: 86 additions & 0 deletions Week04/functions_furkan_bulut.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
custom_power = lambda x=0, /, e=1: x ** e

def custom_equation(x: int = 0, y: int = 0, /, a: int = 1, b: int = 1, *, c: int = 1) -> float:
"""
Calculate a custom equation based on the parameters provided.

This function computes the result of the equation:
(x^a + y^b) / c, where:
- `x` and `y` are the bases for exponentiation.
- `a` and `b` are the exponents for `x` and `y`, respectively.
- `c` serves as the divisor, which cannot be zero.

:param x:
The base for exponentiation (positional only). Default is 0.

:param y:
The base for exponentiation (positional only). Default is 0.

:param a:
The exponent for `x` (positional or keyword). Default is 1.
This defines the power to which `x` is raised.

:param b:
The exponent for `y` (positional or keyword). Default is 1.
This defines the power to which `y` is raised.

:param c:
A keyword-only parameter representing the divisor. Default is 1.
If set to zero, a division by zero exception is raised.

:raises ValueError:
If `c` is zero, a `ValueError` is raised indicating that division by zero
is not allowed.

:returns:
The result of the equation (x^a + y^b) / c.
This will return a float value representing the computed result.

:example:

#>>> custom_equation(2, 3, a=2, b=2, c=1)
13.0
#>>> custom_equation(2, 3, a=2, b=2, c=0)
Traceback (most recent call last):
...
ValueError: Division by Zero Exception
"""
if c == 0:
raise ValueError("Division by Zero Exception")

return (x ** a + y ** b) / c

def fn_w_counter() -> (int, dict[str, int]):
"""
A function that counts how many times it has been called and tracks callers.

Each time this function is invoked, it increments a call counter and logs
the name of the caller (the module name). This can be useful for debugging
purposes or monitoring how frequently this function is used in different
parts of the application.

:returns:
A tuple containing:
- The total number of times the function has been called across all instances.
- A dictionary mapping caller names (module names) to the number of times
they have invoked this function.

:example:

#>>> fn_w_counter()
(1, {'__main__': 1})
#>>> fn_w_counter()
(2, {'__main__': 2})
"""
if not hasattr(fn_w_counter, 'call_count'):
fn_w_counter.call_count = 0
fn_w_counter.callers = {}
fn_w_counter.call_count += 1

caller_name = __name__

if caller_name in fn_w_counter.callers:
fn_w_counter.callers[caller_name] += 1
else:
fn_w_counter.callers[caller_name] = 1
return fn_w_counter.call_count, fn_w_counter.callers