Creating a Dictionary

Chris Angelico rosuav at gmail.com
Wed Oct 4 22:24:57 EDT 2017


On Thu, Oct 5, 2017 at 12:24 PM, Stefan Ram <ram at zedat.fu-berlin.de> wrote:
>   One might wish to implement a small language with these commands:
>
> F - move forward
> B - move backward
> L - larger stepsize
> S - smaller stepsize
>
>   . One could start with the following pseudocode for a dictionary:
>
> { 'F': lambda: myturtle.forward( s ),
>   'B': lambda: myturtle.backward( s ),
>   'L': lambda: global s; s *= 2,
>   'S': lambda: global s; s /= 2 }
>
>   . But lambda-expressions cannot contain statements.
>
>   Any other suggestions?

There are a few options here. One is to make use of a simple
"collector decorator":

commands = {}
def cmd(f):
    commands[f.__name__.upper()] = f
    return f

@cmd
def f():
    myturtle.forward( s )

@cmd
def b():
    myturtle.backward( s )

@cmd
def l():
    global siz
    size *= 2

@cmd
def s():
    global siz
    size //= 2

(Also untested, but the pattern is one I've used many times.)

Another is to deploy the whole thing as a class, with no globals:

class Turtle:
    def __init__(self):
        self.size = ...
        self.turtle = ...
    def cmd_F(self):
        self.turtle.forward(self.size)
    def cmd_B(self):
        self.turtle.backward(self.size)
    def cmd_L(self):
        self.size *= 2
    def cmd_S(self):
        self.size //= 2

Note that I've added "cmd_" in front of the names, which means you can
safely getattr(turtle, "cmd_" + letter) and be confident you won't
accidentally grab something that isn't a command.

(Note also that I used // for division. If your size is actually a
float, then change those back to single slashes.)

Either of these patterns would work fairly well. There are others,
too, but I'd be inclined to use one of these.

ChrisA



More information about the Python-list mailing list