Search code examples
pythonlistcountmidimido

Python add/subtract counter by comparing last to second-to-last values


I am trying to count the number of items in a list by adding/subtracting depending on certain conditions.

For a bit more context: I have Midi controller that outputs Midi data whenever a knob is turned. Regardless of where the knob is, I want to counter to reset to 0, and as it turns in one direction then increase the value and decrease in the other direction.

Each midi message outputs something like this:

control_change channel=0 control=16 value=5 time=0
control_change channel=0 control=16 value=6 time=0
control_change channel=0 control=16 value=7 time=0

So I figure I can check if the next received messages is either greater or less than the previous message.

The problem I am running into is that having an index like:

second_to_last_message = messages[-2]

Automatically produces IndexError: list index out of range which makes sense because you can get the second-to-last item in an empty list. But I'm not sure how I can check if the value is increasing or decreasing without a check like that...feels like a catch-22.

Also I am not sure whats the best way to implement the counter. I would be grateful for any ideas of how to approach this.

CODE

messages = []
for msg in inport:

   def add(msg):
       messages.append(msg)

   def subtract(msg):
       messages.remove(msg)

   last_message = msg
   second_to_last_message = messages[-2]

   if last_message.value > second_to_last_message.value:
       add(msg)
       print len(messages)


   elif last_message.value < second_to_last_message.value:
       subtract(msg)
       print len(messages)

UPDATED CODE

messages = []
def add(msg):
    messages.append(msg)

def subtract(msg):
    messages.remove(messages[-1])

for msg in inport:
    if len(messages) < 2:
        add(msg)
        print len(messages)

    else:
        last_message = msg
        second_to_last_message = messages[-2]

        if last_message.value > second_to_last_message.value:
            add(msg)
            print len(messages)

        elif last_message.value < second_to_last_message.value:
            subtract(msg)
            print len(messages)

Solution

  • You simply need to check whether you have a next-to-last element before you reference it:

    if len(messages) < 2:    # Not enough messages accumulated: 
                             #   add this one without checking the value
       add(msg)
       print len(messages)
    
    else:
       second_to_last_message = messages[-2]
       # Continue with the rest of your code