<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def main(argv=None):
 """ Entry point for the command line tool 'uflash'. Will print help text if the optional first argument is "help". Otherwise it will ensure the optional first argument ends in ".py" (the source Python script). An optional second argument is used to reference the path to the micro:bit device. Any more arguments are ignored. Exceptions are caught and printed for the user. """

    if not argv:
        argv = sys.argv[1:]

    parser = argparse.ArgumentParser(description=_HELP_TEXT)
    parser.add_argument('source', nargs='?', default=None)
    parser.add_argument('target', nargs='*', default=None)
    parser.add_argument('-r', '--runtime', default=None,
                        help="Use the referenced MicroPython runtime.")
    parser.add_argument('-e', '--extract',
                        action='store_true',
                        help=("Extract python source from a hex file"
                              " instead of creating the hex file."), )
    parser.add_argument('-w', '--watch',
                        action='store_true',
                        help='Watch the source file for changes.')
    parser.add_argument('-m', '--minify',
                        action='store_true',
                        help='Minify the source')
    parser.add_argument('--version', action='version',
                        version='%(prog)s ' + get_version())
    args = parser.parse_args(argv)

    if args.extract:
        try:
            extract(args.source, args.target)
        except Exception as ex:
            error_message = "Error extracting {source}: {error!s}"
            print(error_message.format(source=args.source, error=ex),
                  file=sys.stderr)
            sys.exit(1)

    elif args.watch:
        try:
            watch_file(args.source, flash,
                       path_to_python=args.source,
                       paths_to_microbits=args.target,
                       path_to_runtime=args.runtime)
        except Exception as ex:
            error_message = "Error watching {source}: {error!s}"
            print(error_message.format(source=args.source, error=ex),
                  file=sys.stderr)
            sys.exit(1)

    else:
        try:
            flash(path_to_python=args.source, paths_to_microbits=args.target,
                  path_to_runtime=args.runtime, minify=args.minify)
        except Exception as ex:
            error_message = (
                "Error flashing {source} to {target}{runtime}: {error!s}"
            )
            source = args.source
            target = args.target if args.target else "microbit"
            if args.runtime:
                runtime = "with runtime {runtime}".format(runtime=args.runtime)
            else:
                runtime = ""
            print(error_message.format(source=source, target=target,
                                       runtime=runtime, error=ex),
                  file=sys.stderr)
            sys.exit(1)