-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathmaterial-part-2.html
12193 lines (8750 loc) · 540 KB
/
material-part-2.html
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>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Programming Basics Continuation Course, Spring 2012</title>
<link rel="stylesheet" href="stylesheets/common.css" type="text/css" media="screen, print" />
<link rel="stylesheet" href="stylesheets/menu.css" type="text/css" media="screen" />
<link rel="stylesheet" href="stylesheets/shjs/sh_style.css" type="text/css" media="screen, print" />
<link rel="stylesheet" href="stylesheets/exercises.css" type="text/css" media="screen, print" />
<script type="text/javascript" src="javascripts/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="javascripts/exercises2.js"></script>
<script type="text/javascript" src="javascripts/common-new.js"></script>
<script type="text/javascript" src="javascripts/jquery.easing.js"></script>
<script type="text/javascript" src="javascripts/shjs/sh_main.min.js"></script>
<script type="text/javascript" src="javascripts/shjs/sh_java.min.js"></script>
</head>
<body>
<h1>Advanced programming course</h1>
<p>Arto Vihavainen and Matti Luukkainen</p>
<div id="toc" class="menu" data-first-chapter-index="1" data-first-exercise-index="109">
<div id="materiaali_toc"></div>
<div id="tehtavat_toc"></div>
</div>
<p><strong><big>Note for the reader</big></strong></p>
<section class="viikkoraja" id="0">
<div div class="viikkoraja-mooc" id="Note for the reader" tekija="Arto Vihavainen, Matti Luukkainen">
<p>This is direct continuation to the programming basics course Object-Oriented Programming with Java, part 1<a href="http://mooc.fi/courses/2013/programming-part-1/">material</a>.</p>
<p>This material is meant for the University of Helsinki Department of Computer Science advanced programming course, and released here as an Massive Open Online Course. The material is based on courses in 2012, 2011, and 2010, of which content has been affected by Matti Paksula, Antti Laaksonen, Pekka Mikkola, Juhana Laurinharju, Martin Pärtel, Joel Kaasinen and Mikael Nousiainen.</p>
<p>Read the material so that you do all of the examples you read yourself. It's worth making small changes to the examples and observe how the changes affect the program. At first you might think that doing the examples yourself and editing them too would slow down your learning. However, this isn't true at all. As far as we know, no one has yet learned to program by just reading (or by just listening to a lecture). Learning is based substantially on actively doing and growing a routine. The examples, and especially doing your own experiments, are one of the best ways to truly internalize the read text.</p>
<p>Try to do assignments, or at least to try them out as you read the text. If you can't get an assignment pass right off the bat, don't get depressed, since you'll be always able to get help with the assignment at the workshop.</p>
<p>The text isn't meant to be just read once. You'll most certainly have to return to parts you've already read, or to assignments you've already done. This text doesn't contain everything essential related to programming. As a matter of fact, no book exists that would have everything essential. So you will in every case - on your programming career - have to find information on your own. The excersises of the course already hold some instructions on how and where you'd be able to find useful information.</p>
<p>The course picks up where the programming basics left off, and everything learned in the programming basics course is now assumed to be known. It's a good idea to go and check the <a href="../ohpe/index.html">material</a> of the programming basics course.</p>
</div>
</section>
<section class="viikkoraja" id="1" >
<div class="viikkoraja">Week1</div>
<div class="viikkoraja-mooc" id="Week 7" deadline=" " data-first-chapter-index="33" data-first-exercise-index="108" data-first-week-index="7" data-first-chapter-index-mooc="33" data-first-exercise-index-mooc="1" data-first-week-index-mooc="7" tekija="Arto Vihavainen, Matti Luukkainen">
<h2>Recapping programming basics</h2>
<p>In this chapter we briefly recap a few concepts we became familiar with in Part 1. You can familiarize yourself with the programming basics course material <a href="http://mooc.fi/courses/2013/programming-part-1/">here</a>.</p>
<h3>Program, commands and variables</h3>
<p>A computer program consists of a series of commands that a computer runs one at a time, from top to bottom. The commands always have a predefined structure and semantics. In Java - the programming language we use in this course - the commands are read from top to bottom, left to right. Programming courses are traditionally started by introducing a program that prints the string <code>Hello World!</code>. Below is a command written in Java that prints the <code>Hello World!</code> string.</p>
<pre class="sh_java">
System.out.println("Hello World!");
</pre>
<p>In the command the method <code>println</code> - which belongs to the <code>System</code> class - gets called, which prints the string passed in to it as a parameter, and after that a linebreak. The method is given the string <code>Hello World!</code> as a parameter; consequently the program prints out <code>Hello World!</code> followed by a linebreak.</p>
<p>Variables can be used as part of the functionality of the program. Below is a program which introduces the variable <code>length</code> of the integer type. The value 197 is set to this variable on the next line. After this the value <code>179</code> of the variable <code>length</code> is printed.</p>
<pre class="sh_java">
int length;
length = 179;
System.out.println(length);
</pre>
<p>The execution of the program above would happen one line at a time. First the line <code>int length;</code> is executed, in which the variable <code>length</code> is introduced. Next the line <code>length = 179;</code> is executed, in which we set the value <code>179</code> to the variable that was introduced on the previous line. After this the line <code>System.out.println(length);</code> is run, in which we call the print method we saw earlier. To this method we give the variable <code>length</code> as a parameter. The method prints the content - the value - of the variable <code>length</code>, which is <code>179</code>.</p>
<p>In the program above we really wouldn't have to introduce the variable <code>length</code> on one line and then set its value on the next. The introduction of a variable and setting its value can be done on the same line.</p>
<pre class="sh_java">
int length = 179;
</pre>
<p>When executing the above line, the variable <code>length</code> is introduced and as it is introduced the value <code>179</code> is set to it.</p>
<p>In reality all information within a computer is represented as a series of bits - ones and zeros. Variables are an abstraction offered by the programming language with which we can handle different values more easily. The variables are used to store values and to maintain the state of the program. In Java, we have the primitive variable types <code>int</code> (integer), <code>double</code> (floating-point), <code>boolean</code> (truth value), <code>char</code> (character), and the reference variable types <code>String</code> (character string), <code>ArrayList</code> (array), and all classes. We'll return to primitive data type variables and to reference type variables and their differences later.</p>
<h3>Comparing variables and reading input</h3>
<p>The functionality of programs is built with the help of control structures. Control structures make different functions possible depending on the variables of the program. Below, an example of an <code>if - else if - else</code> control structure, in which a different function is executed depending on the result of the comparison. In the example a string <code>Accelerate</code> is printed if the value of the variable <code>speed</code> is smaller than 110, the string <code>Break</code> if the <code>speed</code> is greater than 120, and the string <code>Cruising</code> in other cases.</p>
<pre class="sh_java">
int speed = 105;
if (speed < 110) {
System.out.println("Accelerate");
} else if (speed > 120) {
System.out.println("Break");
} else {
System.out.println("Cruising");
}
</pre>
<p>Because in the example above the value of the variable <code>speed</code> is 105, the program will always print the string <code>Accelerate</code>. Remember that the comparison of strings is done with the <code>equals</code> method that belongs to the <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/String.html" target="_blank">String</a> class. Below is an example in which an object created from Java's <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Scanner.html" target="_blank">Scanner</a> class is used to read the input of a user. The program checks if the strings entered by the user are equal.</p>
<pre class="sh_java">
Scanner reader = new Scanner(System.in);
System.out.print("Enter the first string: ");
String first = reader.nextLine();
System.out.print("Enter the second string: ");
String second = reader.nextLine();
System.out.println();
if (first.equals(second)) {
System.out.println("The strings you entered are the same!");
} else {
System.out.println("The strings you entered weren't the same!");
}
</pre>
<p>The functionality of the program depends on the user's input. Below is an example; the red text is user input.</p>
<pre>
Enter the first string: <font color="red">carrot</font>
Enter the second string: <font color="red">lettuce</font>
The strings you entered weren't the same!
</pre>
<h3>Loops</h3>
<p>Repetition is often required in programs. First we make a so-called <code>while-true-break</code> loop, which we run until the user inputs the string <code>password</code>. The statement <code>while(true)</code> begins the loop, which will then be repeated until it runs into the keyword <code>break</code>.</p>
<pre class="sh_java">
Scanner reader = new Scanner(System.in);
while (true) {
System.out.print("Enter password: ");
String password = reader.nextLine();
if (password.equals("password")) {
break;
}
}
System.out.println("Thanks!");
</pre>
<pre>
Enter password: <font color="red">carrot</font>
Enter password: <font color="red">password</font>
Thanks!
</pre>
<p>You can also pass a comparison to a <code>while</code> loop instead of the boolean <code>true</code>. Below, the user input is printed so that there are stars above and below it.</p>
<pre class="sh_java">
Scanner reader = new Scanner(System.in);
System.out.print("Enter string: ");
String characterString = reader.nextLine();
int starNumber = 0;
while (starNumber < characterString.length()) {
System.out.print("*");
starNumber = starNumber + 1;
}
System.out.println();
System.out.println(characterString);
starNumber = 0;
while (starNumber < characterString.length()) {
System.out.print("*");
starNumber = starNumber + 1;
}
System.out.println();
</pre>
<pre>
Enter string: <font color="red">carrot</font>
******
carrot
******
</pre>
<p>The example above should make you feel a little bad inside. The bad feelings are hopefully because you see that the example violates the rules learned in the programming basics. The example has unneccessary repetition which should be removed with the help of methods.</p>
<p>In addition to the while-loop we also have two versions of the <code>for-loop</code> at our disposal. The newer <code>for-loop</code> is used for going through lists.</p>
<pre class="sh_java">
ArrayList<String> greetings = new ArrayList<String>();
greetings.add("Hei");
greetings.add("Hallo");
greetings.add("Hi");
for (String greet: greetings) {
System.out.println(greet);
}
</pre>
<pre>
Hei
Hallo
Hi
</pre>
<p>The more traditional <code>for-loop</code> is used in situations similar to where you would use a <code>while-loop</code>. It can, for example, be used to go through arrays. In the following example all values in the array <code>values</code> will be multiplied by two and then finally printed using the newer <code>for-loop.</code></p>
<pre class="sh_java">
int[] values = new int[] {1, 2, 3, 4, 5, 6};
for (int i = 0; i < values.length; i++) {
values[i] = values[i] * 2;
}
for (int value: values) {
System.out.println(value);
}
</pre>
<pre>
2
4
6
8
10
12
</pre>
<p>The traditional <code>for-loop</code> is very useful in cases where we go through indices one at a time. The loop below will go through the characters of a character string one by one, and prints the character string <code>Hip!</code> every time we encounter the character <code>a</code>.</p>
<pre class="sh_java">
String characterString = "saippuakauppias";
for (int i = 0; i < characterString.length(); i++) {
if (characterString.charAt(i) == 'a') {
System.out.println("Hip!");
}
}
</pre>
<pre>
Hip!
Hip!
Hip!
Hip!
</pre>
<h3>Methods</h3>
<p>Methods are a way of chopping up the functionality of a program into smaller entities. All Java programs start their execution from the <code>main</code> program method, which is defined with the statement <code>public static void main(String[] args)</code>. This statement defines a static method - that is a method which belongs to the <em>class</em> - which receives a character string array as its parameter.</p>
<p>The program defines methods to abstract the functionalities of the program. When programming, one should try to achieve a situation in which the program can be looked at from a <em>higher level</em>, in such a case the main method consists of calls to a group of self-defined, well-named methods. The methods then specify the functionality of the program and perhaps are based on calls to other methods.</p>
<p>Methods that are defined using the keyword <code>static</code> belong to the <em>class</em> that holds the method, and work as so-called support methods. The methods that are defined without the keyword <code>static</code> belong to the instances - <em>the objects</em> - created from the class and can modify the state of that individual object.</p>
<p>A method always has a visibility modifier (<code>public</code>, visible to 'everyone', or <code>private</code>, only visible within its class), a return type (in the <code>main</code> method this is <code>void</code>, which returns nothing) and a name. In the following code we create a method which belongs to a class, <code>public static void print(String characterString, int times)</code>. This method prints a character string the defined amount of times. This time we use the method <code>System.out.print</code>, which works just like <code>System.out.println</code>, but doesn't print a linebreak.</p>
<pre class="sh_java">
public static void print(String characterString, int times) {
for (int i = 0; i < times; i++) {
System.out.print(characterString);
}
}
</pre>
<p>The method above prints the character string it receives as a parameter an amount of times equal to the integer - which was also passed in as a parameter.</p>
<p>In the section on loops we noticed that the code had some nasty copy-paste stuff in it. With the help of methods, we can move the printing of stars to a separate method. We create a method <code>public static void printStars(int times)</code>, which prints the amount of stars it receives as a parameter. The method uses a <code>for</code> loop instead of a <code>while</code>.</p>
<pre class="sh_java">
public static void printStars(int times) {
for (int i = 0; i < times; i++) {
System.out.print("*");
}
System.out.println();
}
</pre>
<p>When making use of a method, our previous (and hideous) example now looks like the following.</p>
<pre class="sh_java">
Scanner reader = new Scanner(System.in);
System.out.print("Enter characterString: ");
String characterString = reader.nextLine();
printStars(characterString.length());
System.out.println(characterString);
printStars(characterString.length());
</pre>
<h3>Class</h3>
<p>Methods can abstract a program up to a certain point, but as the program becomes larger it's sensible to chop down the program even further into smaller and more logical entities. With the help of classes, we can define higher level concepts of a program and functionalities related to those concepts. Every Java program requires a class in order to work, so the <code>Hello World!</code> example wouldn't work without the class definition. A class is defined with the keywords <code>public class nameOfTheClass</code>.</p>
<pre class="sh_java">
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
</pre>
<p>In a program, classes are used to define concepts and functionalities related to those concepts. Objects can be created from a class and are the embodiments of that class. Every object that belongs to a certain class has the same structure, but the variables belonging to each objects can be different. The methods of objects handle the <em>state</em> of the object, that is, the variables of the object.</p>
<p>Let's inspect the class <code>Book</code> below; the class has the object variables <code>name</code> (String) and <code>publishingYear</code> (integer).</p>
<pre class="sh_java">
public class Book {
private String name;
private int publishingYear;
public Book(String name, int publishingYear) {
this.name = name;
this.publishingYear = publishingYear;
}
public String getName() {
return this.name;
}
public int getPublishingYear() {
return this.publishingYear;
}
}
</pre>
<p>The definition in the beginning, <code>public class Book</code>, tells the name of the class. This is followed by the definitions of object variables. Object variables are variables which for each of the objects created from the class are their own -- the object variables of one object are unrelated to the state of the same variables of another object. It's usually appropriate to hide the object variables from the users of the class, to define the visibility modifier <code>private</code> for them. If the visibility modifier is set to <code>public</code>, the user of the object will be able to directly access the object variables.</p>
<p>Objects are created from a class with a <em>constructor</em>. A constructor is a method that initializes an object (creates the variables belonging to the object) and executes the commands that are within the constructor. The constructor is always named the same as the class that has the constructor in it. In the constructor <code>public Book(String name, int publishingYear)</code> a new object is created from the class <code>Book</code> and its variables are set to the values that were passed in as parameters.</p>
<p>Two methods that handle the information in the object are also defined for the class above. The method <code>public String getName()</code> returns the name of the object in question. The method <code>public int getPublishingYear()</code> returns the publishing year of the object in question.</p>
<h3>Object</h3>
<p><em>Objects</em> are created with the help of the constructor that is defined within a class. In the program code the costructor is called with the <code>new</code> command, which returns a reference to the new object. Objects are instances created from classes. Let's inspect a program that creates two different books, after which it prints the values returned by the <code>getName</code> methods belonging to the objects.</p>
<pre class="sh_java">
Book senseAndSensibility = new Book("Sense and Sensibility", 1811);
Book prideAndPrejudice = new Book("Pride and Prejudice", 1813);
System.out.println(senseAndSensibility.getName());
System.out.println(prideAndPrejudice.getName());
</pre>
<pre>
Sense and Sensibility
Pride and Prejudice
</pre>
<p>So, each object has its own internal state. The state is formed from object variables that belong to the object. Object variables can be both primitive type variables and reference type variables. If reference type variables belong to the objects, it is possible that other objects also refer to the same referenced objects! Let's visualize this with the bank example, in which there are accounts and persons.</p>
<pre class="sh_java">
public class Account {
private String accountID;
private int balanceAsCents;
public Account(String accountID) {
this.accountID = accountID;
this.balanceAsCents = 0;
}
public void deposit(int sum) {
this.balanceAsCents += sum;
}
public int getBalanceAsCents() {
return this.balanceAsCents;
}
// .. other methods related to an account
}
</pre>
<pre class="sh_java">
import java.util.ArrayList;
public class Person {
private String name;
private ArrayList<Account> accounts;
public Person(String name) {
this.name = name;
this.accounts = new ArrayList<Account>();
}
public void addAccount(Account account) {
this.accounts.add(account);
}
public int moneyTotal() {
int total = 0;
for (Account account: this.accounts) {
total += account.getBalanceAsCents();
}
return total;
}
// ... other methods related to a person
}
</pre>
<p>Each object created from the <code>Person</code> class has its own name and its own list of accounts. Next, let's create two persons and two accounts. One of the accounts is owned by only one person and the other one is shared.</p>
<pre class="sh_java">
Person matti = new Person("Matti");
Person maija = new Person("Maija");
Account salaryAccount = new Account("NORD-LOL");
Account householdAccount = new Account("SAM-LOL");
matti.addAccount(salaryAccount);
matti.addAccount(householdAccount);
maija.addAccount(householdAccount);
System.out.println("Money on Matti's accounts: " + matti.moneyTotal());
System.out.println("Money on Maija's accounts: " + maija.moneyTotal());
System.out.println();
salaryAccount.deposit(150000);
System.out.println("Money on Matti's accounts: " + matti.moneyTotal());
System.out.println("Money on Maija's accounts: " + maija.moneyTotal());
System.out.println();
householdAccount.deposit(10000);
System.out.println("Money on Matti's accounts: " + matti.moneyTotal());
System.out.println("Money on Maija's accounts: " + maija.moneyTotal());
System.out.println();
</pre>
<pre>
Money on Matti's accounts: 0
Money on Maija's accounts: 0
Money on Matti's accounts: 150000
Money on Maija's accounts: 0
Money on Matti's accounts: 160000
Money on Maija's accounts: 10000
</pre>
<p>Initially, the accounts of both persons are empty. When money is added to the salaryAccount - which <code>matti</code> has a reference to - the amount of money on Matti's accounts grows. When money is added to the householdAccount <em>the amount of money each person has grows</em>. This is because both Matti and Maija have "access" to the householdAccount, so in each of the persons' object variable <code>accounts</code>, there's a reference to the householdAccount.</p>
<h3>The structure of a program</h3>
<p>A program should be clear and easy to understand for both the original writer and others. The most important aspects of a clear program are class structure and good naming conventions. Each class should have a single, clearly defined responsibility. Methods are used to reduce repetition and to create a structure for the internal functionality of the class. A method should also have a clear responsibility to ensure it stays short and simple. Methods that do many things should be divided into smaller helper methods, which are called by the original method. A good programmer writes code that can be understood even weeks after it was originally written.</p>
<p>Good, understandable code uses descriptive naming of variables, methods and classes, and consistent indentation. Let's look at the example below, a small program for buying and selling goods. Even though the only thing available is carrots, with no bookkeeping, the user interface could be extended to use a storage class to keep track of items.
<pre class="sh_java">
public class UserInterface {
private Scanner reader;
public UserInterface(Scanner reader) {
this.reader = reader;
}
public void start() {
while (true) {
String command = reader.nextLine();
if (command.equals("end")) {
break;
} else if (command.equals("buy")) {
String line = null;
while(true) {
System.out.print("What to buy: ");
line = reader.nextLine();
if(line.equals("carrot")) {
break;
} else {
System.out.println("Item not found!");
}
}
System.out.println("Bought!");
} else if (command.equals("sell")) {
String line = null;
while(true) {
System.out.print("What to sell: ");
line = reader.nextLine();
if(line.equals("carrot")) {
break;
} else {
System.out.println("Item not found!");
}
}
System.out.println("Sold!");
}
}
}
}
</pre>
<p>This example has numerous problems. The first problem is the long <code>start</code> method. It can be shortened by moving most of the command handling to a separate method.</p>
<pre class="sh_java">
public class UserInterface {
private Scanner reader;
public UserInterface(Scanner reader) {
this.reader = reader;
}
public void start() {
while (true) {
String command = reader.nextLine();
if (command.equals("end")) {
break;
} else {
handleCommand(command);
}
}
}
public void handleCommand(String command) {
if (command.equals("buy")) {
String line = null;
while(true) {
System.out.print("What to buy: ");
line = reader.nextLine();
if(line.equals("carrot")) {
break;
} else {
System.out.println("Item not found!");
}
}
System.out.println("Bought!");
} else if (command.equals("sell")) {
String line = null;
while(true) {
System.out.print("What to sell: ");
line = reader.nextLine();
if(line.equals("carrot")) {
break;
} else {
System.out.println("Item not found!");
}
}
System.out.println("Sold!");
}
}
}
</pre>
<p><code>handleCommand</code> still has some repetition for reading the user input. Both buying and selling first print a character string with the question, then take input from the user. If the input is incorrect (other than "carrot"), "Item not found!" is printed. We will create a new method, <code>public String readInput(String question)</code>, to handle this. Note that if the program used some other object to keep track of inventory, we would compare user input to the inventory's contents instead.</p>
<pre class="sh_java">
public class UserInterface {
private Scanner reader;
public UserInterface(Scanner reader) {
this.reader = reader;
}
public void start() {
while (true) {
String command = reader.nextLine();
if (command.equals("end")) {
break;
} else {
handleCommand(command);
}
}
}
public void handleCommand(String command) {
if (command.equals("buy")) {
String input = readInput("What to buy: ");
System.out.println("Bought!");
} else if (command.equals("sell")) {
String input = readInput("What to sell: ");
System.out.println("Sold!");
}
}
public String readInput(String question) {
while (true) {
System.out.print(question);
String line = reader.nextLine();
if (line.equals("carrot")) {
return line;
} else {
System.out.println("Item not found!");
}
}
}
}
</pre>
<p>The program is now divided into appropriate parts. There are still a few things, other than implementing more methods, we can do to improve readability. The <code>start</code> method has an <code>if</code> branch that ends in <code>break</code>, which exits the loop. We can remove the unnecessary <code>else</code> branch, simply moving the <code>handleCommand</code> method to be called after the <code>if</code> statement. The program still works exactly as before, but the method is now shorter and easier to read. A similar situation exists in the <code>readInput</code> method, so we will clean it up too.</p>
<pre class="sh_java">
public class UserInterface {
private Scanner reader;
public UserInterface(Scanner reader) {
this.reader = reader;
}
public void start() {
while (true) {
String command = reader.nextLine();
if (command.equals("end")) {
break;
}
handleCommand(command);
}
}
public void handleCommand(String command) {
if (command.equals("buy")) {
String input = readInput("What to buy: ");
System.out.println("Bought!");
} else if (command.equals("sell")) {
String input = readInput("What to sell: ");
System.out.println("Sold!");
}
}
public String readInput(String question) {
while (true) {
System.out.print(question);
String line = reader.nextLine();
if (line.equals("carrot")) {
return line;
}
System.out.println("Item not found!");
}
}
}
</pre>
<p>Dividing a program into smaller parts, like we did above, is called <em>refactoring</em>. It does not change how the program works, but the internal structure is changed to be more clear and easier to maintain. The current version is clearer than the original, but it can be improved further. For example, <code>handleCommand</code> can be further divided into two different methods, one for handling buying and the other for selling.</p>
<pre class="sh_java">
public class UserInterface {
private Scanner reader;
public UserInterface(Scanner reader) {
this.reader = reader;
}
public void start() {
while (true) {
String command = reader.nextLine();
if (command.equals("end")) {
break;
}
handleCommand(command);
}
}
public void handleCommand(String command) {
if (command.equals("buy")) {
commandBuy();
} else if (command.equals("sell")) {
commandSell();
}
}
public void commandBuy() {
String input = readInput("What to buy: ");
System.out.println("Bought!");
}
public void commandSell() {
String input = readInput("What to sell: ");
System.out.println("Sold!");
}
public String readInput(String question) {
while (true) {
System.out.print(question);
String line = reader.nextLine();
if (line.equals("carrot")) {
return line;
} else {
System.out.println("Item not found!");
}
}
}
}
</pre>
<p>The program now has a clear structure with descriptively named methods. Every method is short and has a small task to handle. Note that refactoring the code did not add any new functionality, it merely changed the way the program works internally.</p>
<h3>Programming and the importance of practicing</h3>
<p>As far as we know, nobody has yet learned programming by listening to lectures. To develop the skill required in programming, it is essential to practice both what you have learned earlier and things that are new to you. Programming can be compared to speaking languages or playing an instrument, both of which can only be learned by doing. Master violinists are probably not good at playing <em>only</em> because they practice a lot. Playing an instrument is fun, which makes one more motivated to practice. The same applies to programming.</p>
<p>As Linus Torvalds said, <em>"Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program"</em>.</p>
<p>Dr. Luukkainen has written a list of instructions for new programmers to follow when learning to program. Follow this advice to become a great programmer!</p>
<ul>
<li> Take small steps
<ul>
<li> Divide the problem you are trying to solve into smaller parts and solve them <strong>one at a time</strong> </li>
<li> Keep testing that your solution is moving in the right direction, ensuring that you have solved the current part correctly</li>
</ul></li>
<li> Keep the code as clean as you can
<ul>
<li> use proper indentation </li>
<li> use descriptive names for variables, methods, classes, everything</li>
<li> keep all methods short, including <code>main</code> </li>
<li> write methods that only do one thing </li>
<li> <strong>remove all copy-paste code by refactoring (or don't copy and paste code in the first place!)</strong></li>
<li> replace "bad" and unclear code with clean, easy to read code </li>
</ul></li>
</ul>
<h3>Visibility</h3>
<p>Until now, we have been using two different keywords to define the <em>visibility</em> of methods and instance variables. <code>public</code> makes the method or instance variable visible and accessable to everyone. Methods and constructors are usually marked as public, so that they can be called from outside the class.</p>
<p>Declaring a method or instance variable <code>private</code> hides it from the outside, making it only accessible from inside the same class.</p>
<pre class="sh_java">
public class Book {
private String name;
private String contents;
public Book(String name, String contents) {
this.name = name;
this.contents = contents;
}
public String getName() {
return this.name;
}
public String getContents() {
return this.contents;
}
// ...
}
</pre>
<p>The instance variables in the Book class above can only be accessed with the public methods <code>getName</code> and <code>getContents</code>. Fields declared as private are only accessible in code inside the class. Methods can also be declared as private, which prevents them from being called outside the class.</p>
<p>Now it's time to start practicing!</p>
<div class="tehtavat" id="viikko7">
<div class="tehtava">
<h3>Smileys</h3>
<p>Create the support method <code>private static void printWithSmileys(String characterString)</code> for the class <code>Smileys</code> which comes with the assignment template. The method is to print the given character string surrounded with smileys. Use the character string <code>:)</code> as the smiley.</p>
<pre class="sh_java">
printWithSmileys("\\:D/");
</pre>
<pre>
:):):):):)
:) \:D/ :)
:):):):):)
</pre>
<p>Note, that the character string must have \\ so we can print the symbol \.</p>
<p><em>Note!</em> if the length of the character string is an odd number, add an extra space on the right side of the given character string.</p>
<pre class="sh_java">
printWithSmileys("\\:D/");
printWithSmileys("87.");
</pre>
<pre>
:):):):):)
:) \:D/ :)
:):):):):)
:):):):):)
:) 87. :)
:):):):):)
</pre>
<p>It's a good idea to first think how many smileys should be printed for a character string of a certain length. The length of a character string can be found out with the method <code>length</code> which belongs to it. A loop is helpful for printing the top and bottom smiley rows, the middle row can be handled with a normal print command. You can check if a length is an odd number with the help of a remainder <code>characterString.length() % 2 == 1</code>.</p>
</div>
<div class="tehtava">
<h3>Character String Changer</h3>
<p>In this assignment we create a character string changer, which consists of two classes. The class <code>Changer</code> turns a single character to another one. The Changer holds a number of Changes and changes character strings with the help of Change objects it holds.</p>
<h4>Change-class</h4>
<p>Create a class <code>Change</code>, that has the following functionalities:</p>
<ul>
<li> constructor <code>public Change(char fromCharacter, char toCharacter)</code> that creates an object that makes changes from character <code>fromCharacter</code> to <code>toCharacter</code></li>
<li> method <code>public String change(String characterString)</code> returns the changed version of the given character string</li>
</ul>
<p>The class is used in the following way:</p>
<pre class="sh_java">
String word = "carrot";
Change change1 = new Change('a', 'b');
word = change1.change(word);
System.out.println(word);
Change Change2 = new Change('r', 'x');
word = Change2.change(word);
System.out.println(word);
</pre>
<p>The example above would print:</p>
<pre>
cbrrot
cbxxot
</pre>
<p><strong>Tip:</strong> you can handle replacing characters in two ways, either with the help of a method in the class <code>String</code> (look for it yourself!) or by going through the character string character by character while forming the changed character string.</p>
<p>If you don't use the ready-made method of String, it is good to remember that even though you compare character strings with the command <code>equals</code> you compare single characters with the == operator:</p>
<pre class="sh_java">
String word = "carrot";
String replacedA = "";
for ( int i=0; i < word.length(); i++) {
char character = word.charAt(i);
if ( character == 'a' ) {
replacedA += '*'
} else {
replacedA += character;
}
}
System.out.println(replacedA); // prints c*rrot
</pre>
<h4>Changer-class</h4>
<p>Create the class <code>Changer</code>, with the following functions:</p>
<ul>
<li> constructor <code>public Changer()</code> creates a new changer</li>
<li> method <code>public void addChange(Change change)</code> adds a new Change to the Changer</li>
<li> method <code>public String change(String characterString)</code> executes all added Changes for the character string in the order of their adding and returns the changed character string</li>
</ul>
<p>The class is used in the following way:</p>
<pre class="sh_java">
Changer scandiesAway = new Changer();
scandiesAway.addChange(new Change('ä', 'a'));
scandiesAway.addChange(new Change('ö', 'o'));
System.out.println(scandiesAway.change("ääliö älä lyö, ööliä läikkyy"));
</pre>
<p>The above example would print:</p>
<pre>
aalio ala lyo, oolia laikkyy
</pre><!-- TODO -->
<p><strong>Tip:</strong> It's a good idea to store the Changes to a list object variable of Changer (in the same fashion as on the basics course we stored players to a team, phone numbers to a phone book or books to a library, for example) A Changer is executed so that the changes are done to the character string one at a time as in the following example:</p>
<pre class="sh_java">
ArrayList<Change> changes = new ArrayList<Change>();
changes.add( new Change('a', 'b') );
changes.add( new Change('k', 'x') );
changes.add( new Change('o', 'å') );
String word = "carrot";
for (Change Change : changes) {
word = Change.change(word);
}
System.out.println(word); // print pårxxbnb
</pre>
<p><strong>REMINDER</strong> when you add an ArrayList, a Scanner or a Random, Java doesn't recognize the class unless you "import" it by adding the following lines to the beginning:</p>
<pre class="sh_java">
import java.util.ArrayList; // imports ArrayList
import java.util.*; // imports all tools from java.util, including ArrayList, Scanner ja Random
</pre>
</div>
<div class="tehtava">
<h3>Calculator</h3>
<p>In this assignment, we make a simple calculator, similar to the one made in the material of programming basics' week 1. This time however, we pay attention to the structure of the program. Especially we will make the <em>main</em>-method (the main program) very light. The main program method doesn't actually do anything else than just start the program:</p>
<pre class="sh_java">
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
calculator.start();
}
}
</pre>
<p>What the main program here does is it just creates the object that implements the actual application logic and then starts it. This is the proper way of creating programs and from now on we'll try to achieve this structure.</p>
<h4>Reader</h4>
<p>In order to communicate with the user, the calculator needs a Scanner-object. As we've seen, reading integers with a Scanner is a little laborious. We now create a separate class <code>Reader</code> that encapsulates a Scanner-object.</p>
<p>Implement the class <code>Reader</code> and add the following methods to it</p>
<ul>
<li><code>public String readString()</code></li>
<li><code>public int readInteger()</code></li>
</ul>
<p>Within the Reader there should be a Scanner-object as an instance variable, which the methods use in the old familiar way we know from programming basics. Remember that when reading integers, it's good to first read the entire line and then turn that in to an integer. Here we can utilize the method <code>parseInt</code> of the <code>Integer</code>-class.</p>
<h4>Application body</h4>
<p>The calculator works like this:</p>
<pre>
command: <font color="red">sum</font>
value1: <font color="red">4</font>
value2: <font color="red">6</font>
sum of the values 10
command: <font color="red">product</font>
value1: <font color="red">3</font>
value2: <font color="red">2</font>
product of the values 6
command: <font color="red">end</font>
</pre>
<p>Implement the class <code>Calculator</code> to take care of the application logic of your program, and for that class a method <code>public void start()</code> which looks exactly like this:</p>
<pre class="sh_java">
public void start() {
while (true) {
System.out.print("command: ");
String command = reader.readString();
if (command.equals("end")) {
break;
}
if (command.equals("sum")) {
sum();
} else if (command.equals("difference")) {
difference();
} else if (command.equals("product")) {
product();
}
}
statistics();
}
</pre>
<p>The calculator has the operations <code>sum, difference, product</code>.</p>
<p>Finish the bodies for the methods <code>sum</code>, <code>difference</code>, <code>product</code> and <code>stasistics</code>. All of them are to be of the type <code>private void</code> which means that the methods are available only for internal use in the calculator.</p>
<p>Add an instance variable of the type <code>Reader</code> for the calculator and create the reader in the constructor. <em>The calculator may not have a separate Scanner-type variable!</em></p>
<h4>Implementation of the application logic</h4>