command-line binary/hex conversion program in python I'm just learning the ropes to programming, so bear with me here. I wanted a simple command-line program to quickly convert decimal numbers into either binary or hexadecimal. This is what I came up with, but I know it can be improved.
while True:
    while True:
        conv_type = input(&quot;Hexadecimal or Binary?: &quot;).lower()
        if &quot;b&quot; not in conv_type and &quot;h&quot; not in conv_type:
            print(&quot;Invalid Input&quot;)
            continue
        else:
            break

    while True:
        try:
            dec_num = int(input(&quot;Decimal Number: &quot;))
        except ValueError:
            print(&quot;Invalid Input&quot;)
            continue
        break

    if &quot;h&quot; in conv_type:
        print(&quot;   &quot;, dec_num, &quot;=&quot;, hex(dec_num), &quot;in hexadecimal&quot;)

    if &quot;b&quot; in conv_type:
        print(&quot;   &quot;, dec_num, &quot;=&quot;, bin(dec_num).replace(&quot;0b&quot;, &quot;&quot;), &quot;in binary&quot;)

How would you improve this? I feel a bit weird using three while True loops in the same program, but I couldn't think of a better solution on the fly. Any feedback is greatly appreciated!
User input validation is annoying, right? My instinct is to ask fewer
questions. Does the user really need to ask for hex or binary? For example, we
could just print both conversions. And if it's a command-line script, couldn't
the decimal number come directly from the command line? Or even a bunch of
decimal numbers and our script could convert them all.
But if we retain your current approach, the repetitiveness of the validation
suggests the need to move code into functions and to create a single function
to handle all input() calls. At a minimum, that function needs a user-prompt
and a function (or callable) that will convert the value and raise an error if
it's invalid. For example, to validate conversion type, we need to lowercase
the input and then make sure it contains a b or h. While we're at it, we
could simplify downstream logic by defining constants for conv_type.
Subsequent code can use strict equality to drive logic (rather than
looser in checks). And in this case, the constant can also serve as a label
when printing.
A consolidated approach to getting user input allows you to address
another issue: how does the user quit the program? However you
decide to handle that, it's handy to be able to do it in one place
rather than multiple.
If you strip off the 0b prefix for binary shouldn't you do the same for hex?
If so, that simplifies the logic, because we can extract the things that vary
into a data structure (converters) and then use that structure to drive the
logic. The result is that most of the &quot;algorithm&quot; in the main() function
fades away and we end up with very little conditional branching. Instead, it
just marches step by step, calling utility functions or accessing data
structures directly. Instead, the algorithmic complexity is delegated to
smaller and more narrowly focused utility functions that are easier to think
about in isolation.
import sys

HEX = 'hexadecimal'
BIN = 'binary'

def main(args):
    # Set up conversion functions and prefixes.
    converters = {
        HEX: (hex, '0x'),
        BIN: (bin, '0b'),
    }

    # Perform conversions.
    while True:
        # Get validated input. Since int() will raise if given
        # a bad input, we get that validation for free.
        conv_type = get_user_input('Hexadecimal or binary', is_conv_type)
        dec_num = get_user_input('Decimal number', int)

        # Convert.
        func, prefix = converters[conv_type]
        converted = func(dec_num).replace(prefix, '')

        # Report.
        print(f'    {converted} = in {conv_type}')

def get_user_input(prompt, validate):
    while True:
        # Get input and provide a way for user to quit easily.
        reply = input(prompt + ': ').lower().strip()
        if not reply:
            sys.exit()

        # Return valid converted input or nag the user.
        try:
            return validate(reply)
        except ValueError as e:
            print(f'Invalid input: {reply}')

def is_conv_type(reply):
    # Takes user input. Returns HEX or BIN if valid.
    reply = reply.lower()
    for conv_type in (HEX, BIN):
        if conv_type[0] in reply:
            return conv_type
    raise ValueError()

if __name__ == '__main__':
    main(sys.argv[1:])