Answered by:
Understanding Palette Program
Question

Hello,
I am restudying the answer key from the small basic curriculum lesson 4.1. Despite my frivolous observations and attempts to break the code into pieces, I still remain unclear about one aspect of this program. When I press one of the color blocks, It changes the color of the border of the rectangle in the center, however, if I press in between the color blocks (the narrow white gaps in between the colored blocks) the program doesn't response to my actions. I understand the gaps aren't intended to yield any results, but It's this feature that I wish to further discuss and evaluate how this works logically. Where in the program does this occur?
I rewrote the program so that there is only a palette and that allows the user to select any color border based on the block selected.
Here is the program #: FDQ076
Thank you
 Edited by Ezra94 Thursday, April 30, 2015 5:55 PM
Answers

The magic happens here:
Sub OnMouseDown dot = Shapes.AddEllipse(10,10) x = GraphicsWindow.MouseX y = GraphicsWindow.MouseY If y > 50 And y < 446 Then If Math.Remainder((y  6), 44) <= 40 Then paletteIndex = Math.Floor((y  6) / 44) If x > 4 And x < 44 Then GraphicsWindow.PenColor = color[paletteIndex] ElseIf x > 554 And x < 594 Then GraphicsWindow.PenColor = color[paletteIndex + 9] EndIf GraphicsWindow.DrawRectangle(55, 55, 490, 380) EndIf EndIf EndSub
There are four if statements there. The first two confirm that the yvalue is 1) inside the range of colors squares top to bottom, 2) inside of a particular square. The exact code that has it ignoring the white gaps is:
Math.Remainder((y  6), 44) <= 40
Notice how it is dividing (y  6) by 44 and getting the remainder. This will be a number from 043. It then is checking to see if that number is greater than/equal to 40. This will leave a three pixel gap between each box where the if statement ignores the click.
The last two if statements then decide if the mouse is on the left or the right. Between the two of them you get the index into the color array.
Its not a bad way of handling the issue, however the author should have left some comments explaining the need for the remainder.
 Marked as answer by Ezra94 Thursday, April 30, 2015 8:44 PM

Perhaps this helps
For y = 1 To 200 If (Math.Remainder((y6), 44) <= 40) Then result = "True" Else result = "False" EndIf TextWindow.WriteLine("y = "+y+" : "+(y6)+" : "+Math.Remainder((y6), 44)+" : "+result) EndFor
 Marked as answer by Ezra94 Thursday, April 30, 2015 8:44 PM
All replies

The magic happens here:
Sub OnMouseDown dot = Shapes.AddEllipse(10,10) x = GraphicsWindow.MouseX y = GraphicsWindow.MouseY If y > 50 And y < 446 Then If Math.Remainder((y  6), 44) <= 40 Then paletteIndex = Math.Floor((y  6) / 44) If x > 4 And x < 44 Then GraphicsWindow.PenColor = color[paletteIndex] ElseIf x > 554 And x < 594 Then GraphicsWindow.PenColor = color[paletteIndex + 9] EndIf GraphicsWindow.DrawRectangle(55, 55, 490, 380) EndIf EndIf EndSub
There are four if statements there. The first two confirm that the yvalue is 1) inside the range of colors squares top to bottom, 2) inside of a particular square. The exact code that has it ignoring the white gaps is:
Math.Remainder((y  6), 44) <= 40
Notice how it is dividing (y  6) by 44 and getting the remainder. This will be a number from 043. It then is checking to see if that number is greater than/equal to 40. This will leave a three pixel gap between each box where the if statement ignores the click.
The last two if statements then decide if the mouse is on the left or the right. Between the two of them you get the index into the color array.
Its not a bad way of handling the issue, however the author should have left some comments explaining the need for the remainder.
 Marked as answer by Ezra94 Thursday, April 30, 2015 8:44 PM

