Chemostat Automation Troubleshooting - Error: '>' not supported between instances of 'str' and 'float'

Hello! I am trying to troubleshoot an error reoccurs when I run the Chemostat automation. Here is a log the error.

2022-12-29T19:54:10+0000 [dosing_automation] [app] INFO ErrorOccurred: '>' not supported between instances of 'str' and 'float'
2022-12-29T19:55:10+0000 [dosing_automation] [app] DEBUG '>' not supported between instances of 'str' and 'float'
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/dist-packages/pioreactor/automations/dosing/base.py", line 255, in run
    event = self.execute()
  File "/usr/local/lib/python3.9/dist-packages/pioreactor/automations/dosing/chemostat.py", line 33, in execute
    volume_actually_cycled = self.execute_io_action(media_ml=self.volume, waste_ml=self.volume)
  File "/usr/local/lib/python3.9/dist-packages/pioreactor/automations/dosing/base.py", line 302, in execute_io_action
    elif media_ml > max_:
TypeError: '>' not supported between instances of 'str' and 'float'

I am new to both Raspberry Pi and Python, so sorry if I am missing something obvious. I would appreciate any advice on how to fix the issue or how I could try troubleshooting this type of issue myself.

Troubleshooting
I believe the problem is that when Python runs “elif media_ml > max_” in base.py, line 302, there is an error because either “media_ml” or “max_” is a string and the other is a float. Since “max_” is defined as “max_ = 0.625” in base.py, line 292, I believe “max_” is a float and “media_ml” must therefor be the string.

Since the error occurs when I run the Pioreactor through the web UI, I can think of several different causes for the error: (1) the web ui input type is stored as a string; (2) when a chemostat class is initialized, the input defaults to string and not float; or, (3) a chemostat class is initialized with the input as a float, but the float is converted into a string somewhere along the way.

1. web ui input type stored as string
I looked in chemostat.yaml to try and find more information about the web ui input but don’t see anything that helps.

2. the chemostat class is initialized with the input as a string.
Using the default values, I believe this would be: Chemostat( “chemostat”, duration = 20, volume = 0.5). Then, in chemostat.py:

class Chemostat(DosingAutomationJob):
...
Line 30    self.volume = volume # volume should be 0.5, but I don't know whether  it is a float or string
...
Line 33                   volume_actually_cycled = self.execute_io_action(media_ml=self.volume, waste_ml=self.volume)

I am not sure how to go about troubleshooting/debugging this area. I believe it is possible in Python to pause when this code is run and reaches Line 32. How could I do this (or what terms should I Google), and what Python commands could I use to get information on variables like “volume,” “self.volume,” or “media_ml” after entering “media_ml = self.volume”

  1. The float might be converted to a string when self.execute_io_action(media_ml = self.volume, waste_ml=self.volume)

I have looked through automations/dosing/base.py, but nothing jumped out at me as causing a float → string conversion.

Anyways, sorry for the wall of text. I am fairly new to both programming and Raspberry Pi, so I am not really sure how to continue troubleshooting this issue. Thanks!

Hi @realPeteDavidson!

You’ve provided lots of information to help debug! Let’s see. I’ll walk you through how I see the problem (some of this has been discovered by you, too):

  1. The elif media_ml > max_ suggests that the problem is indeed media_ml, since max_ is hardcoded to 0.625, a float.
  2. Moving up the stack, the chemostat code runs self.execute_io_action(media_ml=self.volume, waste_ml=self.volume). Okay, so why is self.volume a string?
  3. If I try invoking the following from the command line (this is a low level command that you are actually running): pio run dosing_control --automation-name chemostat --skip-first-run 0 --duration 20 --volume 0.5, I encounter the same error too.

The good news is I’m able to reproduce this problem locally, so it’s not an error on your end. Looking at the code in chemostat.py, if volume is a string, then self.volume is a string, too. In fact, I recently removed casting to a float (that change was made only a few weeks ago). Looking deeper into how the Chemostat class is instantiated, we should expect strings here since the value for volume comes from the command line (ex: see my pio command above). So me removing the casting to a float was an error.

A fix

I’ve added back that casting in our codebase as a fix. You can update to the latest code by logging into your Raspberry Pi and running pio update --app -b master on the command line. I’m happy to help with this process if you get stuck here, too - just let me know! This fix is now merged and available with the latest release.

Future proofing

I’ve also added a test to prevent me making the same mistake again!

1 Like

Thanks @CamDavidsonPilon . I updated my Pi using your command and the Chemostat automation is working for me now. I just have one last clarification request.

Looking deeper into how the Chemostat class is instantiated, we should expect strings here since the value for volume comes from the command line (ex: see my pio command above).

Would you be able to expand on this part? When instantiating a class via the command line, will all values default to string type? If I typed the following (before updating my pi):

pio run dosing_control --automation-name chemostat --skip-first-run 0 --duration 20 --volume float(0.5)

Would volume be a string of value “float(0.5)”, or would volume be a float of value “0.5”?

Would volume be a string of value “float(0.5)”, or would volume be a float of value “0.5”?

The former. When working with the command line, it’s up to the program (the context) to parse the inputs as string, floats, etc. for downstream use. The library we use, click, will default to strings if not specified.