Difference between revisions of "W1513 Patterns of Patterns"

From Coder Merlin
Line 7: Line 7:
== Background ==
== Background ==
Using the tools that we've learned to date, we're able to produce many types of images.  In this lab, we'll focus on defining functions (with sensible parameters) that may then be repeatedly invoked to form patterns.
Using the tools that we've learned to date, we're able to produce many types of images.  In this lab, we'll focus on defining functions (with sensible parameters) that may then be repeatedly invoked to form patterns.
== Prepare ==
{{ScenesShellPrepare|W1513}}


== Experiment ==
== Experiment ==
 
{{StopProgram|Stop the running program.
=== Getting Started ===
Return to the ''console'' and press {{SpecialKey|CONTROL|C}}
[[File:Breathe-document-new.svg|left|50px|link=|Breathe-document-new]]  Begin a '''new''' project
}}
 
Create a new Igis shell project within your "Experiences" directory.
<syntaxhighlight lang="bash">
cd ~/Experiences
git clone https://github.com/TheCoderMerlin/IgisShellD W1513
</syntaxhighlight>
 
Enter into the Sources/IgisShellD directory of the new project.
<syntaxhighlight lang="bash">
cd W1513/Sources/IgisShellD/
</syntaxhighlight>
 
[[File:Start button green arrow.svg|left|link=|Start button green arrow]] Run the project.
<br>
<syntaxhighlight lang="bash">
./run.sh
</syntaxhighlight>
 
Open a browser (or use a new tab on an already-open browser).
Go to the URL:  http://www.codermerlin.com/users/user-name/dyn/index.html
 
NOTE:  You MUST change '''user-name''' to your actual user name.  For example, http://www.codermerlin.com/users/john-williams/dyn/index.html
 
You'll know your successful if you see the title bar change to "Coder Merlin: IGIS".  (The browser window will be blank because we haven't added any graphics yet.)
 
