jugaadcode 0.1.10__tar.gz → 0.1.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/PKG-INFO +1 -1
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/pyproject.toml +1 -1
- jugaadcode-0.1.11/src/jugaadcode/anagram.py +115 -0
- jugaadcode-0.1.11/src/jugaadcode/armstrong.py +93 -0
- jugaadcode-0.1.11/src/jugaadcode/binary_search.py +119 -0
- jugaadcode-0.1.11/src/jugaadcode/bubble_sort.py +94 -0
- jugaadcode-0.1.11/src/jugaadcode/capitalize_words.py +77 -0
- jugaadcode-0.1.11/src/jugaadcode/character_frequency.py +85 -0
- jugaadcode-0.1.11/src/jugaadcode/climbing_stairs.py +104 -0
- jugaadcode-0.1.11/src/jugaadcode/coin_change.py +122 -0
- jugaadcode-0.1.11/src/jugaadcode/count_vowels.py +70 -0
- jugaadcode-0.1.11/src/jugaadcode/counting_sort.py +100 -0
- jugaadcode-0.1.11/src/jugaadcode/duplicate_number.py +71 -0
- jugaadcode-0.1.11/src/jugaadcode/even_odd.py +74 -0
- jugaadcode-0.1.11/src/jugaadcode/factorial.py +78 -0
- jugaadcode-0.1.11/src/jugaadcode/factorial_trailing_zeros_direct.py +81 -0
- jugaadcode-0.1.11/src/jugaadcode/factorial_with_trailing_zeros.py +71 -0
- jugaadcode-0.1.11/src/jugaadcode/fibonacci.py +82 -0
- jugaadcode-0.1.11/src/jugaadcode/find_max.py +75 -0
- jugaadcode-0.1.11/src/jugaadcode/find_min.py +82 -0
- jugaadcode-0.1.11/src/jugaadcode/first_non_repeating.py +91 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode.egg-info/PKG-INFO +1 -1
- jugaadcode-0.1.10/src/jugaadcode/anagram.py +0 -12
- jugaadcode-0.1.10/src/jugaadcode/armstrong.py +0 -11
- jugaadcode-0.1.10/src/jugaadcode/binary_search.py +0 -27
- jugaadcode-0.1.10/src/jugaadcode/bubble_sort.py +0 -21
- jugaadcode-0.1.10/src/jugaadcode/capitalize_words.py +0 -6
- jugaadcode-0.1.10/src/jugaadcode/character_frequency.py +0 -13
- jugaadcode-0.1.10/src/jugaadcode/climbing_stairs.py +0 -16
- jugaadcode-0.1.10/src/jugaadcode/coin_change.py +0 -29
- jugaadcode-0.1.10/src/jugaadcode/count_vowels.py +0 -15
- jugaadcode-0.1.10/src/jugaadcode/counting_sort.py +0 -26
- jugaadcode-0.1.10/src/jugaadcode/duplicate_number.py +0 -17
- jugaadcode-0.1.10/src/jugaadcode/even_odd.py +0 -6
- jugaadcode-0.1.10/src/jugaadcode/factorial.py +0 -14
- jugaadcode-0.1.10/src/jugaadcode/factorial_trailing_zeros_direct.py +0 -20
- jugaadcode-0.1.10/src/jugaadcode/factorial_with_trailing_zeros.py +0 -29
- jugaadcode-0.1.10/src/jugaadcode/fibonacci.py +0 -20
- jugaadcode-0.1.10/src/jugaadcode/find_max.py +0 -15
- jugaadcode-0.1.10/src/jugaadcode/find_min.py +0 -15
- jugaadcode-0.1.10/src/jugaadcode/first_non_repeating.py +0 -18
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/README.md +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/setup.cfg +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/__init__.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/gcd.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/harshad_number.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/input_utils.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/insertion_sort.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/kth_largest.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/lcm.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/linear_search.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/longest_consecutive.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/longest_word.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/matrix_transpose.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/maximum_subarray.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/merge_sort.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/move_zeros.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/pair_with_difference.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/palindrome.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/perfect_number.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/power.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/prime.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/quick_sort.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/remove_duplicates_array.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/remove_duplicates_string.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/reverse_linked_list.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/reverse_number.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/reverse_string.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/second_largest.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/selection_sort.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/strong_number.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/subsequence.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/sum_of_digits.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/trailing_zeros.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/two_sum.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/valid_parentheses.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode/word_count.py +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode.egg-info/SOURCES.txt +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode.egg-info/dependency_links.txt +0 -0
- {jugaadcode-0.1.10 → jugaadcode-0.1.11}/src/jugaadcode.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from collections import Counter
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def is_anagram(*args):
|
|
5
|
+
"""
|
|
6
|
+
Check whether two or more strings form anagrams.
|
|
7
|
+
|
|
8
|
+
Supports:
|
|
9
|
+
is_anagram("listen", "silent")
|
|
10
|
+
is_anagram(["listen", "silent"])
|
|
11
|
+
is_anagram(("listen", "silent"))
|
|
12
|
+
is_anagram(("listen", "silent"), ("hello", "world"))
|
|
13
|
+
is_anagram("listen", "silent", "hello", "world")
|
|
14
|
+
|
|
15
|
+
Spaces and letter case are ignored.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
*args : str or collections of strings
|
|
20
|
+
Two strings for a single comparison, or multiple pairs
|
|
21
|
+
supplied as separate arguments or collections.
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
bool or list[bool]
|
|
26
|
+
A boolean for one comparison, or a list of booleans
|
|
27
|
+
for multiple comparisons.
|
|
28
|
+
|
|
29
|
+
Raises
|
|
30
|
+
------
|
|
31
|
+
TypeError
|
|
32
|
+
If an input is not a string or a supported collection.
|
|
33
|
+
ValueError
|
|
34
|
+
If a comparison does not contain exactly two strings,
|
|
35
|
+
or either string is empty after removing whitespace.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
if not args:
|
|
39
|
+
first = input("Enter first string: ")
|
|
40
|
+
second = input("Enter second string: ")
|
|
41
|
+
args = (first, second)
|
|
42
|
+
|
|
43
|
+
def normalize(text):
|
|
44
|
+
if not isinstance(text, str):
|
|
45
|
+
raise TypeError("Every string must be of type str.")
|
|
46
|
+
|
|
47
|
+
normalized = "".join(text.split()).casefold()
|
|
48
|
+
|
|
49
|
+
if not normalized:
|
|
50
|
+
raise ValueError(
|
|
51
|
+
"Strings must contain at least one non-whitespace character."
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return Counter(normalized)
|
|
55
|
+
|
|
56
|
+
def compare_pair(pair):
|
|
57
|
+
if len(pair) != 2:
|
|
58
|
+
raise ValueError(
|
|
59
|
+
"Each anagram comparison must contain exactly two strings."
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
first, second = pair
|
|
63
|
+
return normalize(first) == normalize(second)
|
|
64
|
+
|
|
65
|
+
# Two strings represent one comparison.
|
|
66
|
+
if len(args) == 2 and all(isinstance(arg, str) for arg in args):
|
|
67
|
+
return compare_pair(args)
|
|
68
|
+
|
|
69
|
+
# Multiple strings represent consecutive pairs.
|
|
70
|
+
if all(isinstance(arg, str) for arg in args):
|
|
71
|
+
if len(args) % 2 != 0:
|
|
72
|
+
raise ValueError(
|
|
73
|
+
"Multiple strings must be supplied in pairs."
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
return [
|
|
77
|
+
compare_pair(args[index:index + 2])
|
|
78
|
+
for index in range(0, len(args), 2)
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
# A single collection may contain a pair of strings
|
|
82
|
+
# or multiple pairs of strings.
|
|
83
|
+
if len(args) == 1:
|
|
84
|
+
collection = args[0]
|
|
85
|
+
|
|
86
|
+
if isinstance(collection, (list, tuple)):
|
|
87
|
+
if len(collection) == 2 and all(
|
|
88
|
+
isinstance(item, str) for item in collection
|
|
89
|
+
):
|
|
90
|
+
return compare_pair(collection)
|
|
91
|
+
|
|
92
|
+
results = []
|
|
93
|
+
|
|
94
|
+
for pair in collection:
|
|
95
|
+
if not isinstance(pair, (list, tuple)):
|
|
96
|
+
raise TypeError(
|
|
97
|
+
"Multiple comparisons must be supplied as pairs."
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
results.append(compare_pair(pair))
|
|
101
|
+
|
|
102
|
+
return results
|
|
103
|
+
|
|
104
|
+
# Multiple pairs passed as separate arguments.
|
|
105
|
+
results = []
|
|
106
|
+
|
|
107
|
+
for pair in args:
|
|
108
|
+
if not isinstance(pair, (list, tuple)):
|
|
109
|
+
raise TypeError(
|
|
110
|
+
"Supply strings in pairs or provide collections of string pairs."
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
results.append(compare_pair(pair))
|
|
114
|
+
|
|
115
|
+
return results
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
def is_armstrong(*args):
|
|
2
|
+
"""
|
|
3
|
+
Check whether one or more integers are Armstrong numbers.
|
|
4
|
+
|
|
5
|
+
Supports:
|
|
6
|
+
is_armstrong(153)
|
|
7
|
+
is_armstrong(153, 370, 123)
|
|
8
|
+
is_armstrong([153, 370, 123])
|
|
9
|
+
is_armstrong((153, 370, 123))
|
|
10
|
+
is_armstrong({153, 370, 123})
|
|
11
|
+
is_armstrong(range(100, 200))
|
|
12
|
+
is_armstrong()
|
|
13
|
+
|
|
14
|
+
Returns
|
|
15
|
+
-------
|
|
16
|
+
bool
|
|
17
|
+
For a single integer.
|
|
18
|
+
list[bool] or tuple[bool, ...] or set[bool]
|
|
19
|
+
For multiple integers, according to the input format.
|
|
20
|
+
|
|
21
|
+
Raises
|
|
22
|
+
------
|
|
23
|
+
TypeError
|
|
24
|
+
If an input is not an integer or supported collection.
|
|
25
|
+
ValueError
|
|
26
|
+
If an input contains a negative integer or no values.
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
if not args:
|
|
30
|
+
value = input(
|
|
31
|
+
"Enter number(s) to check, separated by commas: "
|
|
32
|
+
).strip()
|
|
33
|
+
|
|
34
|
+
if not value:
|
|
35
|
+
raise ValueError("Input cannot be empty.")
|
|
36
|
+
|
|
37
|
+
try:
|
|
38
|
+
args = tuple(int(item.strip()) for item in value.split(","))
|
|
39
|
+
except ValueError as exc:
|
|
40
|
+
raise ValueError(
|
|
41
|
+
"Enter valid integers separated by commas."
|
|
42
|
+
) from exc
|
|
43
|
+
|
|
44
|
+
# Determine whether the caller supplied a collection or
|
|
45
|
+
# multiple individual arguments.
|
|
46
|
+
if len(args) == 1:
|
|
47
|
+
value = args[0]
|
|
48
|
+
|
|
49
|
+
if isinstance(value, (list, tuple, set, range)):
|
|
50
|
+
numbers = list(value)
|
|
51
|
+
input_type = type(value)
|
|
52
|
+
else:
|
|
53
|
+
numbers = [value]
|
|
54
|
+
input_type = None
|
|
55
|
+
else:
|
|
56
|
+
numbers = list(args)
|
|
57
|
+
input_type = tuple
|
|
58
|
+
|
|
59
|
+
if not numbers:
|
|
60
|
+
raise ValueError("At least one number must be provided.")
|
|
61
|
+
|
|
62
|
+
def check_number(n):
|
|
63
|
+
if isinstance(n, bool) or not isinstance(n, int):
|
|
64
|
+
raise TypeError("Every value must be an integer.")
|
|
65
|
+
|
|
66
|
+
if n < 0:
|
|
67
|
+
raise ValueError(
|
|
68
|
+
"Armstrong number checking requires non-negative integers."
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
digits = str(n)
|
|
72
|
+
power = len(digits)
|
|
73
|
+
|
|
74
|
+
total = sum(int(digit) ** power for digit in digits)
|
|
75
|
+
|
|
76
|
+
return total == n
|
|
77
|
+
|
|
78
|
+
results = [check_number(n) for n in numbers]
|
|
79
|
+
|
|
80
|
+
# Preserve a single result for a single integer.
|
|
81
|
+
if input_type is None:
|
|
82
|
+
return results[0]
|
|
83
|
+
|
|
84
|
+
if input_type is list or input_type is range:
|
|
85
|
+
return results
|
|
86
|
+
|
|
87
|
+
if input_type is tuple:
|
|
88
|
+
return tuple(results)
|
|
89
|
+
|
|
90
|
+
if input_type is set:
|
|
91
|
+
return set(results)
|
|
92
|
+
|
|
93
|
+
return results
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def binary_search(numbers=None, target=None, *additional_targets):
|
|
5
|
+
"""
|
|
6
|
+
Search for one or more targets in a sorted sequence using binary search.
|
|
7
|
+
|
|
8
|
+
Supports:
|
|
9
|
+
binary_search([1, 3, 5, 7], 5)
|
|
10
|
+
binary_search((1, 3, 5, 7), 5)
|
|
11
|
+
binary_search([1, 3, 5, 7], [3, 7, 9])
|
|
12
|
+
binary_search([1, 3, 5, 7], 3, 7, 9)
|
|
13
|
+
|
|
14
|
+
If the sequence or target is omitted, prompts the user.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
numbers : iterable of int, optional
|
|
19
|
+
Sorted sequence to search.
|
|
20
|
+
target : int or iterable of int, optional
|
|
21
|
+
Target value or values to find.
|
|
22
|
+
*additional_targets : int
|
|
23
|
+
Additional targets to search for.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
int
|
|
28
|
+
Index of the target when a single target is provided.
|
|
29
|
+
Returns -1 if the target is not found.
|
|
30
|
+
list[int]
|
|
31
|
+
Indices for multiple targets, using -1 for missing values.
|
|
32
|
+
|
|
33
|
+
Raises
|
|
34
|
+
------
|
|
35
|
+
TypeError
|
|
36
|
+
If the sequence or target contains unsupported values.
|
|
37
|
+
ValueError
|
|
38
|
+
If the sequence is not sorted in ascending order.
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
if numbers is None:
|
|
42
|
+
raw = input(
|
|
43
|
+
"Enter sorted numbers separated by spaces: "
|
|
44
|
+
).strip()
|
|
45
|
+
|
|
46
|
+
if not raw:
|
|
47
|
+
raise ValueError("The numbers sequence cannot be empty.")
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
numbers = list(map(int, raw.split()))
|
|
51
|
+
except ValueError as exc:
|
|
52
|
+
raise ValueError("Enter valid integers.") from exc
|
|
53
|
+
|
|
54
|
+
if isinstance(numbers, (str, bytes)):
|
|
55
|
+
raise TypeError("numbers must be a sequence of numeric values.")
|
|
56
|
+
|
|
57
|
+
if not isinstance(numbers, Iterable):
|
|
58
|
+
raise TypeError("numbers must be an iterable of integers.")
|
|
59
|
+
|
|
60
|
+
numbers = list(numbers)
|
|
61
|
+
|
|
62
|
+
if any(
|
|
63
|
+
isinstance(number, bool) or not isinstance(number, int)
|
|
64
|
+
for number in numbers
|
|
65
|
+
):
|
|
66
|
+
raise TypeError("Every element in numbers must be an integer.")
|
|
67
|
+
|
|
68
|
+
if any(numbers[i] > numbers[i + 1] for i in range(len(numbers) - 1)):
|
|
69
|
+
raise ValueError("numbers must be sorted in ascending order.")
|
|
70
|
+
|
|
71
|
+
if target is None:
|
|
72
|
+
raw = input("Enter target (or targets separated by spaces): ").strip()
|
|
73
|
+
|
|
74
|
+
if not raw:
|
|
75
|
+
raise ValueError("At least one target must be provided.")
|
|
76
|
+
|
|
77
|
+
try:
|
|
78
|
+
parsed = list(map(int, raw.split()))
|
|
79
|
+
except ValueError as exc:
|
|
80
|
+
raise ValueError("Targets must be valid integers.") from exc
|
|
81
|
+
|
|
82
|
+
if len(parsed) == 1:
|
|
83
|
+
target = parsed[0]
|
|
84
|
+
else:
|
|
85
|
+
target = parsed
|
|
86
|
+
|
|
87
|
+
def search_one(value):
|
|
88
|
+
if isinstance(value, bool) or not isinstance(value, int):
|
|
89
|
+
raise TypeError("Every target must be an integer.")
|
|
90
|
+
|
|
91
|
+
left, right = 0, len(numbers) - 1
|
|
92
|
+
|
|
93
|
+
while left <= right:
|
|
94
|
+
middle = (left + right) // 2
|
|
95
|
+
|
|
96
|
+
if numbers[middle] == value:
|
|
97
|
+
return middle
|
|
98
|
+
|
|
99
|
+
if numbers[middle] < value:
|
|
100
|
+
left = middle + 1
|
|
101
|
+
else:
|
|
102
|
+
right = middle - 1
|
|
103
|
+
|
|
104
|
+
return -1
|
|
105
|
+
|
|
106
|
+
# Collect targets while preserving the original single-target behaviour.
|
|
107
|
+
if additional_targets:
|
|
108
|
+
targets = [target, *additional_targets]
|
|
109
|
+
multiple = True
|
|
110
|
+
elif isinstance(target, (list, tuple, set, range)):
|
|
111
|
+
targets = list(target)
|
|
112
|
+
multiple = True
|
|
113
|
+
else:
|
|
114
|
+
targets = [target]
|
|
115
|
+
multiple = False
|
|
116
|
+
|
|
117
|
+
results = [search_one(value) for value in targets]
|
|
118
|
+
|
|
119
|
+
return results if multiple else results[0]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def bubble_sort(*args):
|
|
5
|
+
"""
|
|
6
|
+
Sort numbers in ascending order using the Bubble Sort algorithm.
|
|
7
|
+
|
|
8
|
+
Supports:
|
|
9
|
+
bubble_sort([5, 2, 8, 1])
|
|
10
|
+
bubble_sort((5, 2, 8, 1))
|
|
11
|
+
bubble_sort(range(5, 0, -1))
|
|
12
|
+
bubble_sort(5, 2, 8, 1)
|
|
13
|
+
bubble_sort()
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
*args
|
|
18
|
+
A collection of numbers, multiple numeric arguments,
|
|
19
|
+
or no arguments to enable interactive input.
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
list
|
|
24
|
+
A new list containing the sorted numbers.
|
|
25
|
+
|
|
26
|
+
Raises
|
|
27
|
+
------
|
|
28
|
+
TypeError
|
|
29
|
+
If the input is not a supported collection of comparable numbers.
|
|
30
|
+
ValueError
|
|
31
|
+
If interactive input is empty or contains invalid numbers.
|
|
32
|
+
|
|
33
|
+
Examples
|
|
34
|
+
--------
|
|
35
|
+
>>> bubble_sort([5, 2, 8, 1])
|
|
36
|
+
[1, 2, 5, 8]
|
|
37
|
+
|
|
38
|
+
>>> bubble_sort(5, 2, 8, 1)
|
|
39
|
+
[1, 2, 5, 8]
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
if not args:
|
|
43
|
+
raw = input("Enter numbers separated by spaces: ").strip()
|
|
44
|
+
|
|
45
|
+
if not raw:
|
|
46
|
+
raise ValueError("At least one number must be provided.")
|
|
47
|
+
|
|
48
|
+
try:
|
|
49
|
+
args = ([
|
|
50
|
+
float(value) if "." in value else int(value)
|
|
51
|
+
for value in raw.split()
|
|
52
|
+
],)
|
|
53
|
+
except ValueError as exc:
|
|
54
|
+
raise ValueError("Enter valid numeric values.") from exc
|
|
55
|
+
|
|
56
|
+
# Accept a collection as the first argument or multiple arguments.
|
|
57
|
+
if len(args) == 1:
|
|
58
|
+
values = args[0]
|
|
59
|
+
|
|
60
|
+
if isinstance(values, (str, bytes)):
|
|
61
|
+
raise TypeError("Input must contain numbers, not a string.")
|
|
62
|
+
|
|
63
|
+
if isinstance(values, Iterable):
|
|
64
|
+
numbers = list(values)
|
|
65
|
+
else:
|
|
66
|
+
numbers = [values]
|
|
67
|
+
else:
|
|
68
|
+
numbers = list(args)
|
|
69
|
+
|
|
70
|
+
# Validate elements.
|
|
71
|
+
for number in numbers:
|
|
72
|
+
if isinstance(number, bool) or not isinstance(number, (int, float)):
|
|
73
|
+
raise TypeError("All elements must be integers or floats.")
|
|
74
|
+
|
|
75
|
+
if isinstance(number, float) and not __import__("math").isfinite(number):
|
|
76
|
+
raise ValueError("NaN and infinity are not supported.")
|
|
77
|
+
|
|
78
|
+
# Bubble Sort.
|
|
79
|
+
numbers = numbers.copy()
|
|
80
|
+
n = len(numbers)
|
|
81
|
+
|
|
82
|
+
for i in range(n):
|
|
83
|
+
swapped = False
|
|
84
|
+
|
|
85
|
+
for j in range(n - i - 1):
|
|
86
|
+
if numbers[j] > numbers[j + 1]:
|
|
87
|
+
numbers[j], numbers[j + 1] = numbers[j + 1], numbers[j]
|
|
88
|
+
swapped = True
|
|
89
|
+
|
|
90
|
+
# Stop early if the list is already sorted.
|
|
91
|
+
if not swapped:
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
return numbers
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def capitalize_words(*args):
|
|
5
|
+
"""
|
|
6
|
+
Capitalize the first character of each word in one or more strings.
|
|
7
|
+
|
|
8
|
+
Supports:
|
|
9
|
+
capitalize_words("hello world")
|
|
10
|
+
capitalize_words("hello world", "python programming")
|
|
11
|
+
capitalize_words(["hello world", "python programming"])
|
|
12
|
+
capitalize_words(("hello world", "python programming"))
|
|
13
|
+
capitalize_words()
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
*args : str or iterable of str
|
|
18
|
+
One string, multiple strings, or a collection of strings.
|
|
19
|
+
If no arguments are supplied, prompts for interactive input.
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
str or list[str] or tuple[str, ...]
|
|
24
|
+
A capitalized string for a single string.
|
|
25
|
+
A list or tuple for multiple strings, matching the input style.
|
|
26
|
+
|
|
27
|
+
Raises
|
|
28
|
+
------
|
|
29
|
+
TypeError
|
|
30
|
+
If an input is not a string or supported collection of strings.
|
|
31
|
+
|
|
32
|
+
Examples
|
|
33
|
+
--------
|
|
34
|
+
>>> capitalize_words("hello world")
|
|
35
|
+
'Hello World'
|
|
36
|
+
|
|
37
|
+
>>> capitalize_words(["hello world", "python programming"])
|
|
38
|
+
['Hello World', 'Python Programming']
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
if not args:
|
|
42
|
+
text = input("Enter a sentence to capitalize words in: ")
|
|
43
|
+
return text.title()
|
|
44
|
+
|
|
45
|
+
# Handle multiple positional strings.
|
|
46
|
+
if all(isinstance(arg, str) for arg in args):
|
|
47
|
+
if len(args) == 1:
|
|
48
|
+
return args[0].title()
|
|
49
|
+
|
|
50
|
+
return tuple(text.title() for text in args)
|
|
51
|
+
|
|
52
|
+
# Handle a single collection of strings.
|
|
53
|
+
if len(args) == 1:
|
|
54
|
+
values = args[0]
|
|
55
|
+
|
|
56
|
+
if isinstance(values, str):
|
|
57
|
+
return values.title()
|
|
58
|
+
|
|
59
|
+
if isinstance(values, Iterable):
|
|
60
|
+
if isinstance(values, (bytes, bytearray)):
|
|
61
|
+
raise TypeError("Input must contain strings, not bytes.")
|
|
62
|
+
|
|
63
|
+
texts = list(values)
|
|
64
|
+
|
|
65
|
+
if not all(isinstance(text, str) for text in texts):
|
|
66
|
+
raise TypeError("Every element must be a string.")
|
|
67
|
+
|
|
68
|
+
results = [text.title() for text in texts]
|
|
69
|
+
|
|
70
|
+
if isinstance(values, tuple):
|
|
71
|
+
return tuple(results)
|
|
72
|
+
|
|
73
|
+
return results
|
|
74
|
+
|
|
75
|
+
raise TypeError(
|
|
76
|
+
"Provide a string, multiple strings, or a collection of strings."
|
|
77
|
+
)
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from collections import Counter
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def character_frequency(*args):
|
|
6
|
+
"""
|
|
7
|
+
Count the frequency of each character in one or more strings.
|
|
8
|
+
|
|
9
|
+
Spaces are ignored. Other whitespace characters, such as tabs
|
|
10
|
+
and newlines, are counted.
|
|
11
|
+
|
|
12
|
+
Supports:
|
|
13
|
+
character_frequency("hello")
|
|
14
|
+
character_frequency("hello", "world")
|
|
15
|
+
character_frequency(["hello", "world"])
|
|
16
|
+
character_frequency(("hello", "world"))
|
|
17
|
+
character_frequency()
|
|
18
|
+
|
|
19
|
+
Parameters
|
|
20
|
+
----------
|
|
21
|
+
*args : str or iterable of str
|
|
22
|
+
A string, multiple strings, or a collection of strings.
|
|
23
|
+
If no arguments are supplied, prompts for interactive input.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
dict[str, int] or list[dict[str, int]] or tuple[dict[str, int], ...]
|
|
28
|
+
A frequency dictionary for one string.
|
|
29
|
+
A collection of frequency dictionaries for multiple strings.
|
|
30
|
+
|
|
31
|
+
Raises
|
|
32
|
+
------
|
|
33
|
+
TypeError
|
|
34
|
+
If an input is not a string or a supported collection of strings.
|
|
35
|
+
|
|
36
|
+
Examples
|
|
37
|
+
--------
|
|
38
|
+
>>> character_frequency("hello")
|
|
39
|
+
{'h': 1, 'e': 1, 'l': 2, 'o': 1}
|
|
40
|
+
|
|
41
|
+
>>> character_frequency(["hello", "world"])
|
|
42
|
+
[{'h': 1, 'e': 1, 'l': 2, 'o': 1},
|
|
43
|
+
{'w': 1, 'o': 1, 'r': 1, 'l': 1, 'd': 1}]
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
if not args:
|
|
47
|
+
text = input("Enter a string to analyze character frequency: ")
|
|
48
|
+
args = (text,)
|
|
49
|
+
|
|
50
|
+
def count_characters(text):
|
|
51
|
+
if not isinstance(text, str):
|
|
52
|
+
raise TypeError("Every input must be a string.")
|
|
53
|
+
|
|
54
|
+
return dict(Counter(character for character in text if character != " "))
|
|
55
|
+
|
|
56
|
+
# A single string produces one frequency dictionary.
|
|
57
|
+
if len(args) == 1 and isinstance(args[0], str):
|
|
58
|
+
return count_characters(args[0])
|
|
59
|
+
|
|
60
|
+
# Multiple positional strings produce multiple dictionaries.
|
|
61
|
+
if all(isinstance(arg, str) for arg in args):
|
|
62
|
+
return tuple(count_characters(text) for text in args)
|
|
63
|
+
|
|
64
|
+
# A collection of strings produces one dictionary per string.
|
|
65
|
+
if len(args) == 1 and isinstance(args[0], Iterable):
|
|
66
|
+
values = args[0]
|
|
67
|
+
|
|
68
|
+
if isinstance(values, (bytes, bytearray)):
|
|
69
|
+
raise TypeError("Input must contain strings, not bytes.")
|
|
70
|
+
|
|
71
|
+
texts = list(values)
|
|
72
|
+
|
|
73
|
+
if not all(isinstance(text, str) for text in texts):
|
|
74
|
+
raise TypeError("Every element in the collection must be a string.")
|
|
75
|
+
|
|
76
|
+
results = [count_characters(text) for text in texts]
|
|
77
|
+
|
|
78
|
+
if isinstance(values, tuple):
|
|
79
|
+
return tuple(results)
|
|
80
|
+
|
|
81
|
+
return results
|
|
82
|
+
|
|
83
|
+
raise TypeError(
|
|
84
|
+
"Provide a string, multiple strings, or a collection of strings."
|
|
85
|
+
)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def climbing_stairs(*args):
|
|
5
|
+
"""
|
|
6
|
+
Calculate the number of distinct ways to climb stairs,
|
|
7
|
+
taking either 1 or 2 steps at a time.
|
|
8
|
+
|
|
9
|
+
Supports:
|
|
10
|
+
climbing_stairs(5)
|
|
11
|
+
climbing_stairs(3, 5, 7)
|
|
12
|
+
climbing_stairs([3, 5, 7])
|
|
13
|
+
climbing_stairs((3, 5, 7))
|
|
14
|
+
climbing_stairs(range(1, 6))
|
|
15
|
+
climbing_stairs()
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
*args : int or iterable of int
|
|
20
|
+
One stair count, multiple stair counts, or a collection
|
|
21
|
+
of stair counts. If omitted, prompts for interactive input.
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
int or list[int] or tuple[int, ...]
|
|
26
|
+
The number of ways for one input or multiple inputs.
|
|
27
|
+
For n = 0, returns 1 because there is one way to climb
|
|
28
|
+
zero stairs: take no steps.
|
|
29
|
+
|
|
30
|
+
Raises
|
|
31
|
+
------
|
|
32
|
+
TypeError
|
|
33
|
+
If an input is not an integer or supported collection.
|
|
34
|
+
ValueError
|
|
35
|
+
If any stair count is negative.
|
|
36
|
+
|
|
37
|
+
Examples
|
|
38
|
+
--------
|
|
39
|
+
>>> climbing_stairs(2)
|
|
40
|
+
2
|
|
41
|
+
>>> climbing_stairs(5)
|
|
42
|
+
8
|
|
43
|
+
>>> climbing_stairs([2, 3, 5])
|
|
44
|
+
[2, 3, 8]
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
if not args:
|
|
48
|
+
raw = input("Enter number(s) of stairs, separated by spaces: ").strip()
|
|
49
|
+
|
|
50
|
+
if not raw:
|
|
51
|
+
raise ValueError("At least one stair count must be provided.")
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
args = tuple(int(value) for value in raw.split())
|
|
55
|
+
except ValueError as exc:
|
|
56
|
+
raise ValueError("Stair counts must be integers.") from exc
|
|
57
|
+
|
|
58
|
+
# Determine whether input is a single value, collection,
|
|
59
|
+
# or multiple positional values.
|
|
60
|
+
if len(args) == 1:
|
|
61
|
+
value = args[0]
|
|
62
|
+
|
|
63
|
+
if isinstance(value, (list, tuple, range)):
|
|
64
|
+
numbers = list(value)
|
|
65
|
+
input_type = type(value)
|
|
66
|
+
else:
|
|
67
|
+
numbers = [value]
|
|
68
|
+
input_type = None
|
|
69
|
+
else:
|
|
70
|
+
numbers = list(args)
|
|
71
|
+
input_type = tuple
|
|
72
|
+
|
|
73
|
+
if not numbers:
|
|
74
|
+
raise ValueError("At least one stair count must be provided.")
|
|
75
|
+
|
|
76
|
+
def count_ways(n):
|
|
77
|
+
if isinstance(n, bool) or not isinstance(n, int):
|
|
78
|
+
raise TypeError("Every stair count must be an integer.")
|
|
79
|
+
|
|
80
|
+
if n < 0:
|
|
81
|
+
raise ValueError("The number of stairs cannot be negative.")
|
|
82
|
+
|
|
83
|
+
if n == 0:
|
|
84
|
+
return 1
|
|
85
|
+
|
|
86
|
+
if n <= 2:
|
|
87
|
+
return n
|
|
88
|
+
|
|
89
|
+
first, second = 1, 2
|
|
90
|
+
|
|
91
|
+
for _ in range(3, n + 1):
|
|
92
|
+
first, second = second, first + second
|
|
93
|
+
|
|
94
|
+
return second
|
|
95
|
+
|
|
96
|
+
results = [count_ways(n) for n in numbers]
|
|
97
|
+
|
|
98
|
+
if input_type is None:
|
|
99
|
+
return results[0]
|
|
100
|
+
|
|
101
|
+
if input_type is tuple:
|
|
102
|
+
return tuple(results)
|
|
103
|
+
|
|
104
|
+
return results
|