-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
1190 lines (1133 loc) · 46.8 KB
/
index.html
File metadata and controls
1190 lines (1133 loc) · 46.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<!-- sidebar -->
<div class="clearfix">
<div class="column sidemenu">
<ul>
<li><a href="#introduction">Introduction</a></li>
<li><a href="#designrecipe">The Design Recipe</a></li>
<li><a href="#INSERT NAME HERE">INSERT NAME HERE</a></li>
<li><a href="#INSERT NAME HERE">INSERT NAME HERE</a></li>
<li><a href="#INSERT NAME HERE">INSERT NAME HERE</a></li>
<li><a href="#INSERT NAME HERE">INSERT NAME HERE</a></li>
<li><a href="#INSERT NAME HERE">INSERT NAME HERE</a></li>
<li><a href="#INSERT NAME HERE">INSERT NAME HERE</a></li>
</ul>
</div>
<div class="column content">
<div class="header">
<h1>
Design Functions in Java
</h1>
<p style="text-align:center;">
<i>By Rowan Weir, Daniel Barnas, Allan Schougaard</i>
</p>
</div>
<!-- ADD SOURCE FILES FOR ALL EXAMPLES AND CHALLENGES -->
<!-- INTRODUCTION -->
<h2 id="introduction"> Introduction</h2>
<p>
To start, we have learned various Data Types and how they behave/interact in different ways when programming. ADD MORE; like class, object, method summaries.
</p>
<!-- SECTION 1 -->
<h2 id="designrecipe">The Design Recipe</h2>
<!-- Insert ordered list-->
<p>
Fill in Recipe Components
</p>
<p>
Fill in Recipe Components
</p>
<p>
Fill in Recipe Components
</p>
<p>
Fill in Recipe Components
</p>
<p>
The steps in the design recipe can be broken down as follows: **UP FOR DISCUSSION EXACTLY WHAT STEPS WITHIN THE RECIPE WE WANT**
<ol>
<li>Purpose</li>
<li>Signature</li>
<li>Template</li>
<li>Code</li>
</ol>
</p>
<!-- SECTION 1.1 -->
<h3 id="Purpose">Purpose</h3>
<p>
FILL IN PURPOSE DESCRIPTION
</p>
<p>
FILL IN PURPOSE EXAMPLES
<br>
Here is our challenge:
<code class="block">
Create a function that squares any number.
</code>
A good way to begin writing purpose statements is to follow this basic format:
<code class="block">
; Purpose : Given ..., returns ...
</code>
What you are <i>given</i> is your input.
What you <i>return</i> is the function's expected output.
<br>
This may seem overly simplified, but knowing these two components of your function from the very beginning can really help you a great deal later on.
<br>
For the purpose statement of this function, we could write the following:
<code class="block">
; Purpose : Given any number, returns that number raised to the second power.
</code>
Keep in mind that a purpose statement should be fairly short, around 1-2 lines of comments.
If you find yourself needing more than that, it may be a sign that the function you're trying to write could be broken up into smaller functions.
If you cannot clearly and succinctly come up with a purpose statement that fits within two lines, the function you are trying to write can likely be broken down into a few functions of lesser complexity.
<div class="question">
Consider a pre-existing function that you already know.
If you were to write that function, what might the purpose statement be?
</div>
<div class="question">
What about a graphics function, like <code>overlay</code> or <code>rotate</code>?
</div>
</p>
<!-- SECTION 1.2 -->
<h3 id="Signature">Signature</h3>
<p>
FILL IN SIGNATURE COMPONENTS
<br>
Let's proceed with our example to get a better idea of what a signature should look like.
<code class="block">
; Signature : Number → Number
</code>
Note the arrow seperating our two datatypes.
The presence of the arrow indicates the datatype(s) on the left side are what we expect to input, and the type(s) on the right are what we expect the function to return.
It is another way of saying <code> Given ... → Returns ... </code>
Note also the capitalization of Number and Number.
Capitalization in the signature denotes a datatype in these notes.
<br>
Our function accepts a number, and is expected to produce a number as well.
Specifying the signature of a pre-existing function can be a way to better understand what that function does.
For example, the signature of the <code>place-image</code> would be:
<code class="block">
; Signature : Image Number Number Image → Image
</code>
<div class="question">
What would the signature be for a graphics function that produces a shape, like <code>ellipse</code> or <code> radial-star </code>?
</div>
</p>
<!-- SECTION 1.3 -->
<h3 id="Template">Template</h3>
<p>
FILL IN TEMPLATE COMPONENTS
</p>
<p>
In the case of our <code>squared</code> function, we know that when squaring a number, you multiply it by itself.
So, we know we will likely need to use <code>*</code>, the multiplication function.
<code>*</code> requires two arguments, but we don't need to be specific yet, so we can just include <code>...</code> where those inputs will go.
<code class="block">
; Template :
(define (square-number num)
(* ... ...)
)
</code>
At this stage you can also check that your syntax and formatting is correct.
You can run the template and it will tell you if all parentheses are in the right place.
In the next section, we will fill out the gaps in our template.
</p>
<!-- SECTION 1.3 -->
<h3 id="Code">Code</h3>
<p>
FILL IN CODING COMPONENTS
</p>
<p>
Looking at our template, what arguments should we replace the <code>...</code> spaces with?
<code class="block">
; Code :
(define (square-number num)
(* num num)
)
</code>
</p>
<p>
Now we can run our code and see if our function passes the tests we set.
<a class="try-it" href="src/square-number.rkt" download>Try It</a>
</p>
<!-- Section 2 -->
<h2 id="stop-sign"> Stop Sign </h2>
<p>
Stop signs are ubiquitous, and generally share the same distinctive design regardless of the country they appear in.
A red octogon accompanied by white text is the international standard.
Many countries use the English word "STOP" on their signs, with others electing to use their local language instead.
</p>
<p>
In this example, we want to write a function that produces a stop sign.
This function will take a text input, and return the image of a stop sign with the text displayed in white letters.
<code class="block">
Create a function that produces the image of a stop sign, with text determined by the user.
</code>
Let's apply the design recipe to this problem.
Recall that for the purpose statement, we want to briefly explain what our function will return, and which inputs it will require.
<code class="block">
; Purpose : Given a string of text, return the image of a stop sign displaying that text.
</code>
The general idea behind our function is pretty simple.
When given a string of text, the function should return a stop sign with that text on it.
Our requirements for this function are made clear by the purpose statement, so we can write the signature right away.
<code class="block">
; Signature : String → Image
</code>
This signature gives us a very basic form of how our function will be used, in addition to stating the input and output type(s) we are expecting to use and produce.
</p>
<p>
The <code>check-expect</code> function that we use to test our functions requires a specific example of an input value and the return value that would result.
This is not generally problematic when writing functions that contain simple datatypes such as numbers or strings, but can be more difficult when our expected output is an image.
One way to utilize the <code>check-expect</code> function in this context is to create the image our function will produce prior to coding the function itself.
This gives you a finished example that you can then test your function against.
<br>
For detailed information on how to produce images themselves, see our previous chapter. <!-- Link to previous chapter. -->
<br>
As we want to test stop signs in other languages as well, we should create another stop sign with the word "ALTO".
You can find both examples here, if you want to use them in our own testing. <!-- Place TRY IT with code here -->
</p>
<p>
Now that we have our example images, we can write the tests for our function.
We also want to pick a descriptive name, using the verb-noun naming convention.
<code class="block">
; Examples :
(check-expect (make-stop-sign "STOP") <img src="images/stop-sign.png" width="20%"> )
</code>
The last argument that check-expect takes is the expected result of the function call.
In this case, we can either copy and paste the image itself, or the code used to create the image.
These are ultimately equivalent so the choice is up to you.
</p>
<p>
Usually, the more test cases we provide, the better.
We've already created a Spanish language stop sign, so let's make a test featuring that image as well.
<code class="block">
; Examples :
(check-expect (make-stop-sign "ALTO") <img src="images/alto-sign.png" width="20%"> )
</code>
</p>
<p>
Next, we write the stub.
Remember that the stub mimics a full function definition, with a bogus value in place of code.
<code class="block">
; Stub :
(define (make-stop-sign str) "stop-sign")
</code>
The parameter being used here is <code>str</code>, which indicates that our expected input is a string.
</p>
<p>
<code class="block">
; Template :
(define (make-stop-sign str)
(overlay
(text ... ... ...)
(regular-polygon ... ... ... ...)
)
)
</code>
</p>
<p>
<code class="block">
; Code :
(define (make-stop-sign str)
(overlay
(text str 75 "white")
(regular-polygon 100 8 "solid" "red")
)
)
</code>
<a class="try-it" href="src/stop-sign.rkt" download>Try It</a>
</p>
<div class="question">
Challenge : Now that you know how to create a function that produces a stop sign, can you figure out how to build a similar function that instead produces a yield sign?
<br>
Here is an example you might use when completing the recipe.
Note the expected return datatype, which is the image you want your function to make.
</div>
<code class="block">
; Examples :
(check-expect (make-yield-sign "YIELD") <img src="images/yield-sign.png" width="30%"> )
</code>
<!-- Section 3 -->
<h2 id="counterchange"> Counter-Change </h2>
<p>
For our next challenge, we will use the recipe to write a counter-change function.
A counter-change is when you have two images create a 2-by-2 checkerboard pattern with each image at opposite corners.
</p>
<p>
As usual, the first step of the recipe is the purpose statement.
Remember that the purpose should succinctly describe what the function is going to take as inputs, and what it will return.
In this case, our function will take two images as inputs, and will return a single image of the original two images counter-changed.
The following purpose statement captures the general idea effectively.
<code class="block">
; Purpose : Given two images, return a checkerboard image comprised of those the two image arguments.
</code>
</p>
<p>
Next we create the signature.
The signature should capture the purpose in terms of the data types that our function will take as inputs, and the datatype that it will return.
In this case, our function will be taking two images, and then returning a single image based on the two input images.
<code class="block">
; Signature : Image Image → Image
</code>
</p>
<p>
We need to create an example that will test our function.
Recall that this step allows us to outline the exact specifications of our function, and to define what we want our function to return.
The process of creating examples should also serves to provide us with a general outline for how our function will work.
This will help us when it comes time to write code.
<code class="block">
; Examples :
(check-expect (make-counter-change (square 100 100 "red") (square 100 100 "cyan")) <img src="images/counter-change.png" width="50%"/>)
</code>
</p>
<p>
With our tests and examples in place, it is time to write the stub.
Recall that the purpose of the stub is simply to get our tests to run, and not to pass.
This will assure us that our function header is written correctly.
<code class="block">
; Stub :
(define (make-counter-change image-1 image-2) "checkerboard")
</code>
</p>
<p>
The next step in the recipe is to construct a template.
The template should be a skeleton of what our eventual function will look like.
We need to consider what functions we may need to use to get our intended output.
Most likely, we will need to stack two rows of images to create the full image.
For this we can use the <code>above</code> function.
It requires two arguments, which we can fill in later.
<code class="block">
; Template :
(define (make-counter-change image-1 image-2)
(above
...
...
)
)
</code>
We could move on to the coding step of the recipe at this point, but let's see if we can make our template slighty more detailed.
<br>
The above function will stack two rows, but how might we make the rows themselves?
Each row needs to be two images next to each other.
The <code>beside</code> takes two images and places the second beside the first.
Given what our template looks like right now, we can replace the empty arguments with this function.
<br>
Do you see how this template will stack two rows of images once it is filled out?
<code class="block">
; Template :
(define (make-counter-change image-1 image-2)
(above
(beside ... ...)
(beside ... ...)
)
)
</code>
</p>
<p>
Now it is time to code our function.
The benefit of using the recipe is that we should have already gone through the process of creating a template, and the only thing left to do is fill it in with the appropriate parameters.
</p>
<p>
Check out our code below for the <code>make-counter-change</code> function.
Did you write it the same way?
<code class="block">
; Code :
(define (make-counter-change image-1 image-2)
(above
(beside image-2 image-1)
(beside image-1 image-2)
)
)
</code>
<a class="try-it" href="src/counter-change.rkt" download>Try It</a>
</p>
<div class="question">
You can, of course, use this function with any images.
<br>
Try it with the folowing two images:
<img src="images/peach1.png"/>
<img src="images/cherry1.png"/>
</div>
<div class="question">
Challenge : Using these two images, can you alter the function you just made so when it returns the final image, all images are oriented like they are in this <code>check-expect</code>?
<br>
Hint: use <code>flip-horizontal</code>.
</div>
<code class="block">
(check-expect (flip-counter-change <img src="images/peach1.png" width="30%"/> <img src="images/cherry1.png" width="30%"/>) <img src="images/counter-cherry-peach.png" width="50%"/>)
</code>
<!-- Section 4 -->
<h2 id="bulls-eye"> Bulls-Eye </h2>
<p>
For our next example, we will create a function that takes two colors as string inputs, and returns a dart-board of concentric circles, with each circle alternating in color.
The dart-board should have a radius of 100 pixels, and each concentric circle should have a radius that is 10 pixels less than the previous circle.
</p>
<p>
As usual, we begin with our purpose.
This will help us make sure that we know how our function should behave.
<code class="block">
; Purpose : Given two colors, return an image of a bulls-eye comprised of those colors.
</code>
</p>
<p>
Our purpose statement should have hopefully made it clear that our function will need two colors as inputs.
Available preset colors are given as <code>strings</code>.
For clarity, we can note that the <code>string</code> inputs represent colors.
Our function will return an image.
<code class="block">
; Signature : String String → Image, where all strings are colors
</code>
</p>
<p>
Next we create an example to test our function, following the same format as in previous challenges.
<code class="block">
; Examples :
(check-expect (make-bulls-eye "hotpink" "deepskyblue") <img src="images/bulls-eye.png" width="30%"/>)
</code>
</p>
<p>
With our example written, we are ready to create the stub and check if the examples are able to run.
It is in the stub that we will name the the parameters our function will take.
</p>
<p>
Try running with the stub below.
The examples should execute successfully, even though our function will fail.
<code class="block">
; Stub :
(define (make-bulls-eye color-1 color-2) "bulls-eye")
</code>
</p>
<p>
With the example successfully executing when we run the code, we are ready to create a template of our function.
</p>
<p>
For our template, we need to consider what functions will be necessary to build the image of a bulls-eye.
We need to create many circles, and layer them on top of each other.
<br>
The <code>circle</code> function will definitely be used.
Placing the circles on top of one another could be accomplished using a couple different functions, but in our example we are going to use <code>overlay</code>.
Remember that <code>overlay</code> requires at least two images as arguments, and the <code>circle</code> function requires three.
<br>
Knowing this, we can create the following template:
<code class="block">
; Template :
(define (make-bulls-eye color-1 color-2)
(overlay
(circle ... ... ...)
(circle ... ... ...)
)
)
</code>
We don't need to worry about what the circles will look like yet, or how many we will use.
We can take care of that when we code our function, which is next.
</p>
<p>
Looking at our example, how many circles will be required to make the expected image?
<br>
Let's add spaces for those, before we fill out the details of each one.
<code class="block">
; Code :
(define (make-bulls-eye color-1 color-2)
(overlay
(circle ... ... ...)
(circle ... ... ...)
(circle ... ... ...)
(circle ... ... ...)
(circle ... ... ...)
(circle ... ... ...)
(circle ... ... ...)
(circle ... ... ...)
(circle ... ... ...)
(circle ... ... ...)
)
)
</code>
Now we need to specify the arguments for each circle.
Looking at our example again, all the circles are solid, so we can specify that first.
<code class="block">
; Code :
(define (make-bulls-eye color-1 color-2)
(overlay
(circle ... "solid" ...)
(circle ... "solid" ...)
(circle ... "solid" ...)
(circle ... "solid" ...)
(circle ... "solid" ...)
(circle ... "solid" ...)
(circle ... "solid" ...)
(circle ... "solid" ...)
(circle ... "solid" ...)
(circle ... "solid" ...)
)
)
</code>
Recall that the outermost circle will have a radius of 100 pixels, and the other circles will be decreasing by 10 pixels in each iteration.
Can we add the color at the same time, since we know each circle will alternate in color?
<code class="block">
; Code :
(define (make-bulls-eye color-1 color-2)
(overlay
(circle 10 "solid" color-1)
(circle 20 "solid" color-2)
(circle 30 "solid" color-1)
(circle 40 "solid" color-2)
(circle 50 "solid" color-1)
(circle 60 "solid" color-2)
(circle 70 "solid" color-1)
(circle 80 "solid" color-2)
(circle 90 "solid" color-1)
(circle 100 "solid" color-2)
)
)
</code>
<a class="try-it" href="src/bulls-eye.rkt" download>Try It</a>
</p>
<div class="question">
What image would you expect to see if you replaced the function <code>overlay</code> with <code>beside</code>?
How about <code>above</code>?
</div>
<div class="question">
Challenge : Make a function that produces a bulls-eye that, instead of alternating colors, appears as a gradient.
Use this example:
</div>
<code class="block">
(check-expect (make-bulls-eye-gradient "darkviolet") <img src="images/bulls-eye-tr.png" width="50%"/>)
</code>
<!-- Section 5 -->
<h2 id="pinwheel">Pinwheel</h2>
<p>
For the next challenge, we will write a function that takes an image and creates a "pinwheel" of four copies of that image rotated around a corner of the original image.
</p>
<p>
As usual, the first step in the recipe is to summarize the purpose of our function.
Based on the description of the challenge, our function will take one image, and return another image based on the original image.
Let's see if we can capture that idea in a single sentence.
<code class="block">
; Purpose : Given a shape or image, return a 'pinwheel' comprised of that image.
</code>
</p>
<p>
The signature for this function should reflect that the function will take one image and return another image.
Keep in mind that even though the image our function returns will consist of four copies of the original image,
it will still be a single image.
<code class="block">
; Signature : Image → Image
</code>
</p>
<p>
Now we must perform the critical step of creating examples to test what our function will return.
Let's use a rhombus to test our function, since it will be evident if the individual elements of our pinwheel are not aligned properly if the width and height of our test image is different.
<code class="block">
; Examples :
(check-expect (make-pinwheel (rhombus 50 80 "solid" "turquoise")) <img src="images/turq-pinwheel.png"/>)
</code>
</p>
<p>
The stub will test that our examples work.
Remember that our function will only take a single image as an argument.
We will have our stub return a string to guarantee that our tests fail.
All we want to verify is that they successfully run.
<code class="block">
; Stub :
(define (make-pinwheel image) "pinwheel")
</code>
</p>
<p>
We are almost ready to code, but first we need to create the template
A properly constructed template should provide a basic outline of our function.
<br>
The image that we want to produce is similar to an image we produced with an earlier function.
Remember how we made the template for <code>make-counter-change</code>?
<code class="block">
; Template :
(define (make-pinwheel image)
(above
(beside ... ...)
(beside ... ...)
)
)
</code>
There are some differences between that function and the one we are building here, and our template should reflect that.
If we were to use a rhombus as the input in <code>make-counter-change</code>, each shape will be oriented the same way.
What we need to do is rotate each rhombus, which can be accomplished using the <code>rotate</code> function.
We also need to rotate the whole image.
There are a couple ways we could orient the images properly, but lets start with this template:
<code class="block">
; Template :
(define (make-pinwheel image)
(rotate ...
(above
(beside
(rotate ... ...)
(rotate ... ...)
)
(beside
(rotate ... ...)
(rotate ... ...)
)
)
)
)
</code>
</p>
<p>
Now we can fully code our function.
The first argument the <code>rotate</code> function requires is the number of degrees you want the image to be rotated.
A positive value will rotate the image to the right, and a negative value will rotate the image to the left.
We want our rhombus to be rotated 45 degrees, but in each row, one will be rotated to the left, and one will be rotated to the right.
The final image will also be rotated 45 degrees.
<code class="block">
; Code :
(define (make-pinwheel image)
(rotate -45
(above
(beside
(rotate 45 image)
(rotate -45 image)
)
(beside
(rotate -45 image)
(rotate 45 image)
)
)
)
)
</code>
Before you run your code, can you picture how the resulting image will look?
It is helpful to visualize what you expect your function will return.
<a class="try-it" href="src/pinwheel.rkt" download>Try It</a>
</p>
<p>
Let's try something we haven't done before: produce an image, then use our function on that image.
<br>
Here is how we would produce the image we used for our example:
<code class="block">
(make-pinwheel (rhombus 50 80 "solid" "turquoise"))
</code>
We can use this as an argument for the same function, like so:
<code class="block">
(make-pinwheel (make-pinwheel (rhombus 50 80 "solid" "turquoise")))
</code>
</p>
<p>
Is this the image you created?
<img src="images/double-turq-pinwheel.png"/>
</p>
<p>
We can repeat this process as many times as we want to create an interesting pattern:
<img src="images/double-double-turq-pinwheel.png"/>
</p>
<div class="question">
Challenge : Create a function that produces a pinwheel comprised of four different images, as in this example:
</div>
<code class="block">
(check-expect (make-rainbow-pinwheel (rhombus 50 80 "solid" "hotpink") (rhombus 50 80 "solid" "gold") (rhombus 50 80 "solid" "springgreen") (rhombus 50 80 "solid" "mediumslateblue")) <img src="images/rainbow-pinwheel.png"/>)
</code>
<div class="question">
Bonus : What happens when you use this image as an argument in the first pinwheel function? Why does it look like this?
</div>
<img src="images/double-rainbow-pinwheel.png"/>
<!-- Section 6 -->
<h2 id="business-card"> Business Card </h2>
<p>
For the next challenge, we will be creating a function that produces a business card.
The card should have an ID picture, a logo, a name, and a job title.
This challenge will let us practice using many of the placement functions we learned about in the graphics chapter here. <!-- add link -->
You can substitute your own picture, logo, and text for the ones we are using.
</p>
<p>
Here are the images we will be using for our ID and logo respectively:
<img src="images/pigeon1.png"/>
<img src="images/purpleplanet.png"/>
Let's define them so we can use them later.
<code class="block">
(define pigeon <img src="images/pigeon1.png"/>)
</code>
<code class="block">
(define planet-logo <img src="images/purpleplanet.png"/>)
</code>
</p>
<p>
As usual, the first step of the recipe is the purpose.
<code class="block">
; Purpose : Given an identifying image, a logo, a name, and a job, return a business card.
</code>
</p>
<p>
We have quite a few datatypes we will be working with, so lets take stock before we go further:
<ul>
<li>The identifying image and logo will clearly be <code>images</code>.</li>
<li>The name and job will be <code>strings</code>.</li>
<li>The complete business card will be an <code>image</code>.</li>
</ul>
</p>
<p>
We can list all of these datatypes in our signature.
<code class="block">
; Signature : Image Image String String → Image
</code>
</p>
<p>
Next we create our example.
<code class="block">
; Examples :
(check-expect (print-business-card pigeon planet-logo " Dr. Feathers" "Galactic President"))
</code>
</p>
<p>
With our example in place, we can create a stub.
<code class="block">
; Stub :
(define (business-card id logo name job) 0)
</code>
</p>
<p>
Before we start writing the code for our function, we need to create a template.
The design of our business card will have the ID picture on the left side, and the logo toward the upper right.
The name and job title will be centered on the card, slightly toward the right.
There are a few ways we could align and place the images together, so let's start with something central and work our way out.
We can start with the text, which will be in two lines.
<code class="block">
; Template :
(define (business-card id logo name job)
(above
(text ... ... ...)
(text ... ... ...)
)
)
</code>
We know also that the text will need to be placed alongside the ID picture, so we can do that next.
<code class="block">
; Template :
(define (business-card id logo name job)
(beside ...
(above
(text ... ... ...)
(text ... ... ...)
)
)
)
</code>
The only thing left to add is the logo.
Since it requires fairly precise placement, we can use a function like <code>overlay/align/offset</code>, which lets us specify exactly where to put the logo.
<code class="block">
; Template :
(define (business-card id logo name job)
(overlay/align/offset ... ...
(beside ...
(above
(text ... ... ...)
(text ... ... ...)
)
)
... ...
)
)
</code>
</p>
<p>
Now we can finally code the function we need.
Most of the arguments we have used in our function can be changed and experimented with to get a different look.
<code class="block">
; Code :
(define (business-card id logo name job)
(overlay/align/offset "right" "top"
logo
5 -10
(overlay/offset
(beside
id
(above
(text name 36 "black")
(text/font job 24 "dimgray" #f "roman" "italic" "normal" #f)
)
)
40 0
(rectangle 500 250 "solid" "whitesmoke")
)
)
)
</code>
Try changing colors or numbers and see how that effects the look of your final image.
</p>
<p>
Let's add one last thing to this function.
The image we have used would probably look more like an ID picture if it were a rectangle.
<br>
Recall that the function <code>place-image</code> constrains the image that it returns by the dimensions of the background image that is given.
<br>
Can you guess how this might help us?
<code class="block">
; Code :
(define (business-card id logo name job)
(overlay/align/offset "right" "top"
logo
5 -10
(overlay/offset
(beside
(place-image
id
115 100
(rectangle 175 225 "solid" "white")
)
(above
(text name 36 "black")
(text/font job 24 "dimgray" #f "roman" "italic" "normal" #f)
)
)
40 0
(rectangle 500 250 "solid" "whitesmoke")
)
)
)
</code>
<img src="images/business-card.png"/>
<a class="try-it" href="src/business-card.rkt" download>Try It</a>
</p>
<!-- Section 7 -->
<h2 id="clock-face"> Clock Face </h2>
<p>
As our last challenge in this chapter, we will attempt to create a clock face.
In our particular implementation, the numbers 1-12 on the clock-face should be oriented relative to the center of the dial, with 12 at the top. This challenge will require us to do more than simply place images a certain way.
Though we could write one long function that handles every facet of this challenge, we will instead do our best to divide this challenge into several smaller challenges that we will then handle separately.
This approach to programming is called "divide and conquer", and you will recall that it was one of our motivations for using the HtDF recipe to begin with.
Large problems are often dealt with much more effectively if they are broken down into several smaller problems.
</p>
<p>
To begin, let's create the blank clock-face and define it as a constant.
<code class="block">
(define clock-face
(circle 130 "outline" "black")
)
</code>
</p>
<p>
Now we have defined the constant <code>clock-face</code>, which returns the image of an outlined circle with a radius of 130 pixels.
This is the blank clock face on which we will place our numbers.
</p>
<p>
Remember, the <code>Number</code> datatype is distinct from the <code>Image</code> datatype.
If we would like to have numbers on our clock face, we need to have images of the numbers.
We need a function that accepts a number and returns an image of that number.
</p>
<p>
As with any function, we begin by concisely stating our purpose:
<code class="block">
; Purpose : Given a number, return an image of that number.
</code>
</p>
<p>
The signature is specified next.
We know our function will accept a number, and we want it to return an image of that number.
<code class="block">
; Signature : Number → Image
</code>
</p>
<p>
Now we will create some examples of how we expect our function to work.
We want our function to return an image for any number entered.
<code class="block">
; Examples :
(check-expect (print-digit-image "12") <img src="images/print-digit-image.png"/>)
</code>
</p>
<p>
With our examples defined, we know what success looks like for our function.
The next step in the recipe is to see if we can get the examples to execute.
<code class="block">
; Stub :
(define (print-digit-image num) 0)
</code>
</p>
<p>
We are almost ready to begin coding our function, but first we need to write our function template.
Our final image will consist of text, so we can begin by using the <code>text/font</code> function.
Remember that this function is like the <code>text</code> function with additional parameters.
<code class="block">
; Template :
(define (print-digit-image num)
(text/font ... ... ... ... ... ... ... ...)
)
</code>
</p>
<p>
Now we can start coding.
Our <code>num</code> argument will determine what the <code>text/font</code> function prints.
However, <code>text/font</code> can only accept a string, and our argument is a number.
We need to convert the number to a string before it can be used by <code>text/font</code>.
<code class="block">
; Code :
(define (print-digit-image num)
(text/font (number->string num) ... ... ... ... ... ... ...)
)
</code>
All we need to do now is fill in the rest of the gaps in our code.
<code class="block">
; Code :
(define (print-digit-image num)
(text/font (number->string num) 30 "black" #f "swiss" "normal" "bold" #f)
)
</code>
<a class="try-it" href="src/print-digit-image.rkt" download>Try It</a>
</p>
<p>
We now have a function that accepts number, and returns an image of that number.
This is a big step, but we're not there yet.
We now need to somehow arrange the numbers 1 through 12 around the clock face.
</p>
<p>
There are many possible ways we could go about this.
The method we will use places a number, starting with 12, at the top of the clock face, and then rotates the clock face some amount before placing the next number in the same way.
Repeating this process for all 12 numbers should produce a fully-numbered clock face.
</p>
<p>
As always, we want to break down each larger task into smaller steps whenever possible.
Let's start with the simpler task of placing an image on the top of the clock face, and then rotating it the appropriate amount.
</p>
<p>
At this point, we can write the purpose of our next function.
<code class="block">
; Purpose : Given a number and an image of a clock face, return an image of the number overlayed on the clock face, both rotated some degrees.
</code>
</p>
<p>
The following signature should reflect the datatypes that our function will accept and return, based on the purpose statement.
<code class="block">
; Signature : Number Image → Image
</code>
</p>
<p>
Now let's come up with some examples.
Something to keep in mind is that our function returns an image of a clock face with a number on it.
This new image could now be used as the face input for the function when we want to place the number 2.
Can you see how this might be used to fill up our clock face with all the numbers?
<code class="block">
; Examples :
(check-expect (place-and-rotate 12 clock-face) <img src="images/place-and-rotate.png"/>)
</code>
</p>
<p>
Let's see if we can get our test to run.
Make sure the arguments match the signature.
<code class="block">
; Stub :
(define (place-and-rotate face) 0)
</code>
</p>
<p>
For the template, we will gather the tools that we have at our disposal.
To start, we know that we will want to overlay the number we input on the face.
However, the <code>overlay</code> function simply centers one image "on top of" another.
We would like to place the number on the clock face, but at the top of the face in the vertical direction and in the center in the horizontal direction.
Fortunately, the <code>overlay/align/offset</code> allows us to specify where we want to place the foreground image relative to the background image.
Looking at our purpose statement, we will probably also want to use <code>rotate</code> to rotate the resultant image.
<code class="block">
; Template :
(define (place-and-rotate num face)
(rotate ...
(overlay/align/offset ... ... ... ... ... ...)
)
)
</code>
</p>
<p>
At this point, we're ready to code our function.
The first thing to figure out is how much we would like to rotate the clock face, once the number is placed.
The <code>rotate</code> function accepts a number of degrees by which to rotate the given image.
A circle has 360 degrees.
We would like to place 12 numbers at approximately equal intervals, so the clock face should rotate +30 degrees between the placement of each number.
<code class="block">
; Code :
(define (place-and-rotate num face)
(rotate 30
(overlay/align/offset ... ... ... ... ... ...)
)