Contributing to the Community: Hacktoberfest PR #1
Tags: opensource, beginners, git, python
Published: 2023-10-03 07:10:52

## October!!
It's October which means Thanksgiving and Halloween are right around the corner! Well, I guess it also means Hacktoberfest has officially begun too... 

*ahem*

Moving on... This is my first Hacktoberfest ever! I'm feeling a weird mixture of anxiety and an untamable drive to do some really awesome stuff this October. However, I know myself very well and how addicted I can get to problems that are far outside of my skill range, so I settled for a minor but unique [issue](https://github.com/bhargavnova/python-helper-modules/issues/21) to tackle for my first [PR](https://github.com/bhargavnova/python-helper-modules/pull/22).

## What was the issue about?
The issue requested a Python module to be built with the following capabilities. 

1. Function Runtime Measurement:
    * Print the runtime of a function
1. Script Runtime Measurement:
    * Measure the overall runtime of a script
1. User-Friendly Output:
    * Ensure the output is human-readable

I've done something similar to this a very long time ago, although it was done in C++, so I figured I would give it a shot in Python this time around.

## The process
I started out by making a class called `runtime_calculator` so that I could contain all the necessary functions and class features that would be required for the module. 

I then had to do some research on the `time` library, which proved to be extremely useful. I learned all about `time.time()` built-in function and how to manipulate it for what I was looking to implement. It also allowed me to look into wrappers and decorators in Python, 2 very powerful tools that allowed my module to really shine!

The bread and butter of the module is the `measure_runtime()` function: 
```python
def measure_runtime(func):
    """A decorator function that measures the runtime of a given function"""
    def wrapper(*args, **kwargs):
        calculator.start()
        result = func(*args, **kwargs)
        runtime = calculator.stop()
        print(f"Function {func.__name__} took {runtime: .2f} seconds to run.")
        return result
    return wrapper
```
This allows for the timer to be started and then a function to promptly be timed as it runs, finally printing the runtime to the console. 

Figuring out the script runtime was a little different as it required the timer to start as soon as the script ran. I ended up finding a fix for it by setting the starting time to a variable at the class initialization and calling a function to grab the final time before the script stopped.

## Sending the PR
The pull request was sent and promptly verified for merging into the repo. I was very happy that I was able to do it right the first time because I spent a lot of time debugging everything and making sure it was up to spec. The maintainer of the repo was very kind and was a great intro to how helpful and kind the open-source community is.

## Learning outcomes
Decorators are something I've very loosely used, along with wrappers, which is why being able to really understand them in a brand-new setting was quite a refreshing experience. The experience using such powerful concepts is priceless as they've shown me a lot of what Python has to offer in terms of modularity. I love the fact that you can just cast a function into the form of a variable and simply run the function within the decorator. Even with such a small code addition, it feels like I've levelled up my knowledge of Python.