P01: Universal Number Base Converter

P01: Universal Number Base Converter

The Core Question: โ€œHow does the computer understand that the symbols โ€˜255โ€™, โ€˜FFโ€™, and โ€˜11111111โ€™ all represent the same value?โ€


Learning Objectives

By completing this project, you will:

  1. Master positional notation - Understand that every number system works the same way, just with different bases
  2. Implement the division-remainder algorithm - Convert from decimal to any base without using built-in functions
  3. Implement the power-summation algorithm - Convert from any base to decimal manually
  4. Internalize the binary-hex relationship - Instantly recognize that 4 binary bits equal 1 hex digit
  5. Build professional CLI tools - Create a complete, validated, user-friendly command-line application
  6. Think like a computer - See numbers as abstract values with multiple representations
  7. Handle edge cases gracefully - Build robust software that fails gracefully with meaningful errors

Project Overview

Attribute Value
Main Language Python
Alternative Languages JavaScript (Node.js), Go, C#
Difficulty Beginner
Time Estimate Weekend (6-10 hours)
Prerequisites Basic programming (loops, functions, conditionals)
Main Book โ€œCode: The Hidden Languageโ€ by Charles Petzold

What Youโ€™ll Build

A command-line tool that converts numbers between decimal, binary, and hexadecimal. The tool accepts a number in any base, validates it, and outputs the equivalent representation in the target base.

Example usage:

$ python converter.py --from dec --to hex 255
FF

$ python converter.py --from bin --to dec 11111111
255

$ python converter.py --from hex --to bin FF
11111111

The key constraint: You must implement the conversion algorithms yourself. Do not use Pythonโ€™s bin(), hex(), or int(x, base) functions. The learning happens when you write the logic.


Real World Outcome

When you complete this project, youโ€™ll have a professional utility you can use whenever you need quick conversions. Hereโ€™s exactly what your tool will produce:

Example 1: Decimal to Hexadecimal Conversion

$ python converter.py --from dec --to hex 255
Input:   255 (decimal)
Binary:  11111111
Hex:     FF
Output:  FF (hexadecimal)

Example 2: Hexadecimal to Decimal (Memory Addresses)

$ python converter.py --from hex --to dec 0x7FFF5C2A
Input:   0x7FFF5C2A (hexadecimal)
Decimal: 2147466282
Binary:  01111111111111110101110000101010
Output:  2147466282 (decimal)

Example 3: Binary to All Formats

$ python converter.py --from bin --to all 11010110
Input:   11010110 (binary)
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
Decimal: 214
Hex:     D6
Octal:   326
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Example 4: Verbose Mode (Shows Work)

$ python converter.py --from dec --to bin 25 --verbose
Input: 25 (decimal)

Step-by-step conversion:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Step โ”‚ Divide โ”‚ Result โ”‚ Remainder     โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1    โ”‚ 25 รท 2 โ”‚ 12     โ”‚ 1 (rightmost) โ”‚
โ”‚ 2    โ”‚ 12 รท 2 โ”‚ 6      โ”‚ 0             โ”‚
โ”‚ 3    โ”‚ 6 รท 2  โ”‚ 3      โ”‚ 0             โ”‚
โ”‚ 4    โ”‚ 3 รท 2  โ”‚ 1      โ”‚ 1             โ”‚
โ”‚ 5    โ”‚ 1 รท 2  โ”‚ 0      โ”‚ 1 (leftmost)  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Reading remainders bottom-to-top: 11001

Output: 11001 (binary)

Example 5: Batch Processing Mode

$ python converter.py --batch conversions.txt
Processing 5 conversions...
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
[1] 127 (dec) โ†’ 0x7F (hex)
[2] 0xFF (hex) โ†’ 255 (dec)
[3] 10101010 (bin) โ†’ 170 (dec)
[4] 256 (dec) โ†’ 100000000 (bin)
[5] CAFE (hex) โ†’ 51966 (dec)
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
All conversions complete.

Example 6: Error Handling

$ python converter.py --from hex --to dec "GG"
Error: Invalid hexadecimal input 'GG'
       Hexadecimal digits must be 0-9 or A-F.

