none
Understanding Palette Program RRS feed

  • Question

  • Hello,

    I am re-studying 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
    Thursday, April 30, 2015 5:52 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 y-value 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 0-43. 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
    Thursday, April 30, 2015 6:47 PM
    Answerer
  • Perhaps this helps

    For y = 1 To 200
      If (Math.Remainder((y-6), 44) <= 40) Then
        result = "True"
      Else
        result = "False"
      EndIf
      TextWindow.WriteLine("y = "+y+" : "+(y-6)+" : "+Math.Remainder((y-6), 44)+" : "+result)
    EndFor

    • Marked as answer by Ezra94 Thursday, April 30, 2015 8:44 PM
    Thursday, April 30, 2015 8:30 PM
    Moderator

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 y-value 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 0-43. 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
    Thursday, April 30, 2015 6:47 PM
    Answerer
  • 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( (y-6) / 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
    Thursday, April 30, 2015 8:08 PM
  • Perhaps this helps

    For y = 1 To 200
      If (Math.Remainder((y-6), 44) <= 40) Then
        result = "True"
      Else
        result = "False"
      EndIf
      TextWindow.WriteLine("y = "+y+" : "+(y-6)+" : "+Math.Remainder((y-6), 44)+" : "+result)
    EndFor

    • Marked as answer by Ezra94 Thursday, April 30, 2015 8:44 PM
    Thursday, April 30, 2015 8:30 PM
    Moderator
  • 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 using
    TextWindow.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
    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 (y-6)/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 = (z-zInt) 'Fractional part of y in x
    rem = frac*y
    TextWindow.WriteLine(rem) 'With a small rounding error


    Thursday, April 30, 2015 9:06 PM
    Moderator
  • 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
    Thursday, April 30, 2015 9:26 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
      

    Friday, May 1, 2015 6:29 PM
    Answerer
  • Hi Coding Cat.

    These modulo examples are very interesting. Do you have any more to share?


    • Edited by Ezra94 Tuesday, June 23, 2015 1:48 AM
    Tuesday, June 23, 2015 1:47 AM