The Joys Of Data-Driven Programming

Lawrence D’Oliveiro lawrencedo99 at gmail.com
Wed Aug 17 22:36:19 EDT 2016


Problem: let the user specify certain parameters for a screen display (width, height, diagonal, pixel density, pixels across, pixels down, optimum viewing distance) and from the ones specified, work out the parameters which were not specified.

Solution: set up a table of rules <https://github.com/ldo/screencalc> listing all the ways in which parameters can be computed from other parameters. (The table is called “paramdefs”.)

This one table saves so much code. It is used to drive the command-line parsing:

    opts, args = getopt.getopt \
      (
        sys.argv[1:],
        "",
        list(k + "=" for k in paramdefs)
      )

and again:

    params = dict((k, None) for k in paramdefs) # None indicates unspecified parameter value
    for keyword, value in opts :
        if keyword.startswith("--") :
            param = keyword[2:]
            params[param] = paramdefs[param]["parse"](value)
        #end if
    #end for

and of course the actual parameter dependency determinations and value calculations:

    while True :
        # try to calculate all remaining unspecified parameter values
        did_one = False
        undone = set()
        for param in params :
            if params[param] == None :
                calculate = paramdefs[param]["calculate"]
                trycalc = iter(calculate.keys())
                while True :
                    # try next way to calculate parameter value
                    trythis = next(trycalc, None)
                    if trythis == None :
                        # run out of ways
                        undone.add(param)
                        break
                    #end if
                    if all(params[k] != None for k in trythis) :
                        # have all values needed to use this calculation
                        params[param] = calculate[trythis](*tuple(params[k] for k in trythis))
                        did_one = True
                        break
                    #end if
                #end while
            #end if
        #end for
        if len(undone) == 0 or not did_one :
            break # all done, or can't make further progress
    #end while

I also did the same sort of thing in Java for Android <https://github.com/ldo/screencalc_android>. Guess which version is more concise...



More information about the Python-list mailing list