Metadata-Version: 2.4
Name: jugaadcode
Version: 0.1.15
Summary: A Python library for common programming logic and algorithms
Author: Mohamed Faraazman Bin Farooq S, Surya Deepta
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# jugaadcode 🐍

**A beginner-friendly Python library for coding logic, algorithms, and interview preparation.**

`jugaadcode` is a Python library containing commonly used programming problems and algorithm implementations. It is designed for students, beginners, developers, and anyone preparing for coding interviews.

Solve common programming problems with simple Python function calls instead of rewriting the logic every time.

## Features

- Common number-based programming problems
- String manipulation and character operations
- Array and list operations
- Searching and sorting algorithms
- Mathematical algorithms
- Dynamic programming problems
- Matrix operations
- Linked-list algorithms
- Interactive input support for functions that accept optional arguments
- Individual Python modules for individual algorithms
- Simple function-based API

## Installation

Install the latest version from PyPI:

```bash
python -m pip install jugaadcode
```

Upgrade to the latest version:

```bash
python -m pip install --upgrade jugaadcode
```

## Basic Usage

Import the library:

```python
import jugaadcode
```

Call a function by passing its required arguments:

```python
print(jugaadcode.is_prime(17))
print(jugaadcode.factorial(5))
print(jugaadcode.is_armstrong(153))
```

Example output:

```text
True
120
True
```

You can also import individual functions:

```python
from jugaadcode import is_prime, factorial, fibonacci

print(is_prime(17))
print(factorial(5))
print(fibonacci(7))
```

## Interactive Input

Functions that support optional arguments can prompt you for input when called without those arguments.

```python
import jugaadcode

result = jugaadcode.factorial()
print(result)
```

The function prompts you to enter a number.

You can also pass a number directly:

```python
print(jugaadcode.factorial(5))
```

**Note:** Interactive input is available only for functions implemented to support it. Check each function's arguments before calling it without parameters.

---

# 1. Number Algorithms

These functions solve common mathematical and number-based programming problems.

| Function | Description | Example |
|---|---|---|
| `is_prime(n)` | Checks whether a number is prime | `jugaadcode.is_prime(17)` |
| `factorial(n)` | Calculates the factorial of a number | `jugaadcode.factorial(5)` |
| `fibonacci(n)` | Generates Fibonacci numbers | `jugaadcode.fibonacci(7)` |
| `is_palindrome(n)` | Checks whether a number is a palindrome | `jugaadcode.is_palindrome(121)` |
| `is_armstrong(n)` | Checks whether a number is an Armstrong number | `jugaadcode.is_armstrong(153)` |
| `reverse_number(n)` | Reverses the digits of a number | `jugaadcode.reverse_number(1234)` |
| `sum_of_digits(n)` | Calculates the sum of a number's digits | `jugaadcode.sum_of_digits(1234)` |
| `is_perfect_number(n)` | Checks whether a number is perfect | `jugaadcode.is_perfect_number(28)` |
| `is_strong_number(n)` | Checks whether a number is a strong number | `jugaadcode.is_strong_number(145)` |
| `is_harshad_number(n)` | Checks whether a number is divisible by its digit sum | `jugaadcode.is_harshad_number(18)` |
| `gcd(a, b)` | Finds the greatest common divisor | `jugaadcode.gcd(12, 18)` |
| `lcm(a, b)` | Finds the least common multiple | `jugaadcode.lcm(12, 18)` |
| `is_even(n)` | Checks whether a number is even | `jugaadcode.is_even(8)` |
| `power(base, exponent)` | Calculates a power | `jugaadcode.power(2, 3)` |
| `trailing_zeros(n)` | Counts trailing zeros in `n!` | `jugaadcode.trailing_zeros(100)` |
| `factorial_with_trailing_zeros(k)` | Finds a number whose factorial has a specified number of trailing zeros | `jugaadcode.factorial_with_trailing_zeros(3)` |
| `factorial_trailing_zeros_direct(n)` | Calculates the factorial and counts its trailing zeros | `jugaadcode.factorial_trailing_zeros_direct(10)` |

### Examples

```python
import jugaadcode

print(jugaadcode.is_prime(17))          # True
print(jugaadcode.factorial(5))          # 120
print(jugaadcode.is_palindrome(121))    # True
print(jugaadcode.is_armstrong(153))     # True
print(jugaadcode.reverse_number(1234))  # 4321
print(jugaadcode.sum_of_digits(1234))   # 10
print(jugaadcode.gcd(12, 18))           # 6
print(jugaadcode.lcm(12, 18))           # 36
print(jugaadcode.is_even(8))            # True
print(jugaadcode.power(2, 3))           # 8
print(jugaadcode.trailing_zeros(100))   # 24
```

---

# 2. String Algorithms

These functions perform common string-processing operations.

