-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from Navid-JL/dev
Implement Base Converter Functionality
- Loading branch information
Showing
13 changed files
with
349 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"[python]": { | ||
"editor.defaultFormatter": "ms-python.autopep8" | ||
}, | ||
"python.formatting.provider": "none", | ||
"python.linting.pylintArgs": ["--disable=C0116", "--disable=C0114"], | ||
"python.linting.enabled": true, | ||
"python.linting.pylintEnabled": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,22 @@ | ||
from choosing import choose_from_base, choose_to_base, choose_input_number | ||
from validating import validate_input_number | ||
from converting import convert_base | ||
from sys import path | ||
from src.cli.prompt import select_base | ||
from src.utils.validator import Validator | ||
from src.core.convert import convert_base | ||
|
||
bases = [2, 8, 10, 16] | ||
|
||
from_base = choose_from_base(bases) | ||
def main(): | ||
origin_base = select_base() | ||
entered_number = input("Enter number:") | ||
|
||
to_base = choose_to_base(from_base, bases) | ||
Validator.validate_input(entered_number, origin_base) | ||
|
||
valid_input_number = False | ||
while not valid_input_number: | ||
input_number = choose_input_number(from_base) | ||
valid_input_number = validate_input_number(from_base, input_number) | ||
destination_base = select_base() | ||
|
||
output_number = convert_base(from_base, to_base, input_number) | ||
converted_number = convert_base( | ||
entered_number, origin_base, destination_base) | ||
print(converted_number) | ||
|
||
print(f'Your result is {output_number}, a base {to_base} number.') | ||
|
||
if __name__ == "__main__": | ||
path.append('../') | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
bases=[2,8,10,16] | ||
binary_digits=[0,1] | ||
octal_digits=[0,1,2,3,4,5,6,7] | ||
decimal_digits=[0,1,2,3,4,5,6,7,8,9] | ||
hex_digits=[0,1,2,3,4,5,6,7,8,9,"A","B","C","D","E","F"] | ||
out=False | ||
def choosing(bases): | ||
while True: | ||
choice=input("What Base Would You Like To Convert From [2, 8, 10 ,16]: ") | ||
if not choice.isdigit(): | ||
print("Input Must Be A Number, Please Try Again.") | ||
continue | ||
choice=int(choice) | ||
if choice not in bases: | ||
print("Not A Choice, Please Try Again.") | ||
continue | ||
break | ||
return choice | ||
choice=choosing(bases) | ||
available_bases = list(filter(lambda b: b != choice, bases)) | ||
def choosing_2(choice): | ||
while True: | ||
choice_2=input(f"What Base Would You Like To Convert To? {available_bases}: ") | ||
if not choice_2.isdigit(): | ||
print("Input Must Be A Number, Please Try Again.") | ||
continue | ||
choice_2=int(choice_2) | ||
choice_2=int(choice_2) | ||
if choice_2 not in bases: | ||
print("Choice Does Not Exist, Please Try Again.") | ||
continue | ||
if choice_2==choice: | ||
print("Cannot Convert To Same Base, Please Try Again.") | ||
continue | ||
break | ||
return choice_2 | ||
choice_2=choosing_2(choice) | ||
def inputting_number(choice,out): | ||
while True: | ||
number=input(f"Please Input A Base {choice} Number: ") | ||
if not number.isdigit() and choice!=16: | ||
print("Input Must Be A Number.") | ||
continue | ||
if choice in [2,8,10]: | ||
number=int(number) | ||
if choice==2: | ||
for digit in str(number): | ||
if digit not in str(binary_digits): | ||
print("Please Input A Valid Base 2 Number.") | ||
out=True | ||
break | ||
if choice==8: | ||
for digit in str(number): | ||
if digit not in str(octal_digits): | ||
print("Please Input A Valid Base 8 Number.") | ||
out=True | ||
break | ||
if choice==10: | ||
for digit in str(number): | ||
if digit not in str(decimal_digits): | ||
print("Please Input A Valid Base 10 Number.") | ||
out=True | ||
break | ||
if choice==16: | ||
for digit in str(number): | ||
if digit not in str(hex_digits): | ||
print("Please Input A Valid Base 16 Number.") | ||
out=True | ||
break | ||
if out==True: | ||
continue | ||
break | ||
return number | ||
number=inputting_number(choice,out) | ||
print(number) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
bases=[2,8,10,16] | ||
|
||
def choosing(bases): | ||
while True: | ||
choice=input("What Base Would You Like To Convert From [2, 8, 10 ,16]: ") | ||
if not choice.isdigit(): | ||
print("Input Must Be A Number, Please Try Again.") | ||
continue | ||
choice=int(choice) | ||
if choice not in bases: | ||
print("Not A Choice, Please Try Again.") | ||
continue | ||
break | ||
return choice | ||
choice=choosing(bases) | ||
available_bases = list(filter(lambda b: b != choice, bases)) | ||
|
||
def choosing_2(choice): | ||
while True: | ||
print("What Base Would You Like To Convert To?",available_bases,end=": ") | ||
choice_2=input("") | ||
if not choice_2.isdigit(): | ||
print("Input Must Be A Number, Please Try Again.") | ||
continue | ||
choice_2=int(choice_2) | ||
choice_2=int(choice_2) | ||
if choice_2 not in bases: | ||
print("Choice Does Not Exist, Please Try Again.") | ||
continue | ||
if choice_2==choice: | ||
print("Cannot Convert To Same Base, Please Try Again.") | ||
continue | ||
break | ||
return choice_2 | ||
choice_2=choosing_2(choice) | ||
print(choice_2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
def choosing(): | ||
while True: | ||
choice=input("Please Choose One Of These Bases [2, 8, 10, 16]: ") | ||
if not choice.isdigit(): | ||
print("Not A Number, Please Try Again") | ||
continue | ||
choice=int(choice) | ||
|
||
if choice != 2 and choice != 8 and choice != 10 and choice != 16: | ||
print("Choice Does Not Exist, Please Try Again") | ||
else: | ||
break | ||
return choice | ||
choice=choosing() | ||
list=[2,8,10,16] | ||
list.remove(choice) | ||
def choosing_2(choice): | ||
while True: | ||
print("What Base Would You Like To Convert To?",list,end=": ") | ||
choice_2=input("") | ||
if not choice_2.isdigit(): | ||
print("Not A Number, Please Try Again") | ||
continue | ||
choice_2=int(choice_2) | ||
if choice_2 != 2 and choice_2 != 8 and choice_2 != 10 and choice_2 != 16: | ||
print("Choice Does Not Exist, Please Try Again") | ||
continue | ||
if choice_2==choice: | ||
print("Cannot Convert To Same Base, Please Try Again.") | ||
continue | ||
else: | ||
break | ||
return choice_2 | ||
print(choosing_2(choice)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
[tool.poetry] | ||
name = "base-converter" | ||
version = "1.0.0" | ||
description = "A Python program to convert numbers between different bases." | ||
authors = ["Your Name <[email protected]>"] | ||
license = "CC0-1.0" | ||
readme = "README.md" | ||
packages = [{include = "base_converter"}] | ||
|
||
[tool.poetry.dependencies] | ||
python = "^3.11" | ||
inquirer = "^3.1.3" | ||
pylint = "^2.17.5" | ||
pytest = "^7.4.0" | ||
|
||
|
||
[build-system] | ||
requires = ["poetry-core"] | ||
build-backend = "poetry.core.masonry.api" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
from enum import Enum | ||
|
||
|
||
class Base(Enum): | ||
"""Base enum""" | ||
BINARY = 2 | ||
OCTAL = 8 | ||
DECIMAL = 10 | ||
HEXADECIMAL = 16 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import inquirer | ||
from src.bases.base_names import Base | ||
|
||
|
||
def select_base() -> int: | ||
"""prompts the user to select a base | ||
Returns: | ||
dict[str, str]: user selected base | ||
""" | ||
base_list = [ | ||
inquirer.List( | ||
"input", | ||
message="Select base", | ||
choices=[base.value for base in Base], | ||
), | ||
] | ||
|
||
answer = inquirer.prompt(base_list) | ||
|
||
return answer["input"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
def convert_base(number: str, origin_base: int, destination_base: int) -> str: | ||
if origin_base == destination_base: | ||
return number | ||
converted_number = "" | ||
number = str(int(number, base=origin_base)) | ||
|
||
if destination_base == 2: | ||
converted_number = bin(int(number))[2:] | ||
elif destination_base == 8: | ||
converted_number = oct(int(number))[2:] | ||
elif destination_base == 10: | ||
converted_number = number | ||
elif destination_base == 16: | ||
converted_number = hex(int(number)).upper()[2:] | ||
return converted_number |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import re | ||
|
||
|
||
class Validator: | ||
@staticmethod | ||
def is_valid_base(number: str, base: int) -> bool: | ||
if base < 16: | ||
pattern = rf'^[0-{base - 1}]$' | ||
else: | ||
pattern = r'^[0-9A-Fa-f]+$' | ||
|
||
return re.match(pattern, number) is not None | ||
|
||
@staticmethod | ||
def validate_input(entered_number: str, selected_base: int): | ||
for digit in entered_number: | ||
if not Validator.is_valid_base(digit, selected_base): | ||
raise ValueError() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
from src.core.convert import convert_base | ||
|
||
# Binary to other bases | ||
|
||
|
||
def test_bin_to_bin(): | ||
result = convert_base("1001", 2, 2) | ||
assert result == "1001" | ||
|
||
|
||
def test_bin_to_oct(): | ||
result = convert_base("1101", 2, 8) | ||
assert result == "15" | ||
|
||
|
||
def test_bin_to_dec(): | ||
result = convert_base("1100", 2, 10) | ||
assert result == "12" | ||
|
||
|
||
def test_bin_to_hex(): | ||
result = convert_base("1111", 2, 16) | ||
assert result == "F" | ||
|
||
# Octal to other bases | ||
|
||
|
||
def test_oct_to_oct(): | ||
result = convert_base("73", 8, 8) | ||
assert result == "73" | ||
|
||
|
||
def test_oct_to_bin(): | ||
result = convert_base("73", 8, 2) | ||
assert result == "111011" | ||
|
||
|
||
def test_oct_to_dec(): | ||
result = convert_base("73", 8, 10) | ||
assert result == "59" | ||
|
||
|
||
def test_oct_to_hex(): | ||
result = convert_base("73", 8, 16) | ||
assert result == "3B" | ||
|
||
# Decimal to other bases | ||
|
||
|
||
def test_dec_to_dec(): | ||
result = convert_base("94", 10, 10) | ||
assert result == "94" | ||
|
||
|
||
def test_dec_to_bin(): | ||
result = convert_base("94", 10, 2) | ||
assert result == "1011110" | ||
|
||
|
||
def test_dec_to_oct(): | ||
result = convert_base("94", 10, 8) | ||
assert result == "136" | ||
|
||
|
||
def test_dec_to_hex(): | ||
result = convert_base("94", 10, 16) | ||
assert result == "5E" | ||
|
||
# Hexadecimal to other bases | ||
|
||
|
||
def test_hex_to_hex(): | ||
result = convert_base("DEA5", 16, 16) | ||
assert result == "DEA5" | ||
|
||
|
||
def test_hex_to_bin(): | ||
result = convert_base("DEA5", 16, 2) | ||
assert result == "1101111010100101" | ||
|
||
|
||
def test_hex_to_oct(): | ||
result = convert_base("DEA5", 16, 8) | ||
assert result == "157245" | ||
|
||
|
||
def test_hex_to_dec(): | ||
result = convert_base("DEA5", 16, 10) | ||
assert result == "56997" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from src.cli.prompt import select_base | ||
|
||
|
||
def test_input_value(): | ||
# Test if the input is not an empty string or null | ||
selected_base = select_base() | ||
assert selected_base["input"] != "" or None |