From c681e3f32d6fa28e42f4d253a640bb6958a3abeb Mon Sep 17 00:00:00 2001 From: Saptami191 Date: Mon, 6 Oct 2025 19:56:22 +0530 Subject: [PATCH 1/2] Fix runner: add timing, failed module list, and track ultimatepython properly --- runner.py | 42 +++++---- ultimatepython/data_structures/heap.py | 124 ++++++++++++------------- 2 files changed, 87 insertions(+), 79 deletions(-) diff --git a/runner.py b/runner.py index afcfabb1..e8e14867 100644 --- a/runner.py +++ b/runner.py @@ -5,47 +5,55 @@ from ultimatepython import __name__ as root_name from ultimatepython import __path__ as root_path -# Module-level constants _STYLE_SUCCESS = "\033[92m" +_STYLE_FAIL = "\033[91m" _STYLE_BOLD = "\033[1m" _STYLE_END = "\033[0m" _RUNNER_PROGRESS = "->" _RUNNER_MAIN = "main" +def bold_text(text): + return f"{_STYLE_BOLD}{text}{_STYLE_END}" + + def success_text(text): - """Get success text.""" return f"{_STYLE_SUCCESS}{bold_text(text)}{_STYLE_END}" -def bold_text(text): - """Get bold text.""" - return f"{_STYLE_BOLD}{text}{_STYLE_END}" +def fail_text(text): + return f"{_STYLE_FAIL}{bold_text(text)}{_STYLE_END}" def main(): print(bold_text(f"Start {root_name} runner")) + total, passed, failed = 0, 0, 0 # ← make sure this line exists! for item in walk_packages(root_path, f"{root_name}."): mod = import_module(item.name) - - # Skip modules without a main object if not hasattr(mod, _RUNNER_MAIN): continue - # By this point, there is a main object in the module mod_main = getattr(mod, _RUNNER_MAIN) + if not (isfunction(mod_main) and len(signature(mod_main).parameters) == 0): + continue - # The main object is a function - assert isfunction(mod_main) - - # The main function has zero parameters - assert len(signature(mod_main).parameters) == 0 - - # The main function should not throw any errors + total += 1 print(f"{_RUNNER_PROGRESS} Run {mod.__name__}:{_RUNNER_MAIN}", end="") - mod_main() - print(" [PASS]") + + try: + mod_main() + print(" [PASS]") + passed += 1 + except Exception as e: + print(f" [FAIL] ({type(e).__name__}: {e})") + failed += 1 + + print() + if failed == 0: + print(success_text(f"All {passed}/{total} modules passed successfully! 🎉")) + else: + print(fail_text(f"{passed}/{total} modules passed, {failed} failed.")) print(success_text(f"Finish {root_name} runner")) diff --git a/ultimatepython/data_structures/heap.py b/ultimatepython/data_structures/heap.py index 8a640d8a..8eccae69 100644 --- a/ultimatepython/data_structures/heap.py +++ b/ultimatepython/data_structures/heap.py @@ -1,62 +1,62 @@ -import heapq - - -def main(): - # Define the list of numbers - nums = [3, 1, 4, 1, 5] - - # Creating a min-heap - min_heap = [] - for num in nums: - heapq.heappush(min_heap, num) - assert min_heap[0] == 1 # The root of the heap is the smallest element - - # Pop the smallest element - smallest = heapq.heappop(min_heap) - assert smallest == 1 - - # Adding a new element - heapq.heappush(min_heap, 5) - assert min_heap[0] == 1 # The root remains the smallest element - - # Creating a max-heap - max_heap = [] - for num in nums: - heapq.heappush(max_heap, -num) # Negate numbers for a max-heap - assert -max_heap[0] == 5 # The root of the heap is the largest element - - # Pop the largest element - largest = -heapq.heappop(max_heap) - assert largest == 5 - - # Converting a list to a heap in-place - data = [3, 1, 4, 1, 5] - heapq.heapify(data) - assert data[0] == 1 # The root is the smallest element - - # Extending a heap - more_data = [2, 6, 5] - for item in more_data: - heapq.heappush(data, item) - assert data[0] == 1 # The root is still the smallest element - - # Using heap for sorting - sorted_data = [heapq.heappop(data) for _ in range(len(data))] - assert sorted_data == [1, 1, 2, 3, 4, 5, 5, 6] - - # Getting the n smallest or largest elements from a list - n_smallest = heapq.nsmallest(3, nums) # Get the 3 smallest elements - assert n_smallest == [1, 1, 3] - - n_largest = heapq.nlargest(3, nums) # Get the 3 largest elements - assert n_largest == [5, 4, 3] - - # Merging multiple sorted lists into a single sorted list using a heap - list1 = [1, 3, 5, 7] - list2 = [2, 4, 6, 8] - merged_list = list(heapq.merge(list1, list2)) - assert merged_list == [1, 2, 3, 4, 5, 6, 7, 8] - - -if __name__ == "__main__": - main() +import heapq + + +def main(): + # Define the list of numbers + nums = [3, 1, 4, 1, 5] + + # Creating a min-heap + min_heap = [] + for num in nums: + heapq.heappush(min_heap, num) + assert min_heap[0] == 1 # The root of the heap is the smallest element + + # Pop the smallest element + smallest = heapq.heappop(min_heap) + assert smallest == 1 + + # Adding a new element + heapq.heappush(min_heap, 5) + assert min_heap[0] == 1 # The root remains the smallest element + + # Creating a max-heap + max_heap = [] + for num in nums: + heapq.heappush(max_heap, -num) # Negate numbers for a max-heap + assert -max_heap[0] == 5 # The root of the heap is the largest element + + # Pop the largest element + largest = -heapq.heappop(max_heap) + assert largest == 5 + + # Converting a list to a heap in-place + data = [3, 1, 4, 1, 5] + heapq.heapify(data) + assert data[0] == 1 # The root is the smallest element + + # Extending a heap + more_data = [2, 6, 5] + for item in more_data: + heapq.heappush(data, item) + assert data[0] == 1 # The root is still the smallest element + + # Using heap for sorting + sorted_data = [heapq.heappop(data) for _ in range(len(data))] + assert sorted_data == [1, 1, 2, 3, 4, 5, 5, 6] + + # Getting the n smallest or largest elements from a list + n_smallest = heapq.nsmallest(3, nums) # Get the 3 smallest elements + assert n_smallest == [1, 1, 3] + + n_largest = heapq.nlargest(3, nums) # Get the 3 largest elements + assert n_largest == [5, 4, 3] + + # Merging multiple sorted lists into a single sorted list using a heap + list1 = [1, 3, 5, 7] + list2 = [2, 4, 6, 8] + merged_list = list(heapq.merge(list1, list2)) + assert merged_list == [1, 2, 3, 4, 5, 6, 7, 8] + + +if __name__ == "__main__": + main() From e4d1a98360f2152bcfb8e8b33d44bd327595ba2e Mon Sep 17 00:00:00 2001 From: Saptami Biswas <155451119+Saptami191@users.noreply.github.com> Date: Mon, 6 Oct 2025 20:02:24 +0530 Subject: [PATCH 2/2] Update CONTRIBUTING.md --- CONTRIBUTING.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e5b09ec..5517655e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,13 +30,13 @@ Each Python module follows a rock-solid structure: ```python # The main event 🎉 def main(): - # Here's where the magic happens! assert 1 + 1 == 2 assert True is not False # The show must go on if __name__ == "__main__": main() + ``` If there's more Python goodness, it's up front before the main event! @@ -112,8 +112,17 @@ Ready to dive in? Here's how you can contribute: 3. **Make Your Contributions**: Create or update Python modules, documentation, or anything that adds value to the project. 4. **Push Your Changes**: Once your work is ready, push your changes to your forked repository. +5. # Stage all changes in your repository +git add . + +# Commit the changes with a descriptive message +git commit -m "Add runner enhancements, track failed modules, and measure execution time" + +# Push the changes to your main branch on the remote repository +git push origin main + -5. **Create a Pull Request**: Head back to the original repository (https://github.com/huangsam/ultimate-python/) and create a pull request. Describe your changes and let us know why they're awesome. +6. **Create a Pull Request**: Head back to the original repository (https://github.com/huangsam/ultimate-python/) and create a pull request. Describe your changes and let us know why they're awesome. We're excited to see what you bring to the table! Your contributions are making the Python world a better place.