Skip to content

Commit

Permalink
Merge branch 'main' into Zoshans1
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoshan22 authored Jan 13, 2025
2 parents 48c2be6 + a08a291 commit d17359f
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 2 deletions.
6 changes: 4 additions & 2 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ about: A template PR for code review with a checklist

- [ ] The function's name describes it's behavior
- [ ] The function's name matches the file name
- _It's ok to have extra helper functions if necessary, like with mergesort_
- [ ] The function has correct type annotations
- [ ] The function is not called in the function file
- [ ] The function is not called at the top level of the function file
- _Recursive solutions **can** call the function from **inside** the function body_

## Strategy

Expand All @@ -67,7 +69,7 @@ about: A template PR for code review with a checklist

### Don'ts

- [ ] The function's strategy _is not_ described in the documentation
- [ ] The function's strategy _is not_ described in any docstrings or tests
- [ ] Comments explain the _strategy_, **not** the _implementation_
- [ ] The function _does not_ have more comments than code
- If it does, consider finding a new strategy or a simpler implementation
Expand Down
54 changes: 54 additions & 0 deletions solutions/pine_tree_art.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""
Module for generating and displaying ASCII art of a pine tree.
This module provides a function to create a visual representation of a pine tree
with customizable height and trunk dimensions.
Author: fevziismailsahin
Created: 01/09/2025
"""


def pine_tree_art(height: int = 10, trunk_width: int = 3, trunk_height: int = 3) -> str:
"""
Generate an ASCII art representation of a pine tree.
Parameters:
height (int): The height of the tree (default is 10).
trunk_width (int): The width of the tree trunk (default is 3).
trunk_height (int): The height of the tree trunk (default is 3).
Returns:
str: The generated ASCII art as a string.
"""

# Type checks
if (
not isinstance(height, int)
or not isinstance(trunk_width, int)
or not isinstance(trunk_height, int)
):
raise TypeError("Height, trunk_width, and trunk_height must be integers")

# Defensive assertions
if height <= 0:
raise ValueError("Height must be a positive integer")
if trunk_width <= 0:
raise ValueError("Trunk width must be a positive integer")
if trunk_height <= 0:
raise ValueError("Trunk height must be a positive integer")

# Create the foliage of the tree
tree = []
for i in range(height):
spaces = " " * (height - i - 1) # Add spaces for alignment (center the stars)
stars = "*" * (2 * i + 1) # Create the stars for the current level
tree.append(spaces + stars) # Append to tree list with correct alignment

# Create the trunk of the tree
trunk = " " * (height - trunk_width // 2 - 1) + "|" * trunk_width # Centered trunk
for _ in range(trunk_height):
tree.append(trunk)

# Return the tree as a single string with an extra newline at the end
return "\n".join(tree) + "\n"
84 changes: 84 additions & 0 deletions solutions/tests/test_pine_tree_art.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Unit test module for generating ASCII art of a pine tree.
Test categories:
- Standard cases: correct inputs for height, trunk_width, trunk_height;
- Edge cases;
- Defensive tests: wrong input types, assertions;
Created on 2025-01-11
Author: fevziismailsahin
"""

import unittest

from ..pine_tree_art import pine_tree_art


class TestPineTreeArt(unittest.TestCase):
"""Test suite for generating ASCII art of a pine tree."""

# Standard cases: correct inputs
def test_standard_case_1(self):
"""Test with typical valid inputs for height, trunk_width, trunk_height."""
expected_result = (
" *\n"
" ***\n"
" *****\n"
" *******\n"
" *********\n"
" ***********\n"
" *************\n"
" ***************\n"
" *****************\n"
"*******************\n"
" |||\n"
" |||\n"
" |||\n"
)
self.assertEqual(pine_tree_art(10, 3, 3), expected_result)

def test_standard_case_2(self):
"""Test with smaller tree height and trunk dimensions."""
expected_result = (
" *\n ***\n *****\n *******\n*********\n |||\n |||\n |||\n"
)
self.assertEqual(pine_tree_art(5, 3, 3), expected_result)

# Edge cases: testing zero or near-zero values
def test_zero_height(self):
"""Test when height is zero, which should raise a ValueError."""
with self.assertRaises(ValueError):
pine_tree_art(0, 3, 3)

def test_zero_trunk_width(self):
"""Test when trunk width is zero, which should raise a ValueError."""
with self.assertRaises(ValueError):
pine_tree_art(10, 0, 3)

def test_zero_trunk_height(self):
"""Test when trunk height is zero, which should raise a ValueError."""
with self.assertRaises(ValueError):
pine_tree_art(10, 3, 0)

# Defensive tests: wrong input types, assertions
def test_invalid_height_type(self):
"""Test when 'height' is not an integer, which should raise a TypeError."""
with self.assertRaises(TypeError):
pine_tree_art("ten", 3, 3)

def test_invalid_trunk_width_type(self):
"""Test when 'trunk_width' is not an integer, which should raise a TypeError."""
with self.assertRaises(TypeError):
pine_tree_art(10, "three", 3)

def test_invalid_trunk_height_type(self):
"""Test when 'trunk_height' is not an integer, which should raise a TypeError."""
with self.assertRaises(TypeError):
pine_tree_art(10, 3, "three")


if __name__ == "__main__":
unittest.main()

0 comments on commit d17359f

Please sign in to comment.