Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Python3.3

Python 3 Code Generator Written in Python 3

5.00/5 (2 votes)
10 Nov 2022MIT5 min read 4.9K   141  
This is a Python 3.x code generation program that generates Python 3 programs.
Python 3 program create_python_program.py version 1.1 generates Python 3 programs that parse command-line arguments and displays the input values. The purpose of this program is to allow rapid creation of the parsing code and the help text for Python 3 programs.

Introduction

This program generates Python 3 programs that parse command-line arguments and displays the input values. The purpose of this program is to allow rapid creation of the parsing code and the help text for Python 3 programs.

If I update this, I will upload again and change the version number, which is currently 1.1.1.

Background

This is a greatly-improved program from the Python 2 version I wrote years ago that can be seen at:

I have mostly stopped using Python 2, and write only Python 3 code now. This new program does much more error-checking and validation of user-input than my old program.

Using the Code

Usage:

python create_python_prog.py <program_name> [parameter 1] [parameter 2} ... [parameter N]

python create_python_prog.py [-h | --help]

About create_python_prog.py

This program generates Python 3 programs that parse command-line arguments and displays the input values. The purpose of this program is to allow rapid creation of the parsing code and the help text for Python 3 programs.

Arguments passed to this program specify the generated program name and the creation of generated program arguments.

Each parameter is a comma delimited list with the form:

<variable_name[=initial_value]>[,parameter_type][,parameter_count_token]
[,-one_char_switch][,--long_switch]

The variable name is required and must be first. The optional parameter_type, optional parameter_count_token, and optional parameter_switch, or switches, may be in any order.

Only the variable name is required. All other items are optional.

Parameter switches must start with either one or two hyphen ('-') characters. An initial value can only be specified for an optional parameter. Optional parameters includes switch parameters and positional parameters that have a parameter_count_token equal to either '?' or '*'.

About variable_name

The variable name must starts with a letter in the English alphabet. The rest of the variable name may contain letters of the English alphabet, or numeric digits, or the underscore character '_'.

If the initial_value for a string contains space characters, then the initial value must be delimited with double quote characters.

The only valid default values for a Boolean parameter are False and True.

About parameter_type

The parameter_type specifier can be one of the following characters. If no initial_value is specified for each of these types, the indicated initial value default is used.

  • s or str - A string parameter, defaults to the empty string, or ''.
  • i or int - An integer parameter, defaults to 0.
  • f or float - A floating point parameter, defaults to 0.0.
  • b or bool - A Boolean parameter, defaults to False. A Boolean parameter must be an optional parameter, i.e., a parameter controlled using a switch that starts with a hyphen character.

If the parameter_type is not specified, then the parameter_type defaults to a string argument.

About parameter_count_token

The optional count token controls the number of arguments that are accepted for specified argument type. If the number is more than one, then the variable specified by the given name will be a Python list. This final optional count parameter is used as 'nargs' in the argument parser code. The nargs parameter would typically be one of the following:

  • * - Accept 0 or more of the argument type
  • + - Accept 1 or more of the argument type
  • ? - The argument is optional
  • [A positive integer greater than zero] - Accept the specified number of arguments, e.g., 2

If the parameter_count_token is not specified, then at run-time, only one value is entered on the command line for that parameter. If the parameter_count_token indicates multiple values, then variable_name will identify a Python list instance, and each value entered will be added to the list by the generated parsing code.

About parameter_switches

An initial hyphen character indicates a parameter_switch. A single hyphen character indicates a single character switch name. Two initial hyphen characters specify a long-name switch.

Both a short-name switch and a long-name switch may be specified.

The '-h' and '--help' switches are implemented automatically and should not be specified as switch parameters. When running the generated program, using either help switch results in the __doc__ string at the start of the generated program being output.

Additional Information regarding Boolean Parameters

A Boolean parameter, with parameter_type 'b' or 'bool', may only be an optional switch parameter. Using the switch for a Boolean parameter in the generated program results in the variable name for the Boolean argument being set to the opposite of the initial_value. If no initial value is specified, then the default for a Boolean parameter is False.

Example Command Lines

python create_python_prog.py foo alpha,i beta,f,+ file_name gamma,b,-g,--gma

This command line generates a program named 'foo.py' that takes an integer parameter named 'alpha', and one or more floating point parameters that are in a list named 'beta', then a string parameter named file_name, and finally an optional parameter named 'gamma' that is a Boolean value that is only 'True' if either the '-g' switch or the '--gma' switch is specified.