{{notice|[[File:Oxygen480-actions-help-hint.svg|frameless|30px]]|Helpful hint:  It's useful to bookmark this page in your browser.}}


=== First Steps ===
=== First Steps ===
Line 123: Line 100:




[[File:Start button green arrow.svg|left|link=|Start button green arrow]] Run the project. <br/>
{{RunProgram|Run the program and view in a browser before continuing. Be sure to click on the Canvas several times and observe the behavior.}}
View the results in the browser as you did earlier.<br/>
Be sure to click on the Canvas several times and observe the behavior.


=== Exercises ===
=== Exercises ===

Revision as of 15:59, 3 January 2021

Within these castle walls be forged Mavens of Computer Science ...
— Merlin, The Coder
Repetition of Simple Geometric Shapes

Prerequisites[edit]

Research[edit]

Background[edit]

Using the tools that we've learned to date, we're able to produce many types of images. In this lab, we'll focus on defining functions (with sensible parameters) that may then be repeatedly invoked to form patterns.

Prepare[edit]

Create a new Scenes shell project within your Experiences directory:

ty-cam@codermerlin:~$  cd ~/Experiences

ty-cam@codermerlin:~/Experiences$  git clone https://github.com/TheCoderMerlin/ScenesShellBasic W1513


Enter the Sources/ScenesShell directory of the new project:

ty-cam@codermerlin:~/Experiences$  cd W1513/Sources/ScenesShell/


Start button green arrow
Run the program.

ty-cam@codermerlin:~/Experiences/W1513/Sources/ScenesShell$  run


Ensure that you are logged on to the wiki. Then, click on the Tools menu followed by right-clicking on IGIS and selecting the menu item Open in New Window or Open in New Tab.

You'll know you're successful if you see the title bar change to "Coder Merlin: IGIS". (The browser window will be blank because we haven't added any graphics yet.)

Hint.pngHelpful Hint
It's useful to bookmark this page in your browser.

Experiment[edit]

Stop button red ex
Stop the running program.

Return to the console and press CONTROL-C

First Steps[edit]

Let's set up the ability to draw and display a series of patterns. Edit file "main.swift":

emacs main.swift

Edit the file by finding the definition of the Painter class. Before the init constructor, add the following:

    let maxPattern = 9
    var currentPattern = 1
    var didPaint = false

This will enable us to keep track of whether or not we need to paint, and if so, which pattern should be painted.

To indicate the pattern being painted, let's add a function that we can invoke to paint a label on the canvas. Each of the following functions should be added as a method within the Painter class, and before the constructor.

    func paintLabel(canvas:Canvas, patternId:Int) {
        let text = Text(location:Point(x:15, y:40), text:"\(patternId)", font:"30pt Arial")
        canvas.paint(FillStyle(color:Color(.black)))
        canvas.paint(text)
    }

Next, add nine functions for nine different patterns. Each function will have the form paintPatternN(), where N is the number of the pattern to be drawn. For example, the first two functions would be:

    func paintPattern1(canvas:Canvas) {
        paintLabel(canvas:canvas, patternId:1)
    }

    func paintPattern2(canvas:Canvas) {
        paintLabel(canvas:canvas, patternId:2)
    }

Now, add an render method as follows, immediately after the setup method.

    override func render(canvas:Canvas) {
        if let canvasSize = canvas.canvasSize, !didPaint {
           // Clear the entire canvas
           let clearRect = Rect(topLeft:Point(x:0, y:0), size:canvasSize)
           let clearRectangle = Rectangle(rect:clearRect, fillMode:.clear)
           canvas.paint(clearRectangle)

           switch (currentPattern) {
                case 1:
                    paintPattern1(canvas:canvas)
                case 2:
                    paintPattern2(canvas:canvas)
                case 3:
                    paintPattern3(canvas:canvas)
                case 4:
                    paintPattern4(canvas:canvas)
                case 5:
                    paintPattern5(canvas:canvas)
                case 6:
                    paintPattern6(canvas:canvas)
                case 7:
                    paintPattern7(canvas:canvas)
                case 8:
                    paintPattern8(canvas:canvas)
                case 9:
                    paintPattern9(canvas:canvas)
                default:
                    fatalError("Unexpected pattern: \(currentPattern)")
            }
            didPaint = true
        }
    }

Finally, and an onClick() method so that we may cycle through each of the patterns. Note that the onClick() method does not provide us with a Canvas, so we'll need to update our properties in order to impact the next render() and inform it to paint the next pattern.

    override func onClick(location:Point) {
        currentPattern += 1
        if (currentPattern > maxPattern) {
            currentPattern = 1
        }
        didPaint = false
    }


Start button green arrow
Run the program and view in a browser before continuing. Be sure to click on the Canvas several times and observe the behavior.

Exercises[edit]

While working through these exercises:

  • Use well defined functions that do one thing and do one thing well
  • Do not repeat the same functionality in different functions
  • Use appropriate and meaningful names for all elements
  • Ensure that the pattern number remains visible and is not obscured by the pattern

1. Reproduce the below pattern using the function labeled paintPattern1()
IgisShell-Pattern-1.png

2. Reproduce the below pattern using the function labeled paintPattern2()
IgisShell-Pattern-2.png

3. Reproduce the below pattern using the function labeled paintPattern3()
IgisShell-Pattern-3.png

4. Reproduce the below pattern using the function labeled paintPattern4()
IgisShell-Pattern-4.png

5. Reproduce the below pattern using the function labeled paintPattern5()
IgisShell-Pattern-5.png

6. Reproduce the below pattern using the function labeled paintPattern6()
IgisShell-Pattern-6.png

7. Reproduce the below pattern using the function labeled paintPattern7()
IgisShell-Pattern-7.png

8. Reproduce the below pattern using the function labeled paintPattern8()
IgisShell-Pattern-8.png

9. Reproduce the below pattern using the function labeled paintPattern9()
IgisShell-Pattern-9.png

Key Concepts[edit]

Key ConceptsKeyConceptsIcon.png
  • Well-defined functions
    • should do only one thing and one thing well
    • should be relatively short and easy to understand
    • should base output only on input (and perhaps an object's properties)
      • specifically, avoid referencing global variables
    • proper use of parameters enable functions to be reused under different circumstances
  • Best Practices
    • DRY because DIE
      • DRY - Don't Repeat Yourself
      • DIE - Duplication Is Evil