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

Greetings!

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]

        try:
            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 )
                else:
                    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:

"""
[snip]
        
            {
                "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?

2 Likes

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!

2 Likes

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?

2 Likes

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]
'xyz'

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

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

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.

2 Likes

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.

2 Likes

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

3 Likes

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

2 Likes