In addition to the initial correction of not using
not with every other transition, to smooth things out you need to:
Maintain state (already down and already up) for the button independently, so that the loop doesn't count holding the button down as multiple presses.
Include a bit of "debounce time", also maintained as an aspect of the button -- which points to the conclusion that
button should be a simple class with several characteristics, one tracking its state and one tracking the debounce time. More on this below. In this case, you don't have to create a class, but if you want to use multiple buttons in the same program, you should.
I have an example of this in perl here, but since the focus is not really implementing a button (although it is used as an example), and it is more callback style event based, it may not be easy to follow.
Here are some constraints that your example demonstrates:
You want the loop to be running continuously, because you could push the button at any point, but you should avoid "busy looping" which will consume all of one processor. This means you need a brief sleep in the loop, as per goobering's example. Since no one is likely to be able to be able to push a button up and down in less than 1/20th of a second, you could use 50 ms. However, to start use 250 ms, and keep that in mind as you get it working; push a button down, and hold it at least half a second. This should ensure the loop catches the event.
When a button is pushed down and held for an arbitrary length of time, that should trigger one state change, not one for every iteration of the loop while the button is held down. I don't think goobering's code accounts for this. The 100 ms sleep time will cover debouncing and prevent busy looping, but not this issue.
To deal with the latter problem, you need to track the current state of the button with a simple boolean variable (as per #1 above); when the state of the pin indicates the button is down, you set this variable, and discard subsequent such readings until the state of the pin changes back to up, at which point you change the variable tracking the button state. Only when there is a contrast between the GPIO state and your tracking of the button state do you trigger an event/transition from one color to the next. This means the button can be held down for an arbitrary length of time, but it only counts as one push.
There is a further minor complication though.
As per the wikipedia blurb, contact buttons have a tendency, when first pushed down, to create an oscillating response over a very short time period (milliseconds). If you are using a 100+ ms sleep in your loop, that should cover it. However, in the general case this may add a noticeable bit of latency in response time and make it possible, if you try hard and have the right button, to click it quickly during the sleep, meaning that will be ignored. 50 ms makes this harder, but ideally you want to use event callbacks here anyway instead of a loop, since a GPIO can generate genuine interrupts for the operating system. Responding to those is what will give you the most optimal responsiveness and means you don't need to use any sleep at all. This is what is going on in that other answer with the perl example.
Again, in this case, with a single button, you can use the loop with the brief sleep. As you get into more complicated things, however, keep this debouncing issue in mind. Unless you are going to use a per button thread (which is probably silly), you don't want to use a sleep to debounce. You want to maintain a second variable per button, in addition to the one tracking its state: when the state changed last. You then ignore any changes which take place within a short time which may vary from button to button. I have seen people using 100+ ms bounce times; I think this is way too much and indicates there is something else wrong or the button is very awkward.1 In the perl example it looks like I used 10 ms, and I remember testing that one pretty thoroughly. In the oscilliscope image from wikipedia, the bounce is < 5ms (but we don't know what it is from).
50 ms may be a good compromise. I believe I started with 100 and worked my way down; I think 100 is too much because it complicates getting a clean response when clicking the button quickly -- it must not overlap the point the button is released, because then the variable tracking the button state will be out of phase.
But for now, with your loop and a single button, using a sleep in the loop, starting at 250 ms and working down experimentally, remembering to press and hold the button for at least 1/2 second, should deal with it. The main issue is tracking the button state so the loop does not count one push as a push for every iteration of the loop.
I don't code in python so I can't give you a concrete example, but again, since you are using a loop and one variable, it could simply be another global state variable. Then in each loop iteration:
If the GPIO state says the button is up, set the variable to indicate this.
If the GPIO state says the button is down, and the variable says the button is up, set the variable to indicate this and trigger an event/state transition for the LED. Otherwise just ignore it. Then when the button is released the variable tracking it will be changed, ready for the next press.
1. I've seen people use much more than that, 0.5 - 1 second plus. This is a case where "debounce" is being confused or conflated with the issue of the button being held down and released. That's fine in some contexts but in the general case it is a mistake.