$ python converter.py --from bin --to dec "12345"
Error: Invalid binary input '12345'
       Binary digits must be 0 or 1 only.

$ python converter.py --from dec --to hex -5
Error: Negative numbers not supported in this version.
       Use unsigned integers only.

Real-World Scenarios Where Youโ€™ll Use This

After completing this project, youโ€™ll use your converter for:

  • Debugging memory dumps - Reading hex addresses from debuggers like lldb or gdb
  • Understanding file permissions - Unix permissions like 0755 become readable
  • Network programming - IP addresses and subnet masks in binary/hex
  • Color values - Converting RGB decimal values to hex for CSS
  • Reading assembly output - Understanding hex opcodes and addresses
  • Cryptography work - Hash values and keys displayed in hexadecimal

The Core Question Youโ€™re Answering

โ€œHow does the computer understand that the symbols โ€˜255โ€™, โ€˜FFโ€™, and โ€˜11111111โ€™ all represent the same value?โ€

This project answers the fundamental question that underlies all of computing. Hereโ€™s the deep insight:

Numbers Are Abstract; Notation Is Concrete

The value โ€œtwo hundred fifty-fiveโ€ exists as an abstract concept - the quantity of items in a set. When we write it down, weโ€™re using a notation system to represent that abstract value:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    THE SAME VALUE                               โ”‚
โ”‚                                                                 โ”‚
โ”‚   Decimal:     255      = 2ร—10ยฒ + 5ร—10ยน + 5ร—10โฐ                โ”‚
โ”‚                         = 200 + 50 + 5                          โ”‚
โ”‚                                                                 โ”‚
โ”‚   Binary:      11111111 = 1ร—2โท + 1ร—2โถ + 1ร—2โต + 1ร—2โด            โ”‚
โ”‚                         + 1ร—2ยณ + 1ร—2ยฒ + 1ร—2ยน + 1ร—2โฐ             โ”‚
โ”‚                         = 128 + 64 + 32 + 16 + 8 + 4 + 2 + 1    โ”‚
โ”‚                                                                 โ”‚
โ”‚   Hexadecimal: FF       = 15ร—16ยน + 15ร—16โฐ                       โ”‚
โ”‚                         = 240 + 15                               โ”‚
โ”‚                                                                 โ”‚
โ”‚   All equal: 255                                                 โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why Different Bases Exist

  • Decimal (Base 10): Humans have 10 fingers. We naturally count in tens.
  • Binary (Base 2): Transistors have two states: ON (1) and OFF (0). Computers must use binary.
  • Hexadecimal (Base 16): Perfect bridge between human readability and binary. 4 binary bits = 1 hex digit exactly.

The Magic Relationship: 4 Bits = 1 Hex Digit

This is the most important pattern to internalize:

Binary โ†’ Hex Mapping (Memorize This!)
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
0000 = 0    0100 = 4    1000 = 8    1100 = C
0001 = 1    0101 = 5    1001 = 9    1101 = D
0010 = 2    0110 = 6    1010 = A    1110 = E
0011 = 3    0111 = 7    1011 = B    1111 = F
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Example:
Binary:  1010 0101
         โ†“    โ†“
Hex:      A    5
Result:  0xA5

Reverse:
Hex:     F    8
         โ†“    โ†“
Binary: 1111 1000

By building this converter from scratch, you prove to yourself that you understand the mechanics of positional number systems at a fundamental level.


Concepts You Must Understand First

Before writing any code, you need to internalize these prerequisite concepts. Do not skip this section - the depth of your understanding here determines your success.

1. Positional Notation (Place-Value System)

What it is: In any base-N system, each digitโ€™s position represents a power of N. The rightmost position is Nโฐ (always 1), then Nยน, Nยฒ, and so on moving left.

Book Reference: โ€œCode: The Hidden Language of Computer Hardware and Softwareโ€ by Charles Petzold, Chapter 7: โ€œCountingโ€

