0

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)
NewbCake
  • 433
  • 2
  • 7
  • 22
  • Is there no way to read the current values of the knob from the controller? You need a way to initialize your data to do this kind of thing reliably. Also, you shouldn't define your helper functions in the body of the loop. – Jonah Bishop Nov 27 '18 at 18:00
  • @JonahBishop I can read the value of the knob from 0–127 but those aren't necessarily the numbers I need. I would like it to start from 0, relative from wherever the knob may be. Thanks for the tip, I moved the functions out of the loop. – NewbCake Nov 27 '18 at 18:21

1 Answers1

0

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
Prune
  • 76,765
  • 14
  • 60
  • 81
  • Thanks for the reply @Prune. I updated the code in the post. Is this what you meant by 'Continue with the rest of your code'? It seems to be working. I see the values increasing and decreasing. But as soon asI try to increase again I receive – ValueError: list.remove(x): x not in list – NewbCake Nov 27 '18 at 18:18
  • Which means that you have a separate problem, and should (1) work to debug it yourself; (2) If you're stuck, post a new question. Altering the functionality of a posted question is not a Good Thing, *especially* after you've received valid answers. – Prune Nov 27 '18 at 18:37
  • It's a valid answer, that's fine. Just brought up a new problem that I haven't encountered before. Was hoping for some hint/direction of what is causing the problem. Trying to learn. – NewbCake Nov 27 '18 at 19:00