Hello, Coding Cat. Thank you for the prompt response.
Pardon my inexperience but I remain confused about this line
Math.Remainder((y  6), 44) <= 40
Let's imagine I move my mouse to the y coordinate of 91 pixels. I derived this value by implementing
Sub onMouseMove TextWindow.Clear() TextWindow.WriteLine("X" + GraphicsWindow.MouseX + " Y" + GraphicsWindow.MouseY) EndSub
into the program. When I attempted to click at the y coordinate of 91 pixels and x coordinate of 23 pixels, which is roughly a white gap, it doesn't response. Just as expected. However, I don't understand this logically. Using the equation above( (y6) / 44 ), I subtracted 91 by 6, getting 85 then dividing 85 by 44, which yields a remainder of roughly 1.93. As far as I'm concerned, 1.93 is less than 40, which makes the statement is true, and should allow the button click but it doesn't. To sum it up, when I press the gap at 91 Y and 23 X it doesn't respond and so the statement is false. However, when I calculate for " y " using the equation above, the statement is true. What am I missing?
 Edited by Ezra94 Thursday, April 30, 2015 8:09 PM

Perhaps this helps
For y = 1 To 200 If (Math.Remainder((y6), 44) <= 40) Then result = "True" Else result = "False" EndIf TextWindow.WriteLine("y = "+y+" : "+(y6)+" : "+Math.Remainder((y6), 44)+" : "+result) EndFor
 Marked as answer by Ezra94 Thursday, April 30, 2015 8:44 PM

Hello litdiv,
I saw my mistake.
When I was evaluating the program I used
TextWindow.WriteLine( (y  6) / 44)
With your suggestion, I am now usingTextWindow.WriteLine(Math.Remainder((y  6),44)
Interesting, both lines yield different results. If I replace " y " with 91, the first line of code calculates 1.93 but the second line of code calculates 41. Shouldn't they evaluate the same result? Do you know why?
 Edited by Ezra94 Thursday, April 30, 2015 8:50 PM

Math.Remainder (sometimes called modulo operator) gives you the remainder when you do a division, usually on integers. The remainder is the number left over after whole numbers are removed.
So for y = 91 (y6)/44 is 1.93 or 1 remainder 41 or 1 + 41/44
You could calculate Math.Remainder(x,y) as
x = 85 y = 44 TextWindow.WriteLine(Math.Remainder(x,y)) z = x/y 'Total number of y in x zInt = Math.Floor(z) 'Whole number of y in x frac = (zzInt) 'Fractional part of y in x rem = frac*y TextWindow.WriteLine(rem) 'With a small rounding error
 Edited by litdevModerator Thursday, April 30, 2015 9:07 PM

Okay, I see my mistake again . . . .
I overlooked one fine detail. I assumed that math remainder yields the same results as division. They both divide but math remainder gets the remainder of the result. Quite frankly, I was trying too hard to remember that distinction and still forgot. Thank you litdiv and Coding Cat for the clarification.
 Edited by Ezra94 Thursday, April 30, 2015 9:35 PM

As it turns out, Modulo Arithmetic, or doing math with whole numbers only, is a really important topic in computer science. Keep in mind that the computer uses switches to represent binary digits. In other words, there is no such thing as a decimal in side of the computer. Actually, with the first PC's the main chip (the 8086) was unable to do decimal operations at all. You needed a separate chip (the 8087) or you needed software to fake it. Even now the computer fakes it by using scientific notation to locate the decimal point in the number. This is where the term "Floating Point" comes from.
Even if you discount the value of understanding the workings of the computer, you will find lots of uses for knowing the reminder of division:
num = 1 score = 5000000 'Divide by two, remmainder of 0 = even, 1 = odd If Math.Remainder(num,2) = 0 Then TextWindow.WriteLine("Even") Else TextWindow.WriteLine("Odd") EndIf 'This will tell us if the score is an event multiple of 1000000 If Math.Remainder(score, 1000000) = 0 Then TextWindow.WriteLine("Free Game Awarded") EndIf 'The count from 0 to 10 will repeat itself without 'the need of having an if statement to reset to zero. count = 0 While "True" count = Math.Remainder(count+1, 10) TextWindow.Write(count + " ") Program.Delay(100) EndWhile