ASCII Diagram - How Position Determines Value:

   DECIMAL NUMBER: 1,234
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
   Position:    3      2      1      0
   Power:      10ยณ    10ยฒ    10ยน    10โฐ
   Value:     1000    100     10      1
              โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€
   Digit:       1      2      3      4
              โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€
   Contribution: 1ร—1000 + 2ร—100 + 3ร—10 + 4ร—1
              = 1000  + 200   + 30   + 4
              = 1234
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

   BINARY NUMBER: 1011
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
   Position:    3      2      1      0
   Power:       2ยณ     2ยฒ     2ยน     2โฐ
   Value:        8      4      2      1
               โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€
   Digit:        1      0      1      1
               โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€
   Contribution:  1ร—8  + 0ร—4  + 1ร—2  + 1ร—1
               =   8  +   0  +   2  +   1
               =  11  (decimal)
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

   HEX NUMBER: 2F
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
   Position:    1      0
   Power:      16ยน    16โฐ
   Value:       16      1
              โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€
   Digit:        2      F (=15)
              โ”€โ”€โ”€โ”€โ”€  โ”€โ”€โ”€โ”€โ”€
   Contribution:  2ร—16 + 15ร—1
              =   32  +  15
              =   47  (decimal)
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Why it matters: This is the entire mathematical foundation of base conversion. If you can apply this pattern, you can convert any base to decimal.

2. The Division-Remainder Algorithm

What it is: To convert from decimal to another base, repeatedly divide by the target base and collect the remainders. The remainders (read in reverse) form the digits of the result.

Book Reference: โ€œGrokking Algorithmsโ€ by Aditya Bhargava, Chapter 1 - for understanding algorithmic thinking

Example - Convert Decimal 25 to Binary:

   DECIMAL 25 TO BINARY
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

   Step 1:  25 รท 2 = 12  remainder  1  โ† rightmost bit
   Step 2:  12 รท 2 =  6  remainder  0
   Step 3:   6 รท 2 =  3  remainder  0
   Step 4:   3 รท 2 =  1  remainder  1
   Step 5:   1 รท 2 =  0  remainder  1  โ† leftmost bit
                              โ†‘
                         STOP when quotient = 0

   Read remainders BOTTOM to TOP: 11001

   Verification: 1ร—16 + 1ร—8 + 0ร—4 + 0ร—2 + 1ร—1 = 25 โœ“
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Example - Convert Decimal 255 to Hexadecimal:

   DECIMAL 255 TO HEX
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

   Step 1:  255 รท 16 = 15  remainder  15 (=F)  โ† rightmost
   Step 2:   15 รท 16 =  0  remainder  15 (=F)  โ† leftmost
                               โ†‘
                          STOP when quotient = 0

   Read remainders BOTTOM to TOP: FF

   Verification: 15ร—16 + 15ร—1 = 240 + 15 = 255 โœ“
   โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Why it matters: This algorithm is exactly what youโ€™ll implement in code. You need to understand why it works mathematically.

3. String Manipulation

What it is: Numbers arenโ€™t stored as strings, but user input comes as strings, and output goes as strings. You must know how to:

  • Iterate through characters in a string
  • Convert a character to its numeric value (โ€˜7โ€™ -> 7, โ€˜Aโ€™ -> 10)
  • Build up a string character by character
  • Reverse a string

Book Reference:

  • Python: โ€œAutomate the Boring Stuff with Pythonโ€ by Al Sweigart, Chapter 6
  • JavaScript: โ€œEloquent JavaScriptโ€ by Marijn Haverbeke, Chapter 4

Example - Character to Value Conversion:

# How would you convert the string "A5" (hex) to decimal?

# Step 1: Split into characters
characters = ['A', '5']

# Step 2: Convert to numeric values
#   'A' -> 10 (because A is the 10th value after 0-9)
#   '5' -> 5
values = [10, 5]

# Step 3: Apply positional math (base 16)
#   10 ร— 16ยน + 5 ร— 16โฐ
#   = 160 + 5
#   = 165

# The conversion logic:
def hex_char_to_value(char):
    if char.isdigit():
        return int(char)  # '5' -> 5
    else:
        return ord(char.upper()) - ord('A') + 10  # 'A' -> 10, 'B' -> 11, ...

Why it matters: Your entire converter is about transforming string representations of numbers. This is 50% of your implementation.

4. Command-Line Argument Parsing

