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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
|
\documentclass[landscape,25pt]{foils}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{color}
\usepackage{subfigure}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage{textcomp}
\usepackage{listings}
\lstset{
language=Python,
basicstyle=\footnotesize,
frame=single,
showstringspaces=false,
formfeed=newpage,
tabsize=4,
commentstyle=\it,
morekeywords={models, lambda, forms}
}
\title{Introduction to Object-oriented Analysis and Design}
\author{}
\date{}
\MyLogo{Copyright \copyright 2018, 2019 Hui Lan}
\begin{document}
\maketitle
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Course information (Fall 2019)}
This full-semester course introduces terminology of the object-oriented (OO) \underline{paradigm}, such as classes, superclasses (or parent classes), subclasses (or child classes), class variables, objects, encapsulation, abstraction, simple inheritance, multiple inheritance, polymorphism, duck-typing, exceptions, and abstract base classes. The students will learn the most useful tools in the object-oriented principles by practicing OO analysis, OO design and OO programming (using python 3) for an existing open publishing service. The object-oriented programming paradigm may at first appear quite strange for people familiar with the procedural paradigm, but can turn out to be quite natural for many problems. This course aims to train students to view these problems and come up with solutions in an object-oriented fashion. Previous programming experience, though desirable, is not required. This is a rather {\em practical} course, in which concepts introduced in lectures will be soon applied in the labs as well as in the course project. Finally, we will analyze whether several claimed benefits of the OO paradigm, such as reliability, productivity, reuse, ease of modification, indeed exist.
{\bf Paradigm}: a pattern or model.
{\bf Recommended textbook}: Dusty Phillips. (2015) Python 3 Object Oriented Programming. Second Edition.
A significant portion of the lecture notes is built on the above book.
{\bf Recommended reference book}: Craig Larman. (2004) Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development. Third Edition.
{\bf Grading policy}:
\begin{tabular}{ | l | l |}
\hline
{\bf Component} & {\bf Weight} \\ \hline
Quizzes & 10 \\ \hline
Labs & 20 \\ \hline
Course Project & 20 \\ \hline
Final exam & 50 \\ \hline
\end{tabular}
{\bf Software freely available for this course}:
\begin{itemize}
\item Python 3.7.0 interpreter:
https://www.python.org/downloads/release/python-370/
[scroll to bottom to find a installer for your operating system.]
\item Wing IDE 101: http://wingware.com/downloads/wing-101
\item Flask: https://pypi.org/project/Flask/
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Essential Elements of Object-oriented Analysis and Design}
\begin{itemize}
\item Find classes and class methods from problem description.
\item Repeat
\begin{itemize}
\item Design class and methods along with database schema.
\item Think about test cases and write them down.
\end{itemize}
\item Repeat
\begin{itemize}
\item Start coding (TDD, non-TDD, ITL (Incremental test-last)).
\item Automated or semi-automated testing.
\end{itemize}
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Object}
Object - a physical thing that we can sense, feel and manipulate (e.g., wallets, toys, babies, apples, oranges, etc).
Put simply, an object is a tangible thing.
It does not have to be physical.
\begin{itemize}
\item A {\bf file} can be an object.
\item An {\bf operating system} can be an object.
\item A {\bf job position} can be an object.
\end{itemize}
An object has {\bf data} and {\bf behaviors} (usually).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Oriented}
Orient's dictionary definition. 1. align or position (something) relative to the points of a compass or other specified positions. Find one's position in relation to new and strange surroundings. 2. adjust or tailor (something) to specified circumstances or needs.
Oriented - {\em directed towards}.
Object-oriented. Specify the style of software development: we are going to {\bf model objects and their interactions} (if any). Functionally directed toward modeling objects.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{The object-oriented umbrella}
Object-oriented umbrella - OO analysis, OO design, and OO programming.
As we have learned from our {\em Software Engineering} course, design happens before programming, and analysis before design.
In reality, this order is not that strict.
In fact, iteration is common.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Object-oriented analysis}
{\em What}?
DO THE RIGHT THING.
Analyze the requirements first. Work product: {\bf use cases}.
Understand the problem. Happen after the Software Requirements stage.
Understand what needs to be done (and what needs {\em not} to be done), by looking at a task and identifying objects and their interactions.
Object-oriented exploration - interview customers, study their processes, and eliminate possibilities (i.e., define scope).
For example, an online food store:
\begin{itemize}
\item {\em review} our {\bf history}
\item {\em apply} for {\bf jobs}
\item {\em browse}, {\em compare}, and {\em order} {\bf products}
\end{itemize}
Tasks:
\begin{itemize}
\item Identify objects, e.g., Plane, Flight, Pilot.
\item Organize the objects by creating a object model diagram.
\item Describe how the objects interact/collaborate.
\end{itemize}
\href{https://www.tutorialspoint.com/object\_oriented\_analysis\_design/ooad\_tutorial.pdf}{A useful tutorial on OOAD}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Object-oriented design}
{\em How}?
DO THE THING RIGHT.
Present a conceptual solution.
Figure out {\em how} things should be done.
More specifically, {\bf assign responsibilities} to classes and collaborate objects.
{\bf Responsibility assignment} is an important skill we need to master.
{\bf Responsibility-driven design}.
Convert analysis of requirements into implementation specification (classes and interfaces).
Tasks:
\begin{itemize}
\item Name the objects.
\item Specify which objects interact with other objects.
\item Identify constraints.
\item Define object attributes -- data, e.g., tailNumber in Plane.
\item Define object actions -- behaviors, e.g., getFlightHistory.
\end{itemize}
Class Responsibility Collaborator Models. You should be able to draw CRC cards and move them around on a table. A design technique. An effective tool for conceptual modeling and detailed design.
\begin{itemize}
\item Class - class name (a singular noun)
\item Responsibility - what the class {\bf knows} or {\bf does}.
\item Collaborator - collaborate/interact with other classes. Need help from other classes. For example, Seminar could be Student's collaborator for checking space availability and for enrollment.
\end{itemize}
http://www.agilemodeling.com/artifacts/crcModel.htm
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Object-oriented programming}
Smalltalk, Java, Python.
Convert design into a working program using an OO programming language.
Smalltalk (too ancient), C++ (too complex), Java (too verbose), Python (just right).
Some classic designs are called {\bf design patterns}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{The real world is MURKY}
Murky dictionary definition: dark and gloomy, especially due to thick mist. Not fully explained or understood.
No matter how hard we try to separate these stages (OOA, OOD and OOP), we will always
find things that need further analysis while we are designing. When we are programming, we find features
that need clarification in the design.
Remember the Agile Process we've talked in our Software Engineering course? A series of short development cycles.
{\bf Development is iterative}. How iterative it is depends on the team's experience, and the completeness of requirements.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Iterative and incremental development}
IID - iterative and incremental development, dates back to late 1950s.
45\% of the features in Waterfall requirements are never used.
A typical software project experienced a 25\% change in requirements [Boehm and Papaccio].
Work on a series of {\bf mini-projects} to get a series of {\bf partial systems}, each being a growing subset of the final system.
1. Get some requirements.
2. Plan.
3. {\bf Build} a partial system.
4. Ask for {\bf feedback} (requirements clarification, marketplace change).
5. Analyze and {\bf incorporate} feedback.
Repeat 2-5 for about 10-15 iterations.
See picture iterative-development.png
UP - Unified Process (Extreme Programming - Test-driven development and pair programming, Risk-driven development, Client-driven development, Scrum - war room, daily stand-up meeting, three special questions to be answered by each team member, Refactoring and CI)
Monday: one-hour meeting, review last iteration's diagrams, whiteboards, pseudocode and design notes. No rush to code.
No overly-detailed design.
Short {\bf timeboxed} iterations are preferred. Why?
{\bf Agile methods}: Each iteration refines requirements, plans and design. {\em Whatever works. }
3 weeks better than 6 weeks. Why?
Too much work in the current iteration? De-scope iteration goals.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Waterfall thinking}
Up-front analysis and modeling.
BUT software development is a {\bf high-change} area.
Figure 2.3 Larman's book PDF page 63.
``Let's write all the use cases before starting to program.''
``Let's do many detailed OO models in UML before starting to program.''
Consequences: 45\% of the features in waterfall requirements are never
used, and early waterfall schedules and estimates vary up to 400\%
from the final actuals.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Evolutionary analysis and design}
For example, a project needs 20 iterations, each timeboxed in 3 weeks.
The first 5 iterations include requirements {\bf workshops} and
critical prototypes, stabilizing 90\% of the requirements, but only
completing 10\% of the whole software. That is, about 20\% of the
whole project time is devoted to requirements.
Figure 2.4 Larman's book PDF page 69.
Starting coding near Day One of the project is also bad. We need a middle way.
Iterative and evolutionary requirements analysis combined with early {\bf timeboxed iterative development} and {\bf frequent stakeholder participation}, evaluation, and {\bf feedback} on partial results.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Agile modeling}
The purpose of modeling (sketching UML, ...) is primarily to understand, not to document.
Treat it lightly.
Doing UML is not to create many detailed UML diagrams for programmers,
but to quickly explore alternatives and paths to a good OO design.
Misconception: people translate UML diagrams mechanically to code.
Prefer sketching UML on whiteboards, and taking a picture for it.
Don't do it alone.
``Good enough'', simple notations.
Quick creative flow and change.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Agile Unified Process}
Phase plan - high-level
Iteration plan - detailed, adaptive
Tackle high-risk and high-value issues in early iterations.
Engage users for evaluation, feedback and requirements.
Test early, often, and realistically.
Manage requirements.
{\bf Artifacts}
Domain model - noteworthy concepts in the application domain
Use-Case model and Supplementary Specification - functional and non-functional requirements. Glossary. Vision. Business Rules.
Design model - objects.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Objects and classes}
A class usually has {\bf attributes} and {\bf behaviors}.
Kind of objects is {\bf class}. In the class, we summarize their common attributes (the attributes we are interested in).
Classes describe objects. A class definition is like a {\bf blueprint} for creating objects.
This orange of 50 grams belongs to \texttt{Orange} class, and that orange of 100 grams belongs to \texttt{Orange} class. The weight is one of the {\em infinitely many} characteristics that are shared by all oranges. These infinitely many characteristics include farm, pick date, best before date, etc. But any application needs only a finite set of characteristics, we must {\bf ignore irrelevant characteristics} while modeling. This selecting and ignoring process is called ABSTRACTION.
An object is called an {\bf instance} of a class. This object instance has its own set of data and behaviors.
We can make arbitrary number of objects from a class.
An Orange class may have three attributes: weight, orchard and date picked. You can use it to
describe/represent real oranges sold in the market, each having different weight, orchards and pick dates.
\lstinputlisting{./oop_prep/Orange.py}
Use \texttt{cheap\_orange.\_\_dict\_\_} to show attributes and their values. Try also \texttt{Orange.\_\_dict\_\_}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{UML - Unified Modeling Language}
Boxes and lines to intuitively illustrate classes and the association between them.
A useful communication tool during OO analysis and design.
A useful reference for myself in the future. {\em Why did I do that?}
{\bf Caution}: best used only when needed. Don't be lost among UML details. Hide uninteresting details.
{\bf Reality}: the initial diagrams become outdated very soon. Because these diagrams are subject to change in subsequent iterations, some people think drawing UML class diagrams is a waste of time (if you spend too much time on it). Don't make it too formal in the beginning.
Most useful diagrams: class diagrams, use case diagrams, activity diagrams, and sequence diagrams.
\begin{itemize}
\item Class diagrams. A box represents a class. A line between two boxes represents a relationship.
\item Sequence diagrams. Model the interactions (step-by-step) among objects in a Use Case. Vertical lifeline (the dashed line hanging from each object), activation bars, horizontal arrows (messages, methods, return values).
\item Use case diagrams.
\item Activity diagrams.
%https://creately.com/blog/diagrams/sequence-diagram-tutorial/
\end{itemize}
%%% More stuff on UML diagrams
%%% https://holub.com/uml/
%%% http://agilemodeling.com/essays/umlDiagrams.htm
%%% https://www.pl.cs.jhu.edu/oose/lectures/uml.shtml
%%% http://www.agilemodeling.com/artifacts/useCaseDiagram.htm
%%% http://www.agilemodeling.com/artifacts/sequenceDiagram.htm
%%% http://www.agilemodeling.com/artifacts/classDiagram.htm
%%% https://www.tutorialspoint.com/uml/uml_standard_diagrams.htm
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Useful names and resources}
{\bf Martin Fowler} - UML Distilled, Refactoring.
{\bf Scott Ambler} - \href{http://agilemodeling.com/essays/agileRequirements.htm}{Agile Modeling}.
{\bf Gang of Four} - Design Patterns. Not an introductory book.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Procedural versus object-oriented}
A wallet for money deposit and withdrawal.
Procedural:
\lstinputlisting{./oop_prep/money_procedural.py}
Problem: the above code only works for a {\em single} wallet. We can add a \texttt{create} function which returns a dictionary (e.g., \{'money':0\}) for each wallet created.
Procedural:
\lstinputlisting{./oop_prep/money_dictionary.py}
Object-oriented:
{\bf Think in Objects}
\lstinputlisting{./oop_prep/money_oo.py}
\begin{lstlisting}
w = Wallet(0)
w.check()
'The wallet has 0 RMB.'
w.deposit(1000)
w.check()
'The wallet has 1000 RMB.'
w.withdraw(500)
w.check()
'The wallet has 500 RMB.'
\end{lstlisting}
%\begin{center}
%\includegraphics[width=0.85\textwidth]{fig/BoehmCurve_real}
%\end{center}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Chapter 1 Object-oriented design}
Abstraction
Classes
Encapsulation
Inheritance
UML
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Example: Dice Game}
Roll two dices and check whether their face values sum to 7.
{\bf Use case}: Player rolls the dice. System returns results. If the dice face values totals 7, play wins; otherwise, player loses.
{\bf Domain model, or conceptual object model}
{\bf Interaction diagrams} We could use a sequence diagram: flow of message, invocation of methods.
{\bf Class diagrams}.
Visual Modeling is a good thing. Use UML as a sketch. Don't let too many uninteresting details get in the way.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Everything in Python is a class}
We have seen a few examples of customary classes. Note that the internal python data types such as numbers, strings, modules, and even functions, are classes too.
\begin{lstlisting}
>>> import random
>>> type(random)
<class 'module'>
>>> x = 123
>>> type(x)
<class 'int'>
>>> x = '123'
>>> type(x)
<class 'str'>
>>> x = [1,2,3]
>>> type(x)
<class 'list'>
>>> def f():
pass
>>> type(f)
<class 'function'>
>>> class Minimalism:
pass
>>> x = Minimalism()
>>> type(x)
<class '__main__.Minimalism'>
\end{lstlisting}
I fail to see why not everything in the world cannot be described as a class.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Specifying attributes and behaviors}
Objects are {\bf instances} of classes.
Each object of a class has its {\bf own} set of data, and methods
dealing with these data. With OOP, we in principle don't access these
class attributes directly, but {\em only} via class methods.
\begin{itemize}
\item Data describe objects.
Data represents the individual characteristics of a certain object.
Attributes - values
All objects instantiated from a class have the same attributes but may have different values.
Attributes are sometimes called members or properties (usually read-only).
\item Behaviors are actions.
Behaviors are actions ({\bf methods}) that can occur on an object.
We can think of methods as functions which have access to all the data associated with this object.
Methods accept parameters and return values.
\end{itemize}
OOA and OOD are all about identifying objects and specifying their interactions.
%\begin{center}
%\includegraphics[width=0.98\textwidth]{fig/classes_publisher}
%\end{center}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Interacting objects}
How do we make object interact? Pass objects as arguments to object methods.
\lstinputlisting{./oop_prep/orange_basket.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Composition and aggregation}
{\bf Composition}: collecting several objects to make a new one.
{\bf Aggregation} is closely related to composition. Main difference: the aggregate objects may exist independently (they won't be
destroyed after the container object is gone).
Composite and aggregate objects have different lifespan.
The main difference is whether the child could {\bf exist independently} from the parent.
A class has a list of students. \texttt{Students} could exist independently from \texttt{Class}. Aggregation.
A house has a number of rooms. \texttt{Room} could not exist independently from \texttt{House}. Composition.
The difference is not very important in practice.
\begin{itemize}
\item A car is \underline{composed of} an engine, transmission, starter,
headlights and windshield. The engine comprises many parts. We can
decompose the parts further if needed. {\em has a} relationship.
\item How about abstract components? For example, names, titles, accounts,
appointments and payments.
\end{itemize}
Model chess game.
Two {\bf player}s - a player may be a human or a computer.
One {\bf chess set} - a {\bf board} with 64 {\bf
positions}, 32 {\bf piece}s including pawns, rooks, bishops,
knights, king and queen). Each piece has a shape and a unique move rule.
The pieces have an aggregate relationship with the chess set. If the board is destroyed, we can still use the pieces.
The positions have a composite relationship with the chess set. If the board is destroyed, we cannot re-use positions anymore (because positions are part of the board).
Man - Leg - Shoes
\lstinputlisting{./oop_prep/aggregation_vs_composition.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Simple inheritance}
This is the {\bf most famous} object-oriented principle.
For creating {\em is a } relationship.
Abstract common logic into superclasses and manage specific details in the subclass.
Queen {\em is a} Piece.
So are Pawns, Bishops, Rooks, Knights and King.
This is inheritance. Inheritance is useful for sharing code (and for avoiding duplicate code).
Everything in python is inherited (derived) from the most {\em base} class, {\bf object}.
Check the output of \texttt{help(object)} and \texttt{dir(object)}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Overriding methods}
Re-defining a method of the superclass (the method name unchanged) in the subclass. We can override special methods (such as \texttt{\_\_init\_\_}, \texttt{\_\_str\_\_}) too.
\lstinputlisting{./oop_prep/Piece.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{super()}
The super() function returns an object instantiated from the parent class, allowing us to call the parent methods directly.
The super() function can be called anywhere in any method in the subclass.
\lstinputlisting{./oop_prep/Friend.py}
It makes sense to order something from a supplier (Supplier) but not from my friends (Friend). So Supplier has the method order() while Friend does not have this method, although both subclasses are derived from the same parent class, Contact.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Class variables}
In class \texttt{Contact}, \texttt{all\_contacts} is a {\bf class variable}.
What is special about the class variable? It is shared by all instances of this class.
In the above example, whenever we create an object (from Contact, Friend, or Supplier), this object is appended to \texttt{all\_contacts}.
We access the class variable via: \texttt{Contact.all\_contacts}, \texttt{Friend.all\_contacts}, or \texttt{f.all\_contacts}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Extending built-ins}
\begin{itemize}
\item Add a search method to the built-in type \texttt{list}.
\lstinputlisting{./oop_prep/ContactList.py}
In fact, [] is {\bf syntax sugar} for list().
\item Add a longest\_key method to the built-in type \texttt{dict}.
\lstinputlisting{./oop_prep/ContactList.py}
\end{itemize}
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{Keyword arguments - kwargs}
%% **kwargs is a dictionary that collects any keyword arguments that have not been consumed in the parameter list.
%% \lstinputlisting{./oop_prep/kwargs.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Polymorphism}
Polymorphism - many forms of (a function).
A fancy name.
Treat a class differently depending on which {\em subclass} is implemented.
Different behaviors happen depending on which {\em subclass} is being used, without having to explicitly know what the subclass actually is.
Mostly talking about method overriding. A concept based on inheritance.
Same method name, but different actions (function definitions).
\lstinputlisting{./oop_prep/Polymorphism2.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Duck-typing}
\lstinputlisting{./oop_prep/ducktyping.py}
This sort of polymorphism in Python is typically called {\bf ducking typing}: ``If it walks like a duck or swims like a duck, it is a duck''.
No inheritance is involved. We don't really care if it really {\em is a} duck object, as long as it can fly (i.e., has the \texttt{fly()} method).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Multiple inheritance}
A subclass inherits from more than one superclasses.
\begin{lstlisting}
class RicohAficio(Copier, Printer, Scanner, Faxer):
pass
\end{lstlisting}
Not used very often as it can accidentally create the {\bf Diamond Problem} (or Diamond Inheritance): ambiguity in deciding which parent method (with the same name) to use.
\lstinputlisting{./oop_prep/MRO.py}
One potential consequence of the diamond problem is that the base class can be called twice. The following code demonstrates that.
\lstinputlisting{./oop_prep/MRO2.py}
Therefore, to avoid that, we need {\bf Method Resolution Order} (MRO) (with super()).
\lstinputlisting{./oop_prep/MRO1.py}
``next'' method versus ``parent'' method.
Many expert programmers recommend against using it because it will make our code messy and hard to debug. Alternative: composition, instead of inheritance. Include an object from the superclass and use the methods in that object.
{\bf mixin}. A mixin is a superclass that provides extra functionality.
\lstinputlisting{./oop_prep/EmailableContact.py}
In the above example, MailSender is a mixin superclass.
\lstinputlisting{./oop_prep/AddressHolder.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%\foilhead{Instructors - Students - Courses}
%\lstinputlisting{./oop_prep/teaching.py}
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{Library catalog}
%% \lstinputlisting{./oop_prep/catalog.py}
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{A shopping mall}
%% What common objects (classes) can we identify in a shopping mall (e.g., Yorkdale, Eaton, Wanda)? Nouns (class names, class attributes) and verbs (class methods).
%% When can composition or inheritance be used?
%% \begin{enumerate}
%% \item Mall name
%% \item Location
%% \item Transit access
%% \item Opening date
%% \item Owner
%% \item Number of visitors
%% \item Architect
%% \item Hours, holiday hours
%% \item Total area
%% \item Entrances (main, side)
%% \item Underground, parking garages(parking)
%% \item Fire exits (doors)
%% \item Escalators
%% \item Washrooms
%% \item Cinema
%% \item Bank machines (ATMs)
%% \item Floor maps, floors
%% \item Mall map
%% \item Stores may have sales, promotions
%% \item News
%% \item Events
%% \item Customer services
%% \item Tourist information
%% \item Shop card
%% \item Social media
%% \item Number of stores
%% \item Books and Music store
%% \item Food courts (fast food, restaurants)
%% \item Food stores, Apparel stores (men's, ladies, unisex, children), kitchen, housewares, pharmacies and drug stores, footwear stores, Athleticwear stores (asics, adidas, nike), leather and luggage stores, gift stores, stationary stores, health and beauty stores, toys stores, jewelery stores, the apple store (electronics, computers and telephones), the Microsoft store, coffee shops
%% \item Customers, kids, Sales representatives, building staff (security guards, cleaners), cashiers, pharmacist, optometrist
%% \item Products and their associated information
%% \item Interactions between customers and store sales persons.
%% \end{enumerate}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Hiding details and creating public interface}
Determine the {\bf public interface}. Make it stable.
Interface: the collection of attributes and methods that other objects can use to interact with that object.
As class users/clients, it is good enough to just know the interface (API documentation) without needing to worry about its internal workings. As class designers/programmers, they should keep the interface stable while making changes to its internals so that users' code can still work (without modification).
The remote control is our interface to the Television. Each button is like a method that can be called on the TV.
We don't care:
\begin{itemize}
\item Signal transmission from antenna/cable/satellite
\item How the signals are converted to pictures and sound.
\item Signal sent to adjust the volume
\end{itemize}
Vendor machines, %TVs (remote control),
cellphones, Microwaves, Cars, and Jets.
{\bf Information hiding:} the process of hiding functional details. Sometimes loosely called {\bf encapsulation}.
In python, we don't have or need {\em true} information hiding.
We should focus on the level of detail most appropriate to a given task and ignore irrelevant details while designing a class. This is called {\bf abstraction}.
{\bf Abstraction} is an object-oriented principle related information hiding and encapsulation. Abstraction is the process of encapsulating information with separate
public and private interfaces. The private information can be subject to information hiding.
A car driver has a different task domain from a car mechanic.
Driver needs access to brakes, gas pedal and should be able to steer, change gears and apply brake.
Mechanic needs access to disc brakes, fuel injected engine, automatic transmission and should be able to adjust brake and change oil.
So a car can have different abstraction levels, depending on who operates it.
Design tips:
\begin{itemize}
\item Keep the interface simple.
\item When abstracting interfaces, model exactly what needs to be modeled and nothing more.
\item Imagine that the object has a strong preference for privacy.
\end{itemize}
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{Abstraction, encapsulation and information hiding}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Packages, modules, classes and methods}
Usually, methods are organized in a class, classes in a module (a file), and modules in a package.
{\bf A module is a file} containing class/function definitions.
For small projects, just put all classes in one file. So we got only one module. For example, Lab3.py.
A package is a folder containing a few modules. We must create an empty \texttt{\_\_init\_\_} file under that folder to make the folder a package.
There are two options for importing {\bf modules}: import and from-import.
Use simple imports if the imported modules are under the same folder as the importing file, or in system path.
\begin{lstlisting}
import database
db = database.Database()
from database import Database
db = Database()
from database import Database as DB
db = DB()
\end{lstlisting}
\begin{itemize}
\item import
\begin{lstlisting}
import package.module # use period operator to separate packages or modules.
c = package.module.UserClass()
\end{lstlisting}
For example,
\begin{lstlisting}
import math
math.sqrt(4)
\end{lstlisting}
Can you do \texttt{import math.sqrt}? No. sqrt is not a module.
We can do \texttt{from math import sqrt}.
\item from-import, or from-import-as.
\begin{lstlisting}
from package.module import UserClass
c = UserClass()
\end{lstlisting}
For example,
\begin{lstlisting}
from math import sqrt
sqrt(4)
\end{lstlisting}
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Organizing modules to packages and properly importing them}
\begin{lstlisting}
proj/
main.py
ecommerce/
__init__.py
database.py
products.py
payments/
__init__.py
paypal.py
creditcard.py
\end{lstlisting}
How to use the module paypal.py in main.py? Use {\bf absolute imports}, which specify the complete path.
Each module in the package can use {\bf absolute imports} too. (But it won't work if we want to run this module as main program. One solution is move the whole package to a system path called \texttt{site-packages}. We can get all system paths using \texttt{sys.path}.)
Module-level code will be executed immediately when the module is imported.
\begin{lstlisting}
import ecommerce.payments.paypal
ecommerce.payments.paypal.pay()
from ecommerce.payments.paypal import pay
pay()
from ecommerce.payments import paypal
paypal.pay()
\end{lstlisting}
main.py:
\lstinputlisting{./oop_prep/main.py}
ecommerce/products.py:
\lstinputlisting{./oop_prep/ecommerce/products.py}
ecommerce/payments/paypal.py:
\lstinputlisting{./oop_prep/ecommerce/payments/paypal.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Each module has a special, hidden variable called \texttt{\_\_name\_\_}}
Use \texttt{print(\_\_name\_\_)} to check its value.
If you run that module as a main program (note that each module is a file), then \texttt{\_\_name\_\_} is equal to \texttt{'\_\_main\_\_'}.
We say running a module as a main program if we type in the command line like this: \texttt{python module\_name.py}.
If you import that module, then that module's \texttt{\_\_name\_\_} contains its actual file name. For example, \texttt{paypal.py}'s \texttt{\_\_name\_\_} is ``\texttt{ecommerce.payments.paypal}'' when we import the module \texttt{paypal.py} using \texttt{from ecommerce.payments import paypal}.
When we import a module, the module's code will be executed. But since that module's \texttt{\_\_name\_\_} is not \texttt{'\_\_main\_\_'}, then the code under that module's \texttt{if \_\_name\_\_ == '\_\_main\_\_':} won't be executed.
So it is a good idea to put \texttt{if \_\_name\_\_ == '\_\_main\_\_':} in the end of every module (main module or not) and put the test code for that module after it.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Organizing module contents}
A typical order in a Python module:
\begin{lstlisting}
class UsefulClass:
''' This class might be useful to other modules.'''
pass
def main():
''' Do something with it for our module. '''
u = UsefulClass()
print(u)
if __name__ == '__main__':
main()
\end{lstlisting}
Inner classes and inner functions. Usually used as an {\em one-off} helper, not to be used by other methods or other modules.
\lstinputlisting{./oop_prep/formatter_string.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Public, protected and private attributes}
\lstinputlisting{./oop_prep/wallet.py}
Attribute names with two underscores are not visible.
\lstinputlisting{./oop_prep/wallet_test.py}
%\texttt{builtins.AttributeError: 'Wallet' object has no attribute '\_\_gbp'}
%% \begin{lstinputlisting}
%% >>> Wallet.__dict__
%% mappingproxy({'__module__': 'wallet', '__doc__': ' For demostrating public, protected and private attributes. ', '__init__': <function Wallet.__init__ at 0x0000000002A95598>, 'deposit': <function Wallet.deposit at 0x0000000002A95488>, 'withdraw': <function Wallet.withdraw at 0x0000000002A95400>, 'check': <function Wallet.check at 0x0000000002A95F28>, '__dict__': <attribute '__dict__' of 'Wallet' objects>, '__weakref__': <attribute '__weakref__' of 'Wallet' objects>})
%% >>> w.__dict__
%% {'rmb': 0, '_cad': 0, '_Wallet__gbp': 0}
%% \end{lstinputlisting}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Abstract methods and interfaces}
No \texttt{interface} keyword in Python. We use ABCs (Abstract Base Classes) instead.
All subclasses derived from an abstract base class {\bf must implement} the abstract methods (marked by @abstractmethod). This is forced. It is like a contract between class users and class implementers.
We cannot instantiate an abstract base class. We cannot instantiate a subclass of abstract class without defining all its abstract methods.
Specify method names in abstract class, and implement these methods in subclasses.
\lstinputlisting{./oop_prep/AbstractBaseClass2.py}
Duck-typing and isinstance.
\lstinputlisting{./oop_prep/ducktyping2.py}
@ is called decorator.
%\texttt{cls} is class name, and \textt{C} subclass name.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{The iterator design pattern}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Expecting the Unexpected}
An exception is not expected to happen often. Use exception handling for really exceptional cases.
Cleaner code; more efficient.
{\bf Look before you leap.} We can use the \texttt{if-elif-else} clause, why do we bother with exception?
{\bf Ask forgiveness rather than permission.} Exception is not a bad thing, not something to avoid. It is a powerful way to communicate information (pass messages).
What does an exception class look like?
\begin{lstlisting}
class IndexError(LookupError)
| Sequence index out of range.
|
| Method resolution order:
| IndexError
| LookupError
| Exception
| BaseException
| object
\end{lstlisting}
The exception hierarchy.
\begin{lstlisting}
BaseException
^
SystemExit KeyboardInterrupt Exception
^
Most Other Exception
\end{lstlisting}
Other built-in errors: ValueError, TypeError, KeyError, ZeroDivisionError and AttributeError.
\lstinputlisting{./oop_prep/EvenOnly.py}
try-except:
\lstinputlisting{./oop_prep/EvenOnly2.py}
\lstinputlisting{./oop_prep/IndexErrorException.py}
We can omit ``Exception as e'' or use LookupError or IndexError instead. Using IndexError is best as we are explicit here which exception we want to catch (and then handle).
\lstinputlisting{./oop_prep/noreturn.py}
Good floor:
\lstinputlisting{./oop_prep/goodfloor.py}
Stack exception clauses.
\lstinputlisting{./oop_prep/funnydivision.py}
try-except-else-finally:
\lstinputlisting{./oop_prep/IndexErrorException2.py}
\lstinputlisting{./oop_prep/finally.py}
Things under \texttt{finally} will executed no matter what happens (a good place to put clean-up statements). Extremely useful for
\begin{itemize}
\item Cleaning up an open database connection
\item Closing an open file
\end{itemize}
We can use try-finally without the except clause.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Customized exceptions}
Inherit from class Exception. Add information to the exception.
\lstinputlisting{./oop_prep/InvalidWithdrawal.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Getters, setters and @property decorator}
Data encapsulation.
Make methods look like attributes.
``Blurring the distinction between behavior and data''.
No change to client code. Backward compatible.
The \texttt{Color} example, starting from page 130 in Dusty's book.
\lstinputlisting{./oop_prep/ManHeight.py}
% https://www.programiz.com/python-programming/property
% https://www.programiz.com/python-programming/decorator
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{More on @property}
property is in fact a special function that returns a property object.
\begin{lstlisting}
property(fget=None, fset=None, fdel=None, doc=None)
\end{lstlisting}
\begin{lstlisting}
p = property()
dir(p) # attributes [..., 'fdel', 'fget', 'fset', 'getter', 'setter']
help(p)
\end{lstlisting}
\begin{lstlisting}
Man2.height # <property object at 0x0000000002A2FE58>
Man2.height.fget(m)
Man2.height.fset(m, 123)
Man2.height.__getattribute__('getter')
Man2.height.__getattribute__('settter')
\end{lstlisting}
\lstinputlisting{./oop_prep/property_example.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{More on decorators}
{\bf A decorator is a function} which adds some toppings to the decorated function.
\lstinputlisting{./oop_prep/decorator2.py}
In the above example, @steamed\_milk is a decorator.
steamed\_milk is a function that accepts one argument, the name of the decorated
function. steamed\_milk returns its inner function, decor. The inner
function adds some ``toppings'' (Steamed milk).
With overriding (single inheritance) we can add some toppings.
With mixin (multiple inheritance) we can also add some toppings.
We can stack decorators.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Design patterns}
Bridges (stone arch, suspension, cantilever, etc).
We have proven bridge structures that work.
Standard solutions to design for frequently encountered problems.
{\bf Pattern}: an example for others to follow.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Design patterns - the iterator pattern}
An iterator object usually has a \texttt{next} method and a \texttt{done} method.
\begin{lstlisting}
while not iterator.done():
item = iterator.next()
# do sth with the item
\end{lstlisting}
In Python,
\begin{itemize}
\item We have a special method called \texttt{\_\_next\_\_}, accessible by \texttt{next(iterator)}.
\item There is no \texttt{done} method. Raise exception \texttt{StopIteration} instead.
\end{itemize}
\lstinputlisting{./oop_prep/iterator_iterable.py}
Internally, a \texttt{for} loop is actually a \texttt{while} loop.
\begin{lstlisting}
iter([1,2,3])
<list_iterator object at 0x0000000002C40B00>
iter('123')
<str_iterator object at 0x0000000002C45E10>
iter({'a':1, 'b':2})
<dict_keyiterator object at 0x0000000002AD7098>
\end{lstlisting}
Two abstract base classes in \texttt{collections.abc}:
\begin{itemize}
\item Iterable must define \texttt{\_\_iter\_\_}.
\item Iterator must define \texttt{\_\_next\_\_} and \texttt{\_\_iter\_\_}, collectively called the iterator protocol.
\end{itemize}
File objects are iterators too. It has method \texttt{\_\_next\_\_} and \texttt{\_\_iter\_\_} (inherited from \_IOBase)
If there is no StopIetration, we have an infinite iterator.
\lstinputlisting{./oop_prep/RandomIterator.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Comprehensions}
Convert/map a list of items of this form to a list of items of that
form. Each item from the original list can be passed into a function
and the return value of that function becomes the new item in the
converted list.
Usually done in {\bf one} line of code.
Benefits: very concise.
We have list comprehensions, set comprehensions and dictionary comprehensions.
``List comprehensions are far faster than \texttt{for} loops when looping over a huge number of items.'' - I don't agree as of November 2018. In fact, they have similar performance.
\lstinputlisting{./oop_prep/comprehension.py}
\begin{lstlisting}
Time used [comprehension]: 5.93
Time used [for]: 6.19
Time used [comprehension]: 0.31
Time used [for]: 0.30
\end{lstlisting}
We can also make set comprehensions or dictionary comprehensions. To do that, we use braces instead of brackets.
\lstinputlisting{./oop_prep/comprehension_set.py}
Lists, sets and dictionaries are called {\em containers}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Generators}
Sometimes the data is too large, e.g., GB or TB, and we don't need it
at once, so we don't need to load everything into computer memory.
We can use a \texttt{for} loop.
We can also use a comprehension-like expression, called a generator.
\lstinputlisting{./oop_prep/apache-samples/generator1.py}
Use \texttt{yield} inside a function to make a generator.
\lstinputlisting{./oop_prep/apache-samples/generator2.py}
What is the type of filter? It is a generator, which can be used to
generate many values (one-the-fly). A generator is an iterator (since
it has methods \texttt{\_\_next\_\_} and \texttt{\_\_iter\_\_}), which
will be exhausted after one pass.
What is going on inside looks like:
\lstinputlisting{./oop_prep/apache-samples/generator2b.py}
The generator is created without executing the code in the function
body. When we put the generator in a for loop (which internally call
the method \texttt{\_\_next\_\_}), each iteration will stop after the
\texttt{yield} statement.
\lstinputlisting{./oop_prep/apache-samples/generator3.py}
$x$ is 0, $y$ is 1 and $z$ is 2.
Yield data from another generator using \texttt{yield from}.
\lstinputlisting{./oop_prep/apache-samples/generator3b.py}
List all files and directories under a directory:
\lstinputlisting{./oop_prep/apache-samples/generator4.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Coroutines}
`''Generators with a bit extra syntax.''
Execution order:
\begin{itemize}
\item \texttt{yield} occurs and the generator pauses.
\item \texttt{send()} occurs and the generator resumes.
\item The value sent in is assigned (to the left side of the \texttt{yield} statement).
\item The generator continues until the next \texttt{yield} statement.
\end{itemize}
\lstinputlisting{./oop_prep/coroutine.py}
\lstinputlisting{./oop_prep/coroutine_echo.py}
\lstinputlisting{./oop_prep/tally.py}
Linux kernel log parsing:
{\tiny
\begin{verbatim}
unrelated log messages
sd 0:0:0:0 Attached Disk Drive
unrelated log messages
sd 0:0:0:0 (SERIAL=ZZ12345)
unrelated log messages
sd 0:0:0:0 [sda] Options
unrelated log messages
XFS ERROR [sda]
unrelated log messages
sd 2:0:0:1 Attached Disk Drive
unrelated log messages
sd 2:0:0:1 (SERIAL=ZZ67890)
unrelated log messages
sd 2:0:0:1 [sdb] Options
unrelated log messages
sd 3:0:1:8 Attached Disk Drive
unrelated log messages
sd 3:0:1:8 (SERIAL=WW11111)
unrelated log messages
sd 3:0:1:8 [sdc] Options
unrelated log messages
XFS ERROR [sdc]
unrelated log messages
\end{verbatim}
}
\lstinputlisting{./oop_prep/coroutine_logparse.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Design patterns - the observer pattern}
The observers are told (updated with) changes occurred to the {\bf core}
object.
(The observers can then take their own actions.)
Useful for making redundant backup (in database, remote host, local file, etc).
Useful for broadcasting an announcement (using email, text messages, and other instant messaging systems).
\lstinputlisting{./oop_prep/Design_pattern_observer.py}
In the above example, whenever we change the properties \texttt{quantity} and \texttt{product}, the observers get updated (because we called the method \texttt{\_update\_observers}).
We can use \texttt{o()} because we have defined the special method \texttt{\_\_call\_\_}.
The main point of using the observer pattern is that we can add (attach) different observers (having different behaviors) upon any change in the core object.
Different behaviors:
\begin{itemize}
\item Back up the data in a file.
\item Back up the data in a database.
\item Back up the data in an Internet application.
\item Back up the data in a tape.
\end{itemize}
Main benefit: code detachment. We don't have to mix code handling {\em multiple behaviors} code in the observed object. Instead, we put such code in individual observers, facilitating maintainability.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Design patterns - the strategy pattern}
Provide different solutions to a single problem, each in a different object.
\lstinputlisting{./oop_prep/Design_pattern_strategy.py}
Each class has a single method, and the method names are the same in all three classes.
Each class does nothing else except provide a single function.
We can replace \texttt{make\_background} with \texttt{\_\_call\_\_} to make the object directly callable (for example, \texttt{strategy('trump.jpg', (2400, 1200))}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Design patterns - the state pattern}
See page 314 in the textbook.
The XML file \texttt{book.xml} is shown below.\\
\lstinputlisting{./oop_prep/book.xml}
Each class represents a state (see page 316 for the state transition diagram).
Each state class has the same method called \texttt{process}, which
takes the context object \texttt{parser} as an argument.
\texttt{process} consumes the input string, edits the tree, and modifies \texttt{parser}'s state.
Note that the context class \texttt{Parser} also has method
\texttt{process}, which invokes state object's \texttt{process} for
consuming the remaining string, and recursively calls itself.\\
\lstinputlisting{./oop_prep/Design_pattern_state.py}
I have to say the above design is quite clever.
Parse \texttt{book.xml} with a generator. \\
\lstinputlisting{./oop_prep/coroutine_parse_xml.py}
Output\\
\lstinputlisting{./oop_prep/parse_xml_output.txt}
\foilhead{Design patterns - the decorator pattern}
Purpose: wrap an object to make it look different. In other words, add extra things.
Decorate a string. \\
\lstinputlisting{./oop_prep/Design_pattern_decorator1.py}
We have produced {\em altered} strings by wrapping it in a class and rewriting the \texttt{\_\_str\_\_} method.
Gift wrapping (many options). \\
\lstinputlisting{./oop_prep/Design_pattern_decorator0.py}
The interface is not changed. Recall that we learned property decorators before. \\
\lstinputlisting{./oop_prep/Design_pattern_decorator.py}
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{Monkey-patching}
%% %Use functions (function names) as attributes.
%% Monkey-patching: replacing or adding methods at run time.
%% Class-level and object-level.
%% A ``messy hack''.
%% Useful for mock testing. For example, replace a transaction method \texttt{draw\_money} which connects to a remote, in-service database and makes changes there with a dummy transaction method which operates on a local database dedicated for testing.
%% Use it sparingly. \\
%% \lstinputlisting{./oop_prep/fakeprint.py}
%% \texttt{dir(my\_print)} gives us a special method \texttt{\_\_call\_\_}.
%% We can create {\em callable objects} by adding a special method \texttt{\_\_call\_\_} to the class definition, as we did for \texttt{a2()} and \texttt{a3()}.
%% First-class functions. Functions can be treated as objects, i.e., can be assigned to a variable or used as function arguments.
%% {\em Functions are objects}. (1) We can set attributes on functions. (2) We can pass functions (as arguments) around.
%% \lstinputlisting{./oop_prep/functions_are_objects.py}
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{Design patterns - the composite pattern}
%% See page 351 in the textbook for the UML diagram.
%% \lstinputlisting{./oop_prep/Design_pattern_composite.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Design patterns - the template pattern}
The {\bf Don't Repeat Yourself} principle.
Useful in the situation where several tasks share a common subset of steps.
For example, query a SQLite database using different query constructions (statements).
Base class: a sequence of common steps.
Subclasses: overriding one or several of the above steps to provide customized behaviors.
Refer to the picture in Dusty's book (page 325).
\lstinputlisting{./oop_prep/Design_pattern_template.py}
In the two subclasses, we create \texttt{self.query}, which is {\bf not declared but assumed to be there} in the superclass QueryTemplate.
We don't have to declare all attributes in the \texttt{\_\_init\_\_} method. Instead, we can add attributes ``on the fly'' (in class methods or even after we've created an object from that class).
This design pattern can minimize change if we change to other SQL engines, such MySQL. We only need to change QueryTemplate, while leaving its subclasses not affected.
We can override \texttt{format\_results} in UserGrossQuery if we want an HTML file instead of a text file.
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{Design patterns - the adapter pattern}
%% An adapter object sits between two different interfaces, performing translation.
%% Translate argument format. Translate order of arguments.
%% \lstinputlisting{./oop_prep/Design_pattern_adapter.py}
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{Design patterns - the facade pattern}
%% This pattern provides a simple interface (wrapper) that encapsulates the typical usage of a complex system.
%% Easy-to-comprehend and easy-to-use interfaces to complicated tasks.
%% %This pattern abstracts a simpler interface out of a complex one.
%% \lstinputlisting{./oop_prep/Design_pattern_facade.py}
%% Now we can use the above simple facade class to send and receive
%% messages much easier than if we have to interact directly with the
%% complex libraries (\texttt{smtplib} and \texttt{imaplib}).
%% In fact, the library \texttt{smtplib} itself is an abstraction for the SMTP (Simple Mail Transfer Protocol).
%% Other facades:
%% \begin{itemize}
%% \item \texttt{for} loops
%% \item \texttt{list} comprehensions
%% \item Generators
%% \end{itemize}
%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% \foilhead{Design patterns - the singleton pattern}
%% SKIP. SKIP. SKIP. SKIP. SKIP. SKIP.
%% Only one instance of class is created (not matter how many times we create objects of that class).
%% \lstinputlisting{./oop_prep/singleton_pattern.py}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Responsibility-driven design}
Nine principles in Craig Larman's GRASP (General Responsibility Assignment Software Patterns).
These principles are a learning aid for object-oriented design with responsibilities.
Use methods to fulfill responsibilities.
\begin{itemize}
\item Information Expert. \newline \newline
PROBLEM: What is a basic principle by which to assign responsibilities
to an object? \newline
SOLUTION: Assign a responsibility to the class that has the information
needed to respond to it. \newline
Examples:
\begin{itemize}
\item Assign a {\em search} responsibility to a Catalog object, since the Catalog object has the information for all books in the library.
\item Assign a {\em locate} responsibility to a LibraryItem object, since the LibraryItem object has the information for the DDS number for the book.
\end{itemize}
\item Creator. \newline \newline
PROBLEM: Who creates an object A?\newline
SOLUTION: Assign class B the responsibility to create
an instance of class A if one of these is true:
\begin{itemize}
\item B ``contains'' or completely aggregates A
\item B records A
\item B closely uses A
\item B has the initializing data for A
\end{itemize}
Example: \newline
\begin{itemize}
\item Assign Catalog the responsibility to create LibraryItem objects, since Catalog ``contains'' library items.
\item Assign Notebook the responsibility to create Note objects, since Notebook ``contains'' notes.
\end{itemize}
\item Controller. \newline \newline
PROBLEM: What first object (beyond the UI layer) receives and coordinates a System Operation?\newline
SOLUTION: Assign the responsibility to an object representing one of
these choices:
\begin{itemize}
\item Represents the overall ``system'', a root object.
\item Represents a use case scenario within which the system operation occurs.
\end{itemize}
Example: \newline
\begin{itemize}
\item Assign the responsibility to Notebook object. The UI layer is represented by class Menu (page 55 in Dusty Phillips book).
\end{itemize}
\item Low Coupling
\item High Cohesion
\item Polymorphism. \newline \newline
PROBLEM: How to handle alternatives based on type? \newline
SOLUTION: Giving the same name to similar or related services. \newline
Example: \newline
\begin{itemize}
\item LibraryItem is inherited by Book, CD, and DVD, each having the same service {\em locate}.
\end{itemize}
\item Pure Fabrication. \newline \newline
PROBLEM: Sometimes assigning responsibilities only to domain
layer software classes leads to problems like poor
cohesion or coupling, or low reuse potential. \newline
SOLUTION: Assign a highly cohesive set of responsibilities to a convenience class that does not represent a
domain concept. \newline
Example: \newline
\begin{itemize}
\item Make a fabricated class called Cup that holds the dice, roll them, and know their total. Cup can be reused in other applications.
\end{itemize}
\item Indirection
\item Protected Variations
\end{itemize}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\foilhead{Test-driven development}
It forces writing tests before writing code.
It helps understand requirements better.
A good reading: Yamaura, Tsuneo. "How to Design Practical Test Cases." IEEE Software (November/December 1998): 30-36.
It ensures that code continues working after we make changes.
Note that changes to one part of the code can inadvertently break other parts.
\end{document}
|