| Function | Description | Example |
|---|---|---|
| `reverse_string(text)` | Reverses a string | `jugaadcode.reverse_string("hello")` |
| `count_vowels(text)` | Counts vowels in a string | `jugaadcode.count_vowels("education")` |
| `character_frequency(text)` | Counts character occurrences | `jugaadcode.character_frequency("banana")` |
| `is_anagram(first, second)` | Checks whether two strings are anagrams | `jugaadcode.is_anagram("listen", "silent")` |
| `remove_duplicate_characters(text)` | Removes repeated characters | `jugaadcode.remove_duplicate_characters("banana")` |
| `first_non_repeating(text)` | Finds the first non-repeating character | `jugaadcode.first_non_repeating("swiss")` |
| `word_count(text)` | Counts words in a string | `jugaadcode.word_count("Python is easy")` |
| `capitalize_words(text)` | Capitalizes words in a string | `jugaadcode.capitalize_words("hello world")` |
| `longest_word(text)` | Finds the longest word in a sentence | `jugaadcode.longest_word("Python makes coding fun")` |
| `is_subsequence(first, second)` | Checks whether one string is a subsequence of another | `jugaadcode.is_subsequence("ace", "abcde")` |

### Examples

```python
import jugaadcode

print(jugaadcode.reverse_string("hello"))
print(jugaadcode.count_vowels("education"))
print(jugaadcode.is_anagram("listen", "silent"))
print(jugaadcode.remove_duplicate_characters("banana"))
print(jugaadcode.first_non_repeating("swiss"))
print(jugaadcode.word_count("Python is easy"))
print(jugaadcode.capitalize_words("hello world"))
print(jugaadcode.longest_word("Python makes coding fun"))
print(jugaadcode.is_subsequence("ace", "abcde"))
```

Example results depend on each function's implementation and input-handling rules.

---

# 3. Array and List Algorithms

These functions work with Python lists and sequences.

| Function | Description | Example |
|---|---|---|
| `find_max(numbers)` | Finds the largest value | `jugaadcode.find_max([3, 8, 2])` |
| `find_min(numbers)` | Finds the smallest value | `jugaadcode.find_min([3, 8, 2])` |
| `second_largest(numbers)` | Finds the second-largest value | `jugaadcode.second_largest([10, 5, 8, 3])` |
| `remove_duplicates(numbers)` | Removes duplicate elements | `jugaadcode.remove_duplicates([1, 2, 2, 3])` |
| `find_missing_number(numbers)` | Finds a missing number | `jugaadcode.find_missing_number([1, 2, 4, 5])` |
| `find_duplicate(numbers)` | Finds a duplicate number | `jugaadcode.find_duplicate([1, 2, 3, 2])` |
| `rotate_left(numbers, k)` | Rotates a list to the left | `jugaadcode.rotate_left([1, 2, 3, 4, 5], 2)` |
| `rotate_right(numbers, k)` | Rotates a list to the right | `jugaadcode.rotate_right([1, 2, 3, 4, 5], 2)` |
| `two_sum(numbers, target)` | Finds two elements that add up to a target | `jugaadcode.two_sum([2, 7, 11, 15], 9)` |
| `move_zeros(numbers)` | Moves zeros within a list | `jugaadcode.move_zeros([0, 1, 0, 3, 12])` |
| `kth_largest(numbers, k)` | Finds the kth-largest element | `jugaadcode.kth_largest([3, 2, 1, 5, 4], 2)` |
| `maximum_subarray(numbers)` | Finds the maximum-sum contiguous subarray result | `jugaadcode.maximum_subarray([-2, 1, -3, 4, -1, 2, 1])` |
| `longest_consecutive(numbers)` | Finds the longest consecutive sequence length or result | `jugaadcode.longest_consecutive([100, 4, 200, 1, 3, 2])` |
| `pair_with_difference(numbers, difference)` | Finds a pair with a specified difference | `jugaadcode.pair_with_difference([1, 5, 3, 4, 2], 2)` |

### Examples

```python
import jugaadcode

print(jugaadcode.find_max([3, 8, 2]))
print(jugaadcode.find_min([3, 8, 2]))
print(jugaadcode.second_largest([10, 5, 8, 3]))
print(jugaadcode.remove_duplicates([1, 2, 2, 3]))
print(jugaadcode.two_sum([2, 7, 11, 15], 9))
print(jugaadcode.move_zeros([0, 1, 0, 3, 12]))
print(jugaadcode.kth_largest([3, 2, 1, 5, 4], 2))
```

**Important:** Input requirements vary. For example, binary search requires sorted input, and some array algorithms require non-empty lists or specific input formats.

---

# 4. Searching Algorithms

| Function | Description | Example |
|---|---|---|
| `linear_search(numbers, target)` | Searches sequentially for a target | `jugaadcode.linear_search([10, 20, 30], 20)` |
| `binary_search(numbers, target)` | Searches a sorted list efficiently | `jugaadcode.binary_search([10, 20, 30, 40], 30)` |