What it is: Accepting input from the user when they run your program from the terminal.

Book Reference: Python official argparse module documentation

Example:

# The user types:
python converter.py --from hex --to dec FF

# Your program needs to extract:
#   from_base = "hex"
#   to_base = "dec"
#   value = "FF"

Why it matters: A tool that requires code editing to change inputs isnโ€™t a tool - itโ€™s a code snippet. Proper CLI handling makes this professional.

5. Integer Division vs Float Division

What it is: The difference between operations that preserve the decimal part and those that truncate it.

Critical for Python:

# Float division (NOT what you want)
25 / 2  # = 12.5

# Integer division (WHAT you need)
25 // 2  # = 12

# Modulo (the remainder)
25 % 2   # = 1

Why it matters: When you divide 25 by 2, you need the result to be 12 (quotient) and 1 (remainder), not 12.5.

Language-specific notes:

Language Integer Division Remainder
Python x // y x % y
JavaScript Math.floor(x/y) x % y
C/Go x / y (for integers) x % y

Questions to Guide Your Design

Before you write a single line of code, think through these design questions. Your answers will shape your implementation:

Input Handling Questions

  1. How will you handle different input formats?
    • Will you accept FF, 0xFF, 0XFF? What about lowercase ff?
    • Will you accept 11111111, 0b11111111, or both?
    • Should leading zeros be preserved in output?
  2. What about prefixes?
    • Should hex require 0x or allow it optionally?
    • Should binary require 0b?
    • How do you distinguish between them for auto-detection?

Validation Questions

  1. What validation will you implement?
    • What happens if the user inputs "123" but says itโ€™s binary?
    • How will you handle negative numbers? (Twoโ€™s complement is complex)
    • Whatโ€™s the maximum number size youโ€™ll support?
  2. How will you report errors?
    • Generic โ€œInvalid inputโ€ or specific โ€œCharacter โ€˜Gโ€™ is not valid in base 16โ€?
    • Exit codes for scripting compatibility?

Architecture Questions

  1. How will you structure your conversion logic?
    • Option A: Convert everything to decimal first, then to target base
    • Option B: Direct binary<->hex using the nibble relationship
    • Which is simpler? Which is more efficient?
  2. How will you organize your code?
    • Suggested function structure:
      • parse_input(input_string, base) -> returns integer value
      • format_output(number, base) -> returns string representation
      • validate_input(input_string, base) -> returns (bool, error_message)
      • main() -> orchestrates everything

Feature Scope Questions

  1. Should you handle floating-point numbers?
    • Binary/hex floating-point (IEEE 754) is complex
    • Integers-only is perfectly valid for v1.0
    • Document this limitation for your users
  2. What output formats will you support?
    • Just the raw number? (FF)
    • With prefix? (0xFF)
    • With explanation? (FF (hexadecimal) = 255 (decimal))
    • Verbose step-by-step?

Thinking Exercise

Before writing any code, complete these exercises on paper. This builds your intuition and makes the coding phase much easier.

Exercise 1: Manual Conversion Practice (30 minutes)

Convert these numbers by hand, showing all your work:

  1. Decimal 156 -> Binary
  2. Decimal 156 -> Hexadecimal
  3. Binary 10011101 -> Decimal
  4. Hexadecimal A7 -> Decimal
  5. Binary 11011010 -> Hexadecimal (use the nibble trick)
  6. Hexadecimal 3F -> Binary (use the nibble trick)

Check your work (scroll down):

Click to reveal answers
  1. 156 -> 10011100
  2. 156 -> 9C
  3. 10011101 -> 157
  4. A7 -> 167
  5. 11011010 -> DA
  6. 3F -> 00111111

Exercise 2: Algorithm Tracing (20 minutes)

Write out the division-remainder algorithm for converting decimal 89 to binary. Create this table:

Step Division Quotient Remainder
1 89 / 2 44 1
2 44 / 2 ? ?
โ€ฆ โ€ฆ โ€ฆ โ€ฆ

Continue until the quotient reaches 0. Then read the remainders bottom-to-top.

Your answer: 89 decimal = ____ binary

Exercise 3: Edge Case Brainstorming (15 minutes)