python create_python_prog.py foo file_name='bar.txt',?

The ? character in the command line makes the file_name parameter an optional parameter. If no argument is specified, then variable 'file_name' is set to 'bar.txt'.

Addendum

The generated code uses Python's argument parser module. To add arguments, the 'Add_argument' method is used. The 'Add_mutually_exclusive_group' and 'Subparsers' method are not used. If desired, it is relatively easy to modify the generated code to use these additional methods.

Below is a sample generated program that was created using the following command:

python create_python_prog.py foo.py text_desc amount,i value=0.5,f,? maxval,
f,-m,--max display_flag,b,-d,--disp

This is the generated Python 3 program.

Python
#!/usr/bin/env python
"""
    python foo.py <text_desc> <amount> [value] [-m <maxval> | --max <maxval>]
                  [-d <display_flag> | --disp <display_flag>]

    python foo.py [-h | --help]

    TODO: Add usage information here.
"""
import sys
# TODO: Uncomment or add imports here.
#import os
#import re
#import time
#import urllib
#import subprocess
from argparse import ArgumentParser

def foo_main(text_desc, amount, value, maxval, display_flag):
    """ TODO: Add docstring here. """
    # TODO: Add or delete code here.
    # Dump all passed argument values.
    print(f"{text_desc=}")
    print(f"{amount=}")
    print(f"{value=}")
    print(f"{maxval=}")
    print(f"{display_flag=}")
    return 0

# Start of main program.
def main(argv=None):
    # Initialize the command line parser.
    parser = ArgumentParser(description='TODO: Text to display before the argument help.',
                            epilog=f'Copyright (c) 2022 TODO: your-name-here.',
                            add_help=True,
                            argument_default=None, # Global argument default
                            usage=__doc__)
    parser.add_argument(action='store', dest='text_desc', \
                        help='A string value that TODO:')
    parser.add_argument(action='store', dest='amount', \
                        type=int, help='A integer value that TODO:')
    parser.add_argument(action='store', dest='value', \
    type=float, default=0.5, nargs='?', help='A floating point value that TODO:')
    parser.add_argument('-m', '--max', action='store', dest='maxval', \
    type=float, default=0.0, help='A floating point value that TODO:')
    parser.add_argument('-d', '--disp', action='store_true', \
    dest='display_flag', default=False, help='A Boolean value that TODO:')
    # Parse the command line.
    arguments = parser.parse_args(args=argv)
    text_desc = arguments.text_desc
    amount = arguments.amount
    value = arguments.value
    maxval = arguments.maxval
    display_flag = arguments.display_flag
    status = 0
    try:
        foo_main(text_desc, amount, value, maxval, display_flag)
    except ValueError as value_error:
        print(value_error)
        status = -1
    except OSError as os_error:
        print(os_error)
        status = -1
    except MemoryError as mem_error:
        print(mem_error)
        status = -1
    return status

if __name__ == "__main__":
    sys.exit(main())

This is the help output of the generated program shown above:

Python
python foo.py -h
usage:
python foo.py <text_desc> <amount> [value] [-m <maxval> | --max <maxval>]
[-d <display_flag> | --disp <display_flag>]

 python foo.py [-h | --help]

 TODO: Add usage information here.

 TODO: Text to display before the argument help.

positional arguments:
text_desc     A string value that TODO:
amount        A integer value that TODO:
value         A floating point value that TODO: 

options:
-h, --help    show this help message and exit
-m MAXVAL, --max MAXVAL A floating point value that TODO:
-d, --disp   A Boolean value that TODO:

Copyright (c) 2022 TODO: your-name-here.

Points of Interest

It's common to want to print a variable name and a value, such as:

some_variable='variable_value'

Python 3.8 and onward make that very easy using f-strings by adding an equal sign, i.e., '=', after the variable name.
The output above is printed with the following line. This works for string, integer, floating point, and Boolean variables.

Python
print(f"{some_variable=}")

If you're using an earlier version of Python than 3.8, the line above would have to be changed to:

Python
print(f"some_variable={some_variable}")

I believe this is the only feature that has to be changed for earlier versions of Python 3.x.

History

  • Initial upload - Version 1.1
  • Uploaded version 1.1.1 - Fixed a bug in the default value for an optional string variable

License

This article, along with any associated source code and files, is licensed under The MIT License