[Solved] Is there an error in the gopigo3.py library file?


Inviting @cleoqc to the discussion.

I have been studying the gopigo3.py file to understand how to read configuration data into a program at runtime, and I noticed something odd. . .

Note the following segment of the code where the read data is parsed:
[Lines 391 - 406]

            with open(config_file_path, 'r') as json_file:
                data = json.load(json_file)

                # Check for the presence of ticks and positive value
                if 'ticks' in data:
                    ticks = data['ticks']

                # Check for the presence of motor_gear_ratio
                if motor_gear_ratio in data:
                    motor_gear_ratio = data['motor_gear_ratio']

                if data['wheel-diameter'] > 0 and data['wheel-base-width'] > 0 and ticks > 0 and motor_gear_ratio > 0:
                    self.set_robot_constants(data['wheel-diameter'], data['wheel-base-width'], ticks, motor_gear_ratio )
                    raise ValueError('positive values required')

Note that there are two lines in the if stack that read values directly

  • if 'ticks' in data:
  • if motor_gear_ratio in data:

Also note that “ticks” is surrounded by single quotes but “motor_gear_ratio” is not.

Earlier in the file, the structure of the json configuration file is described within a comment block:

                "wheel-diameter": 66.5,
                "wheel-base-width": 117,
                "ticks": 6,
                "motor_gear_ratio": 120

Correct me if I am wrong, but both “ticks” and “motor_gear_ratio” are enumerated values within the configuration json file, and get loaded into a dictionary variable named “data”.

That being the case, shouldn’t “motor_gear_ratio” be quoted since it also appears to be a “key” value in the “data” dictionary?

What say ye?


You are correct. The error is masked by motor_gear_ratio being set to 120 prior, and all motor/encoder “flavors” use the same motor gear ratio of 120.

# default values for ticks and motor_gear_ratio
        # in case they are not present in the file we load up
        ticks = self.ENCODER_TICKS_PER_ROTATION
        motor_gear_ratio = self.MOTOR_GEAR_RATIO

Good catch!


And the reason it doesn’t throw a compile error is because there is both a dictionary key and a variable named motor_gear_ratio, right?


The items in ticks are strings to the interpreter/compiler, and looking for the content of a known variable object motor_gear_ratio as a dictionary key is syntactically legal at interpret/compile time.
At execution time it will be legal even if the content happens to be the number 120.

>>> x = { 120: "xyz", "abc": 100 }
>>> x[120]

NASTY IMO but legal, but then I still get caught by:

>>> y = (8,7,6)
>>> y[2]
>>> y[:-2]
>>> y[-2]

It would have made more sense to me if dictionary elements were x{key} and list elements were y(index) or even more sense to me - y[index], but I have to defer to any language creator as having infinite more sense than me.


That’s interesting.

When I’ve done things like that in the past and used dictionary keys that don’t exist, (or have not been pre-defined), it always flags it as an error/problem.

That’s why, in my robot code, I always pre-define my data structures.  Well, actually for two reasons:

  • It keeps the compiler/linter happy.
  • It helps me keep track of what I’m doing.  :wink:

Otherwise, I end up with a tangled mess that is virtually impossible to figure out.


This has been fixed in the code, btw. Thank you for raising the issue.


You are most welcome.  It is an honor and a privilege to serve.