List at least 10 potential edge cases or error conditions your program might encounter:

  1. Empty string input
  2. Input containing invalid characters for the specified base
  3. Input โ€œ0โ€ (is the output โ€œ0โ€ or โ€œโ€?)
  4. Very large numbers that exceed your languageโ€™s integer size
  5. Negative numbers (do you support them?)
  6. Input with leading zeros (preserve them? strip them?)
  7. Input with spaces or special characters
  8. NULL/None/undefined input
  9. Base conversion to/from the same base (decimal to decimal)
  10. Mixed case input (0xFF vs 0xff vs 0xFf)
  11. Numbers with leading/trailing whitespace
  12. Unicode characters that look like digits

For each edge case, decide: crash, error message, or handle gracefully?

Exercise 4: Pseudocode First (45 minutes)

Write pseudocode (not real code) for your main conversion functions:

function decimal_to_any_base(decimal_number, target_base):
    if decimal_number is 0:
        return "0"

    digits = empty list

    while decimal_number > 0:
        remainder = decimal_number modulo target_base
        convert remainder to appropriate character (0-9 or A-F)
        add character to beginning of digits list
        decimal_number = decimal_number integer-divided-by target_base

    return digits joined as string

Write similar pseudocode for:

  • any_base_to_decimal(input_string, source_base)
  • validate_input(input_string, base)
  • main_program_flow()

The Interview Questions Theyโ€™ll Ask

If you truly understand this project, you should be able to answer these common interview questions confidently:

Basic Level

  1. โ€œHow would you convert a decimal number to binary without using built-in functions?โ€

    Expected answer: Use the division-remainder algorithm. Repeatedly divide by 2, collect remainders, reverse the result. Time complexity is O(log n) where n is the number.

  2. โ€œWhy do we use hexadecimal in programming instead of binary?โ€

    Expected answer: Hex is more compact and human-readable. One hex digit represents exactly 4 bits, making it a perfect shorthand for binary. The number 255 is FF in hex vs 11111111 in binary.

  3. โ€œWhat is the decimal value of the hexadecimal number 0xCAFE?โ€

    Expected answer:

    • C = 12, A = 10, F = 15, E = 14
    • (12 x 16^3) + (10 x 16^2) + (15 x 16^1) + (14 x 16^0)
    • = 49152 + 2560 + 240 + 14
    • = 51,966
  4. โ€œWhat is 0xFF in decimal?โ€

    Expected answer: 255. Itโ€™s the maximum value of an unsigned 8-bit integer.

Intermediate Level

  1. โ€œHow would you implement a function to check if a string is a valid hexadecimal number?โ€

    Expected answer: Iterate through each character and verify itโ€™s in the set [0-9, A-F, a-f]. Optionally handle the โ€˜0xโ€™ prefix. Use a regular expression for conciseness.

  2. โ€œWhatโ€™s the difference between logical and arithmetic bit shifts?โ€

    Expected answer: Logical shifts always fill with zeros. Arithmetic right shift preserves the sign bit (fills with copies of the MSB). This relates to signed vs unsigned integer representation.

  3. โ€œHow is the number -1 represented in binary using twoโ€™s complement?โ€

    Expected answer: In an 8-bit system, -1 is 11111111. In 16-bit, itโ€™s 1111111111111111. All bits are set to 1. (This extends beyond unsigned integers in your project.)

  4. โ€œHow would you convert between hex and binary without going through decimal?โ€

    Expected answer: Use the nibble relationship. Group binary into 4-bit chunks and map each to a hex digit directly. This is O(n) where n is the number of digits.

Advanced Level

  1. โ€œHow would you optimize base conversion for very large numbers (1000+ digits)?โ€

    Expected answer: Use arbitrary-precision arithmetic (like Pythonโ€™s built-in or GMP library). Consider divide-and-conquer algorithms. For converting between bases that are powers of 2, use bit manipulation directly.

  2. โ€œExplain how floating-point numbers are stored in binary (IEEE 754).โ€

    Expected answer: Sign bit (1), exponent (8 or 11 bits), mantissa (23 or 52 bits). The exponent is biased. The mantissa has an implicit leading 1. Special values for infinity and NaN.

  3. โ€œIf youโ€™re debugging a network packet dump, you see โ€˜0x0A 0x00 0x00 0x01โ€™. What might this represent?โ€

    Expected answer: Could be an IPv4 address (10.0.0.1) in network byte order (big-endian). Shows ability to connect number systems to real protocols.