### Example

```python
import jugaadcode

numbers = [10, 20, 30, 40, 50]

print(jugaadcode.linear_search(numbers, 30))
print(jugaadcode.binary_search(numbers, 30))
```

**Note:** The list passed to `binary_search()` must be sorted in ascending order unless the implementation specifies otherwise.

---

# 5. Sorting Algorithms

| Function | Description | Example |
|---|---|---|
| `bubble_sort(numbers)` | Sorts by repeatedly swapping adjacent elements | `jugaadcode.bubble_sort([5, 2, 4, 1])` |
| `selection_sort(numbers)` | Sorts by repeatedly selecting the next smallest element | `jugaadcode.selection_sort([5, 2, 4, 1])` |
| `insertion_sort(numbers)` | Sorts by inserting elements into their correct positions | `jugaadcode.insertion_sort([5, 2, 4, 1])` |
| `merge_sort(numbers)` | Sorts using divide and conquer | `jugaadcode.merge_sort([5, 2, 4, 1])` |
| `quick_sort(numbers)` | Sorts using partitioning and divide and conquer | `jugaadcode.quick_sort([5, 2, 4, 1])` |
| `counting_sort(numbers)` | Sorts integers using value frequencies | `jugaadcode.counting_sort([4, 2, 2, 1, 3])` |

### Example

```python
import jugaadcode

numbers = [5, 2, 4, 1, 3]

print(jugaadcode.bubble_sort(numbers))
print(jugaadcode.selection_sort(numbers))
print(jugaadcode.insertion_sort(numbers))
print(jugaadcode.merge_sort(numbers))
print(jugaadcode.quick_sort(numbers))
print(jugaadcode.counting_sort(numbers))
```

Check whether a sorting function modifies the original list or returns a new list before relying on that behavior.

---

# 6. Dynamic Programming Algorithms

Dynamic programming helps solve problems by reusing results from smaller subproblems.

| Function | Description | Example |
|---|---|---|
| `climbing_stairs(n)` | Calculates the number of ways to climb stairs | `jugaadcode.climbing_stairs(5)` |
| `coin_change(coins, amount)` | Solves a coin-change problem | `jugaadcode.coin_change([1, 2, 5], 11)` |

### Examples

```python
import jugaadcode

print(jugaadcode.climbing_stairs(5))
print(jugaadcode.coin_change([1, 2, 5], 11))
```

The exact result and interpretation depend on each implementation's definition of the problem—for example, whether `coin_change()` returns the minimum number of coins or another representation.

---

# 7. Stack, Matrix, and Linked-List Algorithms

| Function | Description | Example |
|---|---|---|
| `valid_parentheses(text)` | Checks whether brackets are properly matched | `jugaadcode.valid_parentheses("({[]})")` |
| `matrix_transpose(matrix)` | Transposes a matrix | `jugaadcode.matrix_transpose([[1, 2], [3, 4]])` |
| `reverse_linked_list(head)` | Reverses a linked list | `jugaadcode.reverse_linked_list(head)` |

### Examples

```python
import jugaadcode

print(jugaadcode.valid_parentheses("({[]})"))
print(jugaadcode.matrix_transpose([[1, 2], [3, 4]]))
```

For `reverse_linked_list()`, the input must match the linked-list node structure expected by the implementation. Refer to the function's module for the required node format.

---

# 8. Using Individual Modules

Each algorithm is maintained in its own Python module. You can import functions through the main package or import from the specific module.

### Through the main package

```python
import jugaadcode

print(jugaadcode.is_prime(17))
```

### Through an individual module

```python
from jugaadcode.prime import is_prime

print(is_prime(17))
```

Other module examples:

```python
from jugaadcode.factorial import factorial
from jugaadcode.fibonacci import fibonacci
from jugaadcode.two_sum import two_sum
from jugaadcode.binary_search import binary_search
from jugaadcode.bubble_sort import bubble_sort
```

Individual module imports can be useful when you want to work with only one algorithm.

---

# 9. Error Handling

Some functions reject invalid input, such as negative values for factorial or trailing-zero calculations.

You can handle errors using `try` and `except`:

```python
import jugaadcode

try:
    result = jugaadcode.factorial(-5)
    print(result)
except ValueError as error:
    print("Invalid input:", error)
```

Always check the relevant function implementation for its supported input types, constraints, and error behavior.

---

# 10. Requirements

- Python 3.9 or later
- No additional dependencies are required for the basic algorithms, provided the package implementation remains dependency-free.

# 11. Version

Current release: **0.1.9** 

# 12. Author

**Mohamed Faraazman Bin Farooq S**

## Co-author
**Surya Deepta Mazumdar**

---

**Install `jugaadcode`, import the algorithms you need, and focus on solving problems rather than rewriting common logic.**