Behavioral/Design Questions

  1. โ€œWalk me through how you would design a command-line tool for base conversion.โ€

    Expected answer: Requirements gathering, user interface design, error handling strategy, modular architecture, testing approach, documentation, and future extensibility.

  2. โ€œYou discover your converter gives wrong results for numbers above 2^31. How do you debug this?โ€

    Expected answer: Check for integer overflow, use larger integer types or arbitrary-precision libraries, add test cases for boundary values.


Implementation Milestones

Use these milestones to track your progress. Each milestone represents a meaningful checkpoint.

Milestone 1: Basic Decimal to Binary (1-2 hours)

Goal: Implement decimal_to_binary(n) that returns a binary string.

Test cases:

decimal_to_binary(0)   -> "0"
decimal_to_binary(1)   -> "1"
decimal_to_binary(2)   -> "10"
decimal_to_binary(10)  -> "1010"
decimal_to_binary(255) -> "11111111"

You understand: The division-remainder algorithm works.

Milestone 2: Binary to Decimal (1 hour)

Goal: Implement binary_to_decimal(s) that returns an integer.

Test cases:

binary_to_decimal("0")        -> 0
binary_to_decimal("1")        -> 1
binary_to_decimal("1010")     -> 10
binary_to_decimal("11111111") -> 255

You understand: Summing powers of the base works.

Milestone 3: Hexadecimal Conversions (1-2 hours)

Goal: Add hex support with proper character mapping.

Test cases:

decimal_to_hex(0)   -> "0"
decimal_to_hex(15)  -> "F"
decimal_to_hex(255) -> "FF"
decimal_to_hex(256) -> "100"

hex_to_decimal("A")  -> 10
hex_to_decimal("FF") -> 255
hex_to_decimal("100") -> 256

You understand: The hex character mapping (0-9, A-F).

Milestone 4: Input Validation (1 hour)

Goal: Reject invalid input with meaningful errors.

Test cases:

validate("123", binary)  -> Error: '2' and '3' not valid binary
validate("GG", hex)      -> Error: 'G' not valid hex digit
validate("", decimal)    -> Error: empty input
validate("-5", decimal)  -> Error: negative numbers not supported

You understand: Defensive programming and user experience.

Milestone 5: Command-Line Interface (1-2 hours)

Goal: Accept arguments from the command line.

Test cases:

$ python converter.py --from dec --to bin 255
11111111

$ python converter.py --from hex --to dec FF
255

$ python converter.py --help
Usage: converter.py [OPTIONS]
...

You understand: CLI design and user interaction.

Milestone 6: Advanced Features (Optional, 2+ hours)

Goal: Add verbose mode, batch processing, direct binary<->hex conversion.

You understand: The nibble relationship and software polish.


Hints in Layers

If you get stuck while implementing this project, consult these hints in order. Do not skip ahead - the struggle is where the learning happens.

Layer 1: General Direction

Use this if youโ€™re completely stuck on where to start.

  • Break the problem into two separate functions: โ€œany base to decimalโ€ and โ€œdecimal to any baseโ€
  • All conversions can go through decimal as an intermediate step
  • Start with decimal<->binary only, then add hexadecimal once that works
  • Test each function independently before connecting them
  • Write the algorithm on paper first, then translate to code

Layer 2: Algorithmic Hints

Use this if your logic isnโ€™t producing correct results.

For โ€œother base to decimalโ€:

  • Start from the rightmost digit (position 0)
  • For each digit, multiply it by (base^position) and add to running total
  • Example: '1011' binary = (1x2^3) + (0x2^2) + (1x2^1) + (1x2^0) = 8 + 0 + 2 + 1 = 11

For โ€œdecimal to other baseโ€:

  • Use a loop that continues while the number is greater than 0
  • In each iteration: remainder = number % base, then number = number // base
  • Collect the remainders in a list
  • Donโ€™t forget to reverse the list at the end! (or prepend instead of append)

For special case zero:

  • Handle 0 as a special case - return "0" immediately
  • Otherwise your loop never executes (0 is not > 0)

Layer 3: Implementation Hints

Use this if youโ€™re stuck on specific coding details.

For hexadecimal digit conversion:

def hex_char_to_value(char):
    """Convert a single hex character to its numeric value."""
    if char.isdigit():
        return int(char)
    else:
        return ord(char.upper()) - ord('A') + 10

def value_to_hex_char(value):
    """Convert a numeric value (0-15) to its hex character."""
    if value < 10:
        return str(value)
    else:
        return chr(ord('A') + value - 10)

For input validation:

def is_valid_for_base(input_str, base):
    """Check if all characters are valid for the given base."""
    valid_chars = '0123456789ABCDEF'[:base]
    return all(c.upper() in valid_chars for c in input_str)

For handling prefixes:

def strip_prefix(input_str):
    """Remove common prefixes like 0x, 0b, #."""
    if input_str.startswith(('0x', '0X', '0b', '0B')):
        return input_str[2:]
    if input_str.startswith('#'):
        return input_str[1:]
    return input_str

Layer 4: Debugging Hints

Use this if your code runs but gives wrong answers.

  • Print intermediate values to see where the logic breaks:
    print(f"After step {i}: number={number}, remainder={remainder}")
    
  • Test with simple cases first: 0, 1, 2, 10, 15, 16, 255, 256

  • Common bugs to check:
    • Off-by-one errors in loop conditions
    • Forgetting to reverse the result
    • Using / instead of // for integer division
    • Character case issues (โ€˜aโ€™ vs โ€˜Aโ€™)
    • Empty string after removing prefix
  • Verify with known values:
    255 decimal = FF hex = 11111111 binary
    256 decimal = 100 hex = 100000000 binary
    10 decimal = A hex = 1010 binary
    

Layer 5: Optimization Hints

Use this after your solution works and you want to improve it.

  • For binary<->hex, use direct nibble conversion instead of going through decimal:
    NIBBLE_TO_HEX = {
        '0000': '0', '0001': '1', '0010': '2', '0011': '3',
        '0100': '4', '0101': '5', '0110': '6', '0111': '7',
        '1000': '8', '1001': '9', '1010': 'A', '1011': 'B',
        '1100': 'C', '1101': 'D', '1110': 'E', '1111': 'F'
    }
    
  • Add padding for alignment:
    • Pad binary to multiples of 4 for hex conversion
    • Pad binary to multiples of 8 for byte boundaries
  • Add a verbose mode that shows the step-by-step conversion process

  • Support different output formats:
    • Raw: FF
    • Prefixed: 0xFF
    • Padded: 00FF
    • Separated: FF FF FF FF

Books That Will Help

This table maps specific concepts in this project to exact chapters in recommended books:

Topic Book Chapter/Section Why This Helps
Positional Number Systems โ€œCode: The Hidden Language of Computer Hardware and Softwareโ€ by Charles Petzold Chapter 7: Counting, Chapter 8: Binary Arithmetic Builds from first principles; shows why binary is fundamental
Base Conversion Algorithms โ€œIntroduction to Algorithmsโ€ (CLRS) Chapter 3: Growth of Functions Mathematical rigor behind why these algorithms work
Algorithm Design โ€œGrokking Algorithmsโ€ by Aditya Bhargava Chapter 1: Introduction Visual, intuitive approach to algorithmic thinking
String Manipulation (Python) โ€œAutomate the Boring Stuff with Pythonโ€ by Al Sweigart Chapter 6: Manipulating Strings Practical string operations for parsing
Command-Line Tools โ€œPython Cookbookโ€ by Beazley & Jones Chapter 13: Utility Scripting Real-world CLI patterns with argparse
Number Representation โ€œComputer Systems: A Programmerโ€™s Perspectiveโ€ (CS:APP) Chapter 2: Representing and Manipulating Information How computers actually store integers
JavaScript Basics โ€œEloquent JavaScriptโ€ by Marijn Haverbeke Chapter 4: Data Structures If implementing in JS
Bitwise Operations โ€œHackerโ€™s Delightโ€ by Henry S. Warren Jr. Chapter 1: Basics Advanced optimization techniques
Error Handling โ€œThe Pragmatic Programmerโ€ by Hunt & Thomas Topic 23: Design by Contract Philosophy of input validation
Testing โ€œTest-Driven Development with Pythonโ€ by Percival Part I: The Basics How to write tests for your functions
  1. Before coding: Petzold Chapters 7-8, Bhargava Chapter 1
  2. During implementation: Sweigart Chapter 6 (for string handling)
  3. After basic version works: CS:APP Chapter 2 (deeper understanding)
  4. For advanced features: Beazley Chapter 13, Warrenโ€™s โ€œHackerโ€™s Delightโ€

Free Online Resources

  • Khan Academy: โ€œBinary and Hexadecimal Number Systemsโ€ (interactive exercises)
  • Wikipedia: โ€œPositional notationโ€ (mathematical foundation)
  • Python documentation: argparse module (official reference)
  • realpython.com: Command-Line Interfaces tutorials

Self-Assessment Checklist

Before moving to the next project, verify you can:

Conceptual Understanding

  • Explain why 255 = FF = 11111111 without hesitation
  • Convert a 3-digit decimal to binary on paper in under 2 minutes
  • Convert binary to hex using the nibble trick instantly
  • Explain why hex is preferred over binary for displaying bytes
  • Describe the division-remainder algorithm from memory

Implementation Skills

  • Write decimal_to_binary() from scratch without looking at references
  • Write binary_to_decimal() from scratch without looking at references
  • Handle the hex character mapping (0-9, A-F) correctly
  • Validate input and provide meaningful error messages
  • Build a proper CLI interface with help text

Edge Cases

  • Your code handles input 0 correctly (returns "0", not "")
  • Your code handles single-digit inputs correctly
  • Your code rejects invalid characters with clear error messages
  • Your code handles uppercase and lowercase hex digits
  • Your code handles optional prefixes (0x, 0b)

Interview Readiness

  • Can answer โ€œHow would you convert decimal to binary?โ€ clearly
  • Can answer โ€œWhy do we use hexadecimal?โ€ convincingly
  • Can manually calculate 0xCAFE in decimal
  • Can explain the time complexity of your conversion algorithms

Final Milestone

You instinctively see numbers as abstract values with multiple representations. When you see 0xFF, you immediately think โ€œ255, all bits set, maximum byte valueโ€ without conscious effort.


Whatโ€™s Next?

With base conversion mastered, you now understand the fundamental way computers represent information. In Project 2: Hexadecimal Color Visualizer, youโ€™ll apply this knowledge to build an interactive web tool that shows how hex codes like #FF5733 directly correspond to RGB color values. Youโ€™ll see your binary/hex understanding come alive visually.


Quick Reference Card

Keep this handy while working:

โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”
              BINARY/HEX QUICK REFERENCE
โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

NIBBLE TABLE (Memorize This!)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
0=0000  4=0100  8=1000  C=1100
1=0001  5=0101  9=1001  D=1101
2=0010  6=0110  A=1010  E=1110
3=0011  7=0111  B=1011  F=1111

POWERS OF 2
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
2^0 = 1       2^4 = 16      2^8 = 256
2^1 = 2       2^5 = 32      2^9 = 512
2^2 = 4       2^6 = 64      2^10 = 1024
2^3 = 8       2^7 = 128     2^16 = 65536

POWERS OF 16
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
16^0 = 1      16^2 = 256    16^4 = 65536
16^1 = 16     16^3 = 4096   16^5 = 1048576

COMMON VALUES
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
0xFF = 255    (max byte)
0x100 = 256   (1 more than max byte)
0xFFFF = 65535 (max 16-bit)
0xFFFFFFFF = 4,294,967,295 (max 32-bit)

ALGORITHMS
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
To Decimal: Sum of (digit ร— base^position)
To Other Base: Collect remainders of repeated division

โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”

Remember: The goal isnโ€™t just to build a working converter. Itโ€™s to internalize number representations so deeply that you think in multiple bases naturally. Take your time, do the paper exercises, and understand why each step works before coding it.