diff --git a/Course.md b/Course.md index 702ab92aea31de40e57ff6af70d7c71015428f05..5e92d677669113e1f4ebf5f7c9ba0d24a9233904 100644 --- a/Course.md +++ b/Course.md @@ -17,16 +17,18 @@ header-includes: } --- -# Introduction — programming +# Introduction — programming and Java -Before we start learning the Java language, it might be useful to take some -time to think about programming in general. We will make broad remarks that are -not things to know for themselves but will hopefully shed an interesting light -on what we are going to do when we actually start doing things in Java. There -are many ways to program, many languages, many paradigms, but capturing their -similarities will not only prevent us from getting lost in what we're trying to -achieve, it will also allow us to understand what is unique to Java and how we -can leverage that to ease our task. +Java is a statically-typed, object-oriented, programming language designed to +write programs which are compiled to a bytecode for a virtual machine. Before we +start learning the Java language itself, let us think about programming in +general and define the technical terms in the previous sentence. + +## Architecture + +## Types + +## Object-oriented ## Formulas and computations @@ -45,7 +47,7 @@ object and assigns it its value. about modeling… well, "things", that we will smugly call "objects". Actual Java "objects" will be defined properly in the next chapter. -But this symbolic definition is of no use when actual values are needed in a +But such a symbolic definition is of no use when actual values are needed in a concrete application like engineering or statistics. Converting those formulas into actionable data is an entirely different matter that doesn't always rely on the same kind of skills : there starts the realm of computing where notions like @@ -402,11 +404,11 @@ useful *models* of actual problems we want to solve. Doing so requires a toolbox to define those models : data structures. Contrary to what one could believe thinking of programs as "cooking recipe" for -computers, an import part of a program is *describing* things instead of *doing* -things. The following constructs might hence seem hard to understand, because -they don't really achieve much in themselves. They are nonetheless as important -as the next section and should be properly understood before attempting to write -anything. +computers, an important part of a program is *describing* things instead of +*doing* things. The following constructs might hence seem hard to understand, +because they don't really achieve much in themselves. They are nonetheless as +important as the next section and should be properly understood before +attempting to write anything. Because it is easier to describe a set by giving examples of elements it contains, we will in this section present built-in Java types as well as valid diff --git a/IST-4-JAV.md b/IST-4-JAV.md index ba89733b0963500d69a8806f89889270213497ac..40848c70a1ef8b47fef457689df80009407b25ec 100644 --- a/IST-4-JAV.md +++ b/IST-4-JAV.md @@ -4,9 +4,12 @@ title: IST-4-JAV: Java programming # Classes -- 2021-09-21 (tue./ç«): the [slides](no-backup/Class1.pdf) -- 2021-09-24 (fri./金): the [slides](no-backup/Class2.pdf), the [worksheet](no-backup/Worksheet2.pdf) for practice -- 2021-09-28 (tue./ç«): the [slides](no-backup/Class3.pdf), the [worksheet](no-backup/Worksheet3.pdf) for practice -- 2021-10-19 (tue./ç«): the [slides](no-backup/Class4.pdf), the [worksheet](no-backup/Worksheet4.pdf) for practice -- 2021-10-20 (wed./æ°´): the [slides](no-backup/Class5.pdf), no worksheet but the - [sources](no-backup/EmptyWindow.zip) for the longish empty window : ) +- 2022-09-21 (wed./æ°´): the [slides](no-backup/Class1.pdf), the [worksheet](no-backup/Worksheet1.pdf) for practice +- 2022-09-24 (wed./æ°´): the [slides](no-backup/Class2.pdf), the [worksheet](no-backup/Worksheet2.pdf) for practice +- 2022-09-28 (wed./æ°´): the [slides](no-backup/Class3.pdf), the [worksheet](no-backup/Worksheet3.pdf) for practice +- 2022-10-19 (wed./æ°´): the [slides](no-backup/Class4.pdf), the [worksheet](no-backup/Worksheet4.pdf) for practice +- 2022-10-20 (wed./æ°´): the slides, the worksheet for practice + +# Evaluation + +Due 2022-11-09 (wed./æ°´): the [assignment](no-backup/Assignment.pdf) diff --git a/Makefile b/Makefile index b97c3e80c6bc0d41bea4141906dafece03f957dc..0c4662e9361046bc4bed2430ea59e0051d43dedd 100644 --- a/Makefile +++ b/Makefile @@ -3,20 +3,22 @@ pdfs = $(foreach f,$(wildcard $(1)/*.md),$(patsubst %.md,%.pdf,$(f))) MODEL_PARALLELOGRAM = $(call graphs,$(foreach i,0 1 2 3,parallelogram$(i))) INHERITANCE_GRAPHS = $(call graphs,classesTree exceptionsTree) -IMPLEMENTATION_GRAPHS = $(call graphs,arrayList implementations linkedList newCellArrayList newCellLinkedList) +IMPLEMENTATION_GRAPHS = $(call graphs,arrayList implementations linkedList newCellArrayList newCellLinkedList hashMap) BOX = $(call graphs,nestedBox) +COURSE = IST-4-JAV_Course.pdf SLIDES = $(call pdfs,Slides) WORKSHEET = $(call pdfs,Worksheet) WEBPAGE = IST-4-JAV.html -all: Course.pdf $(SLIDES) $(WORKSHEET) $(WEBPAGE) +all: $(COURSE) $(SLIDES) $(WORKSHEET) $(WEBPAGE) -Course.pdf: Course.md $(MODEL_PARALLELOGRAM) +$(COURSE): Course.md $(MODEL_PARALLELOGRAM) pandoc --toc $< -o $@ -Slides/Class1.pdf: $(MODEL_PARALLELOGRAM) figures/helloworld.tex +Slides/Class1.pdf: Slides/Class1.md $(MODEL_PARALLELOGRAM) figures/helloworld.tex + pandoc --slide-level=3 -t beamer $< -o $@ Slides/Class3.pdf: $(INHERITANCE_GRAPHS) Slides/Class4.pdf: $(IMPLEMENTATION_GRAPHS) Slides/Class4.pdf: $(BOX) @@ -34,4 +36,4 @@ Worksheet/%.pdf: Worksheet/%.md pandoc -s $< -o $@ clean: - rm -f $(MODEL_PARALLELOGRAM) $(INHERITANCE_GRAPHS) Course.pdf $(SLIDES) + rm -f $(MODEL_PARALLELOGRAM) $(INHERITANCE_GRAPHS) $(COURSE) $(SLIDES) diff --git a/Slides/Class1.md b/Slides/Class1.md index a5859f8cf5054d8f55561bf534543cac839c9af2..91cb48c294e018e9a1b82640dbb6a729689705bc 100644 --- a/Slides/Class1.md +++ b/Slides/Class1.md @@ -1,25 +1,61 @@ --- title: IST-4-JAV Java Programming -subtitle: Class 1 — Discovering Java +subtitle: Class 1 — (re ?)Discovering Java author: Alice BRENON `<alice.brenon@liris.cnrs.fr>` -date: 2021-09-21 +date: 2022-09-21 +institute: + \includegraphics[height=.9cm]{figures/LIRIS}\quad + \includegraphics[height=.9cm]{figures/INSA} header-includes: \usepackage{fdsymbol} \usepackage{textgreek} \usepackage{bclogo} - \usepackage{hyperref} - \usepackage{color} - \definecolor{yellow}{RGB}{255, 127, 0} - \definecolor{greyblue}{RGB}{58, 103, 183} - \hypersetup{ - colorlinks, - linkcolor = yellow, - urlcolor = greyblue - } - \usetheme{Frankfurt} - \usecolortheme{seahorse} + \usepackage{Beamer/beamerthemePerso} + \setcounter{tocdepth}{1} --- +## Foreword: the IST-4-JAV course {-} + +### Timetable + +#### 20h: 5×4h-sessions + +- 2022-09-21 (today !) +- 2022-09-28 +- 2022-10-12 +- 2022-10-19 +- 2022-10-26 +- (every wednesday 8:00 - 12:00 until october the 26\textsuperscript{th} + included except 2022-10-05) + +#### Time repartition + +- ~2h course +- (some break in-between) +- ~2h practice + +### Course material + +[https://perso.liris.cnrs.fr/abrenon/IST-4-JAV.html](https://perso.liris.cnrs.fr/abrenon/IST-4-JAV.html) + +### How to pass this class ? + +#### Evaluation + +- Game project demonstrating the object-oriented concepts seen in class +- Remediation exam: some (boring) test on paper (no computer allowed) + +#### Time-budget + +- 20h together in class +- 20h at home + + 1h½ after each class + + 12h½ project + +--- + +\tableofcontents + # About programming ## Maths vs. Calculation @@ -205,7 +241,7 @@ $$132 + 41 = ??$$ \end{align*} \begin{center} -$\medbackslash\,\hat{}$ \texttheta \, $\hat{}\,\medslash$ +$\medbackslash\,\hat{}$ $\theta$ $\hat{}\,\medslash$ \end{center} ## Modeling things @@ -227,6 +263,52 @@ $\medbackslash\,\hat{}$ \texttheta \, $\hat{}\,\medslash$ \only<4>{\includegraphics[height=50px]{graphs/parallelogram3.png}} \end{center} +### The core of programming + +- defining abstract concepts from a concrete implementation (the **right** + level) + + too complex: it's slow + + too simple: it's hard to use +- solve problems using the abstraction +- have a system translate it to the implementation +- repeat +- run + +### Layers + +:::columns +::::{.column width=35%} +- higher-level languages +- C +- assembly +- machine binary +:::: +::::{.column width=55%} +\vspace{1cm} +$\updownarrow$ compilation / interpretation +:::: +::: + +### Compiling vs. Interpreting + +:::columns +::::column +**Compiler** + +- generate low-level from high-level +- optimized, fast +:::: +::::column +**Interpreter** + +- translated on the fly (duality program / data) +- generally slower (+ loading time) +- portable ! +:::: +::: + +## Numbers again + ### Calculators - boring rules @@ -260,118 +342,78 @@ $\bcdanger$ physical limits (overflow) ### Anything is a number -**Truth value** +#### Directly ("native") +- **Truth value** True or False, 2 values $\rightarrow$ 1, 0 -**Numbers** +- **Numbers** obvious **but** overflow -**Characters** - -- very natural (remember non-positional systems ?) -- known for very long (before Cæsar) ! -- $\rightarrow$ encodings (ASCII, UTF-8…) - -**Sequences** +- **Characters** + + very natural (remember non-positional systems ?) + + known for very long (before Cæsar) ! + + $\rightarrow$ encodings (ASCII, UTF-8…) +#### As a sequence - notion of memory - special strategies: "stop" symbol vs. length - -**From there** - -- text - "large" numbers -- pictures - -## Piling layers - -**Reminder: our plan** - -- High level models $\rightarrow$ numbers $\rightarrow$ "calculator" -- keeping structure -- compute valuable answers as numbers -- High level models $\leftarrow$ numbers $\leftarrow$ "calculator" +- text +- multimedia -### Processor +### Physically :::columns ::::column {height=120px} - :::: ::::column {height=120px} - :::: ::: -- number represented by sets of digits: *word* -- several input and output numbers: *registers* -- hardwired for several operations: sum, multiplication, bit shift, xor… -- number of bits + set of native instructions: *architecture* -- clocked in cycles - ---- - -**Registers** - -- data: 4 numbers to perform a computation and read the result -- address: "focus" on the memory, **next instruction** -- status: overflow ? null ? parity (number of '1') ? + many more +- many more wires +- *control* wires vs. *data* wires +- $\rightarrow$ registers +- operations are numbers too ! -{height=100px} +### The right word -\begin{center} -Electrical circuit, "numbers" $\rightarrow$ very low level -\end{center} +An *atomic* number $\doteq$ a *word* -### Assembly +**How to choose the right bits size** -:::columns -::::column - -- names registers: `EAX`, `EBX`, `CS`, `IP`… -- name instructions: `mov`, `add`, `xor`, `jz`… -- sections to hold code, data + notion of "entry point" -- follows closely the layout of the processor -:::: -::::column -\input{figures/helloworld.tex} -:::: -::: +- too large is painful to build +- too small is painful to use (slow) -### C +### Instructions -- variables ! (beware of names) -- loops ! -- functions ! (beware of names too!) -- "imperative approach": do this, modify that +- the **paths** in the circuit +- at the **electrical** level +- **hardwired** operations + + sum + + multiplication + + bit shift + + xor + + … -### Compiling vs. Interpreting +### Architecture -:::columns -::::column -**Compiler** +word size + set of instructions = a "machine" -- generate low-level from high-level -- optimized, fast -:::: -::::column -**Interpreter** +**Examples** -- translated on the fly (duality program / data) -- generally slower (+ loading time) -- portable ! -:::: -::: +- x86\_64 +- arm64 +- i686 +- riscv64 -\vspace{1cm} +### Virtual architecture -In practice, much is reused: +- data: *numbers* +- operations: *numbers* -- high-level $\rightarrow$ C -- C $\rightarrow$ assembly -- assembly $\rightarrow$ binary +$\Rightarrow$ we can have *programs* pretending to be *machines* (see Turing machines) ## Java @@ -416,18 +458,57 @@ In practice, much is reused: Contains real bits of Java. - `this` is for actual valid code +- `<THIS>` is for meta bits of code (templating) - mind the case, the quotes, etc. +## Types + +### What they are + +How to navigate the "everything is a number" soup ? + +. . . + +$\rightarrow$ *flags* + +- boundaries (size) +- purpose, intention +- $\sim$ sets in maths +- prevent (some) errors + +### Usage + +#### Convention + +- native (lowercase) +- sequences (uppercase-first) +- `void` + +#### Every value or function + +must be annotated with its type (Java does it too and compares) + +### Pro-tip + +In `jshell` type + +- */vars* : to print the known variables with their type +- */set feedback verbose* : to include the type of expressions in the evaluation + output + +This is **not Java** ! only special commands for the interpreter + ## Data structures -### "Numbers" +### "native" numbers +:::columns +::::{.column width=100%} #### Truth values -\begin{description} -\item[\texttt{boolean}] \hfill \\ - useful for tests, logic, but 1\textsuperscript{st} class values -\end{description} +- `boolean` useful for tests +:::: +::: **Examples** @@ -436,18 +517,16 @@ Contains real bits of Java. --- +:::columns +::::{.column width=100%} #### Integers -\begin{description} -\item[\texttt{byte}] \hfill \\ - 8 bits integers $\rightarrow [-128,127]$ -\item[\texttt{int}] \hfill \\ - 32 bits integers $\rightarrow [-2147483648,2147483647]$ -\item[\texttt{short}] \hfill \\ - 16 bits integers $\rightarrow [-32768,32767]$ -\item[\texttt{long}] \hfill \\ - 64 bits integers $\rightarrow [-2^{63},2^{63}]$ -\end{description} +- `byte` 8 bits integers $\rightarrow [-128,127]$ +- `int` 32 bits integers $\rightarrow [-2147483648,2147483647]$ +- `short` 16 bits integers $\rightarrow [-32768,32767]$ +- `long` 64 bits integers $\rightarrow [-2^{63},2^{63}]$ +:::: +::: **Examples** @@ -458,14 +537,14 @@ Contains real bits of Java. --- +:::columns +::::{.column width=100%} #### Decimal numbers -\begin{description} -\item[\texttt{float}] \hfill \\ - 32 bits decimal numbers, scientific notation, significand/exponent -\item[\texttt{double}] \hfill \\ - same with 64 bits (+ precision) -\end{description} +- `float` 32 bits decimal numbers, scientific notation, significand/exponent +- `double` same with 64 bits (+ precision) +:::: +::: **Examples** @@ -476,12 +555,13 @@ Contains real bits of Java. --- +:::columns +::::{.column width=100%} #### Unicode characters -\begin{description} -\item[\texttt{char}] \hfill \\ - 16 bits, UTF-16, written between simple quotes -\end{description} +- `char` 16 bits, UTF-16, written between simple quotes +:::: +::: **Examples** @@ -491,23 +571,20 @@ Contains real bits of Java. - `'\u00e9'` (code point) - `10`, `0x27` -### "Compounds" $\equal$ objects +### "sequences" $\equal$ objects +:::columns +::::{.column width=100%} #### "Arbitrary" precision -\begin{description} -\item[\texttt{BigInteger}] \hfill \\ - large integers -\item[\texttt{BigDecimal}] \hfill \\ - large decimal numbers -\end{description} +- `BigInteger` large integers +- `BigDecimal` large decimal numbers #### Text -\begin{description} -\item[\texttt{String}] \hfill \\ - immutable sequences of characters -\end{description} +- `String` immutable sequences of characters +:::: +::: **Examples** @@ -535,7 +612,7 @@ Contains real bits of Java. #### Concept -- give a meaningful name to a value +- give a **meaningful** name to a value - absolutely abstract, will need to refer to a place in the memory - a "wire", "bringing" the value (*no copy*) @@ -556,13 +633,13 @@ Contains real bits of Java. - clarify intent - not a remedy for bad naming - not needed to caption the obvious -- can content the documentation (*javadoc*) +- can contain the documentation (*javadoc*) ### Syntax **Rest of line** -``` +```java // this is a comment 4 // it doesn't have to start with the line // but it ends it so this is not a number: 17 @@ -570,7 +647,7 @@ Contains real bits of Java. **General comments** -``` +```java /* these comment can start on a line and end on another one */ /* Since they have an end, this is a number: */ 4 @@ -585,14 +662,11 @@ Contains real bits of Java. - name it ("beware of names" !) - has several input types and one output type for its result -#### Built-in functions +#### Built-in functions examples -\begin{description} -\item[type conversions] \hfill \\ - \texttt{Integer.parseInt}, \texttt{Integer.toString}… -\item[maths toolbox] \hfill \\ - \texttt{Math.max}, \texttt{Math.min}, \texttt{Math.exp}… -\end{description} +- **type conversions** \texttt{Integer.parseInt}, \texttt{Integer.toString}… +- **maths toolbox** \texttt{Math.max}, \texttt{Math.min}, \texttt{Math.exp}… +- … ### Procedures @@ -630,12 +704,10 @@ Contains real bits of Java. **Examples** -``` -System.out.println // display object on the console -"some string".length -userName.charAt -password.equals -``` +- `System.out.println` +- `"some string".length` +- `userName.charAt` +- `password.equals` ### About the memory @@ -661,14 +733,18 @@ password.equals - compute a value - constants - variables (in a context where they are defined — "plugged wire") +- any other type #### Statements - do something (change state) - only "atomic" statement: variable declaration +- type `void` --- +:::columns +::::{.column width=100%} #### Declaring a variable - reserve space in memory @@ -676,10 +752,12 @@ password.equals - can be set with an initial value, but always initialized + "numbers": to the equivalent of `0` + objects: to `null` +:::: +::: **Examples** -``` +```java int messageLength; String userName; char firstLetter = 'a'; @@ -687,6 +765,8 @@ char firstLetter = 'a'; ### Nesting +:::columns +::::{.column width=100%} #### Expressions - if `e` is an expression, so is `(e)` @@ -697,53 +777,74 @@ char firstLetter = 'a'; - if `s1` and `s2` are statements, `s1; s2` is a statement - semantics: `s1` then `s2` - in practice, wrap all the list within `{`…`}` +:::: +::: -``` +```java { s1; s2; s3; … ; sn } ``` ### Casts +:::columns +::::{.column width=100%} #### Use - force a conversion between types +- may lose information (beware of truncation) - (give hints to Java) - -#### Syntax +:::: +::: assuming - `t` is a type -- `e` is an expression +- `<VALUE>` is an expression -``` -(t) e +```java +(t) <VALUE> ``` -is an expression of type `t` with value "projected" from `e` +is an **expression** of type `t` with value "projected" from `<VALUE>` -**Examples** +### Casts examples +```java +(short) 4 // still 4, but coded on 16 bits +(byte) 'c' // == 99 +(float) (2.5 / 2) // still 1.25, but as a float ``` -(short) 4 -(byte) 'c' -(float) (2.5 / 2) + +A full example of truncation + +```java +int gregYear = 2022; // set an initial value +byte byteGregYear = (byte) gregYear; /* works, but +byteGregYear ==> -26 +the 32-bits int was truncated to 8-bits byte ! +(and 2022 % 0x100 == -26)*/ +(int) byteGregYear; +/* $3 ==> -26 +the original information was lost */ ``` ### Function application -- a call to a function or an operator is an expression -- a call to a procedure is a statement +- a call to a function or an operator is an **expression** +- a call to a procedure is a **statement** +:::columns +::::{.column width=100%} #### Syntax - - function or procedure: its name followed by the comma-separated arguments between parentheses - operators: the symbol before, between or after its argument(s) +:::: +::: **Examples** -``` +```java !false total / count "Hello, " + "world !" @@ -753,152 +854,136 @@ System.out.println(someMessage); ### Variable assignment -an expression that +an expression which - changes a value in the memory - returns a value -#### Syntax - assuming - `a` is a variable of type `t` -- `e` is an expression of type `t` +- `<VALUE>` is an expression of type `t` +```java +a = <VALUE> ``` -a = e -``` - -is an expression wich assigns the value of `e` to `a` and has the same value ---- - -#### Assignment operators - -**Binary** +is an **expression** wich assigns the value of `<VALUE>` to `a` and has the same value -- the previous monoidal (except `boolean`) operators followed by `=` -- `+=`, `*=`, `/=`, `|=`, `<<=`… +### Assignment operators -**Unary** +- **Binary** the previous binary (except `boolean`) operators followed by `=` + (`+=`, `*=`, `/=`, `|=`, `<<=`…) +- **Unary** + + shortcuts for the pattern `a = a · 1` (· : '+' or '-') + + *increment*: `++` / *decrement*: `--` + + before or after the variable: value after or before the change -- shortcuts for the pattern `a = a · 1` (· : '+' or '-') -- *increment*: `++` / *decrement*: `--` -- before or after the variable: value after or before the change - -``` +```java int a = 4; ++a; // a is now 5, the line evaluates to 5 --a; // a is back to 4, the line evaluates to 4 -int b = a++; // read, then increment: a is now 5, b is 4 -a--; // a is back to 4 again, the line evaluates to 5 +int b = a++; // read then increment: a is now 5 + // b is 4 +a--; // a is back to 4 again, the line evaluates + // to 5 ``` ## Control structures 101 -### Conditionals - -#### Conditional statement +### Conditional statement assuming -- `test` is an expression of type `boolean` -- `statement_when_true` and `statement_when_false` are statements +- `<TEST>` is an expression of type `boolean` +- `<WHEN_TRUE>` and `<WHEN_FALSE>` are statements :::columns ::::column -``` -if(test) { - statement_when_true +```java +if(<TEST>) { + <WHEN_TRUE> } else { - statement_when_false + <WHEN_FALSE> } ``` :::: ::::column -``` -if(test) { - statement_when_true +```java +if(<TEST>) { + <WHEN_TRUE> } ``` :::: ::: -\vspace{0.5cm} - -are statements which: +are **statements** which: -- if `test` evaluates to `true`, execute `statement_when_true` -- otherwise execute `statement_when_false` (or nothing for the shorter form) - ---- +- if `<TEST>` evaluates to `true`, execute `<WHEN_TRUE>` +- otherwise execute `<WHEN_FALSE>` (or nothing for the shorter form) -#### Conditional expression +### Conditional expression assuming -- `test` is an expression of type `boolean` -- `expression_when_true` and `expression_when_false` are expressions +- `<TEST>` is an expression of type `boolean` +- `<WHEN_TRUE>` and `<WHEN_FALSE>` are expressions +```java +<TEST> ? <WHEN_TRUE> : <WHEN_FALSE> ``` -test ? expression_when_true : expression_when_false -``` - -\vspace{0.5cm} - -is an expression which value is: -- `expression_when_true` if `test` evaluates to `true` -- `expression_when_false` otherwise +is an **expression** which value is: -### Loops +- `<WHEN_TRUE>` if `<TEST>` evaluates to `true` +- `<WHEN_FALSE>` otherwise -#### `for` +### `for` loops assuming -- `initialize` and `iterate` are statements -- `test` is an expression of type `boolean` +- `<INITIALIZE>`, `<ITERATE>` and `<BLOCK>` are statements +- `<TEST>` is an expression of type `boolean` -``` -for(initialize; test; iterate) { - block +```java +for(<INITIALIZE>; <TEST>; <ITERATE>) { + <BLOCK> } ``` -is a statement which: +is a **statement** which: -- executes `initialize` -- if `test` evaluates to `true`, executes `block` then `iterate` then start over - from this line +- executes `<INITIALIZE>` +- if `<TEST>` evaluates to `true`, executes `<BLOCK>` then `<ITERATE>` then + start over from this line - otherwise stops --- -#### `while` +### `while` loops assuming -- `test` is an expression of type `boolean` -- `block` is a statement +- `<TEST>` is an expression of type `boolean` +- `<BLOCK>` is a statement -``` -while(test) { - block +```java +while(<TEST>) { + <BLOCK> } ``` -is a statement which: +is a **statement** which: -- if `test` evaluates to `true`, executes `block` and start over from this line +- if `<TEST>` evaluates to `true`, executes `<BLOCK>` and start over from this + line - otherwise stops - -# Introducing the compiler +# Using it ## How things work in general @@ -908,10 +993,38 @@ is a statement which: - compiles ("source") code to binary - binary is not for the physical architecture but for the Java Virtual Machine +### Java projects + +- organized in packages (folders) +- packages contain classes (files) +- classes contain "code" + + values + + methods + +### Names + +:::columns +::::{.column width=45%} +#### The Operating System + +- file system path +- separated by `/` +- `.java` extension +:::: +::::{.column width=45%} +#### Java + +- package / classes +- separated by `.` +- no extension +:::: +::: + ### Compilation +**Operating System** $\rightarrow$ **Java** + - `static` -- a text file written in Java - `.java` extension - compiled into bytecode `.class` - may catch some mistakes @@ -926,7 +1039,7 @@ javac [OPTIONS] PATH_TO_SOURCE_FILE - the `.class` run by the JVM - may catch some other errors -``` +```sh java [OPTIONS] PATH_TO_BYTECODE ``` @@ -938,27 +1051,31 @@ java [OPTIONS] PATH_TO_BYTECODE - useful to test stuff while programming - also to find bugs -``` +```sh jshell ``` -enters a prompt where the above commands can be evaluated +enters a prompt which evaluates Java code + +([https://onecompiler.com/jshell/](https://onecompiler.com/jshell/)) ### Read the documentation #### Main page of the official Java documentation -[https://docs.oracle.com/en/java/javase/17/index.html](https://docs.oracle.com/en/java/javase/17/index.html) +[https://docs.oracle.com/en/java/javase/19/docs/api/index.html](https://docs.oracle.com/en/java/javase/19/docs/api/index.html) #### Some particularly interesting modules and packages to start -- [`java.base`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/module-summary.html) -- [`java.lang`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/package-summary.html) +- [`java.base`](https://docs.oracle.com/en/java/javase/19/docs/api/java.base/module-summary.html) +- [`java.lang`](https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/package-summary.html) -#### For example, looking up class +### Example -[String](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html) +[String](https://docs.oracle.com/en/java/javase/19/docs/api/java.base/java/lang/String.html)  -### Time for practice : ) +## Time for practice : ) {-} + +[https://perso.liris.cnrs.fr/abrenon/IST-4-JAV.html](https://perso.liris.cnrs.fr/abrenon/IST-4-JAV.html) diff --git a/Slides/Class2.md b/Slides/Class2.md index b9f7fa70cf414637db549ffd2cff949add1d05ad..4073b0893fe501ad72408fc5f7dc25ee84f357a7 100644 --- a/Slides/Class2.md +++ b/Slides/Class2.md @@ -2,22 +2,16 @@ title: IST-4-JAV Java Programming subtitle: Class 2 - Enough to fly author: Alice BRENON `<alice.brenon@liris.cnrs.fr>` -date: 2021-09-24 +date: 2022-09-28 +institute: + \includegraphics[height=.9cm]{figures/LIRIS}\quad + \includegraphics[height=.9cm]{figures/INSA} header-includes: \usepackage{fdsymbol} \usepackage{textgreek} \usepackage{bclogo} - \usepackage{hyperref} - \usepackage{color} - \definecolor{yellow}{RGB}{255, 127, 0} - \definecolor{greyblue}{RGB}{58, 103, 183} - \hypersetup{ - colorlinks, - linkcolor = yellow, - urlcolor = greyblue - } - \usetheme{Frankfurt} - \usecolortheme{seahorse} + \usepackage{Beamer/beamerthemePerso} + \setcounter{tocdepth}{1} --- # Making functions and procedures @@ -30,7 +24,7 @@ header-includes: int initValue = 221; while(initValue > 1) { System.out.println(initValue); - if(initValue % 2 = 0) { + if(initValue % 2 == 0) { initValue /= 2; } else { initValue = 3*initValue + 1; @@ -40,38 +34,7 @@ while(initValue > 1) { - `initValue` is modified ! - $\rightarrow$ need to reset it - naming issue: at the end it's actually the "final" value -- not *reusable*, *composable* - -### Purity vs. side effects - -:::columns -::::column - -#### Maths, again ! - -$$ -f\colon \begin{tabular}{r c l} - A & $\rightarrow$ & B\\ - x & $\mapsto$ & f(x) - \end{tabular} -$$ - -- doesn't "change" `x` -- stable: always returns the same thing - -:::: -::::column - -#### Side effects - -Sometimes programs need to - -- alter values -- interact with the outside world -- notion of "state" of the program - -:::: -::: +- not *reusable* nor *composable* ### Function as an interface @@ -90,25 +53,48 @@ Sometimes programs need to ## How ? +### Example: is a `char` contained in a `String` ? + +We know how to + +- compare 2 `char`s (`==`) +- access a `char` at a given index in a `String` (`.charAt`) +- iterate over a `String` (`for` loop) + +. . . + +$\rightarrow$ algorithm + +``` +for each index i within the input string s: + compare the char c with the one at index i + if they are equal + return true + otherwise + keep going +endfor +return false +``` + ### The `head` of a function ```Java -String findRepetition(String haystack, int size) { +boolean contains(String haystack, char needle) ``` -*legend* - -- `String`: output type -- `findRepetition`: function name +- `boolean`: output type +- `contains`: function name - `(…, …)`: arguments are defined as a tuple - `String haystack`: each argument is defined by its type and its name + $\rightarrow$ variable ### A new statement: `return` - only available in a function/method declaration - stops the current function - "eliminates" the value of an expression $\rightarrow$ a statement -- must match the type of the function ($\|$ declaring a variable) +- must match the type of the function (like declaring a variable) +- "closing the box" ### Examples @@ -116,54 +102,54 @@ String findRepetition(String haystack, int size) { ```Java return 4; // ok in an int, double, etc., function -return; // ok in a void function +return; // ok in a procedure (void function) ``` **Incorrect use** ``` int n = return 2; // bad ! won't compile -someFunction(return 2); // bad ! won't compile either +someFunction(return 2); // bad ! won't compile + // either ``` ### The body -- "regular" code like in `jshell` +- "regular" (= *imperative*) code like in `jshell` - "virtual" environment, "suspended" computation, "assumption" - can declare variables, use statements, call other functions… - every "exit" must be checked: `return;` by default, but that is `void` +### Implementing the body + +**Context** + +- `needle`: the `char` we're looking for +- `haystack`: the `String` where we're searching + ```Java -for(int i = 0; i <= haystack.length() - size; i++) { - char repeated = haystack.charAt(i); - boolean isFound = true; - for(int j = 1; isFound && j < size; j++) { - isFound = haystack.charAt(i + j) == repeated; - } - if(isFound) { - return haystack.substring(i, size); +for(int i = 0; i < haystack.length(); i++) { + if(haystack.charAt(i) == needle) { + return true; } } -return null; +return false; ``` ### Wrapping it up ```Java -String findRepetition(String haystack, int size) { - for(int i = 0; i <= haystack.length() - size; i++) { - char repeated = haystack.charAt(i); - boolean isFound = true; - for(int j = 1; isFound && j < size; j++) { - isFound = haystack.charAt(i + j) == repeated; - } - if(isFound) { - return haystack.substring(i, i + size); +boolean contains(String haystack, char needle) { + for(int i = 0; i < haystack.length(); i++) { + if(haystack.charAt(i) == needle) { + return true; } } - return null; + return false; } ``` +## Meditations + ### Good practice - give clear, meaningful names to your functions @@ -171,6 +157,59 @@ String findRepetition(String haystack, int size) { - give clear, meaningful names to its arguments - functions should do "one thing" +### Purity vs. side effects + +:::columns +::::column + +#### Maths, again ! + +$$ +f\colon \begin{tabular}{r c l} + A & $\rightarrow$ & B\\ + x & $\mapsto$ & f(x) + \end{tabular} +$$ + +- doesn't "change" `x` +- stable: always returns the same thing + +:::: +::::column + +#### Side effects + +Sometimes programs need to + +- alter values +- interact with the outside world +- notion of "state" of the program +- `void` type + +:::: +::: + +### Comparison with other loops + +:::columns +::::{.column width=45%} +*Similarities* + +- "canned" code +- the body within `{` … `}` +- made of statements +:::: +::::{.column width=45%} +*Differences* + +- loops are directly applied +- you can chose function names +- they have a return type +- applying them makes expressions (function) or statements (procedure) + +:::: +::: + # More data ! ## "Object-Oriented" @@ -225,22 +264,22 @@ Plato: the "Theory of Forms/Ideas" - just like in `jshell` : may set a value or not (always a default) ```Java -int roomNumber; -String buildingName; +int room; +String building; ``` ### A "constructor" - define the *how*, the "mold" part +- it's just a function ! (can take parameters) - both the return type *and* the name of the function - usually initializes the fields -- like a regular function, can take parameters - always a default constructor: no arguments, does nothing ```Java -Room(int roomNumber, String buildingName) { - this.roomNumber = roomNumber; - this.buildingName = buildingName; +ClassRoom(int room, String building) { + this.room = room; + this.building = building; } ``` @@ -253,24 +292,26 @@ Room(int roomNumber, String buildingName) { ```Java String view() { - return this.buildingName + ":" + this.roomNumber; + return this.building.charAt(0) + + "-" + this.room; } ``` ### All together now ```Java -class Room { - int roomNumber; - String buildingName; +class ClassRoom { + int room; + String building; - Room(int roomNumber, String buildingName) { - this.roomNumber = roomNumber; - this.buildingName = buildingName; + ClassRoom(int room, String building) { + this.room = room; + this.building = building; } String view() { - return this.buildingName + ":" + this.roomNumber; + return this.building.charAt(0) + + "-" + this.room; } } ``` @@ -289,7 +330,7 @@ class Room { ### Creating objects ```Java -Room someRoom = new Room(17, "Russell"); +ClassRoom javaLab = new ClassRoom(17, "Hopper"); ``` - `new` tells Java we're going to allocate some space @@ -297,11 +338,25 @@ Room someRoom = new Room(17, "Russell"); - an empty "box" is created - the code for the constructor is called +### (What's `this` ? What's `this` ? I can't believe my eyes…) + +```Java +Room(int room, String building) { + this.room = room; + this.building = building; +} +``` + +- the empty, fresh, "box" $\rightarrow$ `this` +- refers to the current instance +- $\approx$ 1\textsuperscript{st} person pronoun + + ### Using fields ```Java -someRoom.roomNumber // an int value (17) -someRoom.view() // a String value ("Russell:11") +javaLab.room // an int value (17) +javaLab.view() // a String value ("H-17") ``` assuming @@ -315,29 +370,14 @@ objectExpression.field is either -- an expression of type `output` -- or a function. - -### (What's `this` ? What's `this` ? I can't believe my eyes…) - -**Remember the constructor and the `new` sequence** - -```Java -Room(int roomNumber, String buildingName) { - this.roomNumber = roomNumber; - this.buildingName = buildingName; -} -``` - -- the empty, fresh, "box" $\rightarrow$ `this` -- refers to the current instance -- $\approx$ 1\textsuperscript{st} person pronoun +- an **expression** of type `output` +- or a **function** or **procedure** ### `static` - related to the "Form" itself, not to any of its instances - *shared* space between instances -- $\implies$ incompatible with the previous `this` ! +- $\implies$ `static` code can refer to `this` ! **Warning** @@ -345,42 +385,56 @@ fields and methods can be `static` $\neq$ constructors can (obviously) not ### Syntax -`static` values must be initialized (no constructors !) +`static` values can be initialized -- during declaration (preferred) -- with an initializer `static` method +- during declaration (preferred $\rightarrow$ no constructors !) +- within a method (`static` or not) ```Java -class AdvancedClass { - static int maxRoomCount = 300; - static void resizeAllBuildings(int newMaxRoomCount) { - maxRoomCount = newMaxRoomCount; +class ClassRoom { + static String separator = "-"; +``` +… +```Java + String view() { + return this.building.charAt(0) + + separator + + this.room; } - - … - } ``` ### Please note - `static` values should only be accessed through the class itself, not one of its - instances (though works). + instances (though it works). **Recommended** ```Java -AdvancedClass.maxRoomCount -AdvancedClass.resizeAllBuildings(100); +ClassRoom.separator; ``` **Not recommended** ```Java -someRoom.maxRoomCount -someRoom.resizeAllBuildings(100); +javaLab.separator; ``` +## Object tooling + +### Wrappers around native types + +- `char` $\rightarrow$ `Character` +- `int` $\rightarrow$ `Integer` +- `double` $\rightarrow$ `Double` +- … + +useful for their `static` methods + +- `Character.isLowerCase` +- `Integer.parseInt` + ### `instanceof` assuming @@ -392,7 +446,7 @@ assuming a instanceof ClassName ``` -is an expression of type `boolean` which evaluates to `true` if `a` belongs to +is an **expression** of type `boolean` which evaluates to `true` if `a` belongs to `ClassName`, `false` otherwise. **Example** @@ -402,38 +456,9 @@ String s = ""; Integer n = 4; s instanceof String // == true n instanceof Integer // == true -s instanceof Integer // == false +s instanceof Integer // will break at compile time ! ``` -## Objects and Functions, sitting in a tree - -### Two strategies - -From lower-level languages (e.g. C): - -#### Pass by value - -- the number `7` doesn't disappear when we apply a function on it -- (maths) functions are pure $\implies$ arguments should be copied -- $\|$ *registers* - -#### Pass by reference - -- the *memory address* of *pointers* -- (nested) objects could be huge, copying is slow -- side-effects impossible on a copy ! - -### "Numbers" and objects again ! - -In Java, calls are by value. - -- "numbers" $\rightarrow$ they *are* their value -- objects $\rightarrow$ the variable only holds the reference ($\rightarrow$ a - machine *word*) to the allocated - space - -$\rightarrow$ we get the best of both worlds - ## Containers ### Arrays @@ -441,15 +466,12 @@ $\rightarrow$ we get the best of both worlds - several values of the same type put together - indexed by an `int` - ($\|$ `String`) -- not objects ! (`.length`: special attribute but no methods) -- `Arrays` (special "object coating" $\|$ Integer) +- `.length`: special attribute but no methods ### Creation -(examples with `char` as the content type) - - type: content type suffixed with `[]` - + `char[]` + + `char[]`, `double[]`, `String[]`, `ClassRoom[]` - value: either + empty (size only): `new char[5]` + pre-initialized: `{'a', 'b', 'c'}` @@ -491,7 +513,7 @@ once an array `a` of length `n` exists in memory it's like: - value: with `new`, like any objects, empty or from another object ```Java -LinkedList<Integer> pages = new LinkedList<Integer>(); +Vector<Integer> pages = new Vector<Integer>(); ``` ### Access @@ -509,24 +531,14 @@ no "cell as a variable" but - notion of type "variable" (`E`) - any type $\rightarrow$ can be nested ! -:::columns -::::column - can be a "number" type or a class for arrays ```Java int[] primes = new int[8]; -String[] cheeseNames = { - "camembert", - "comté", - "maroilles" -}; +String[] cheeseNames = {"camembert", "maroilles"}; int[][] matrix = new int[5][5]; ``` -:::: -::::column - must be a class for object containers ```Java @@ -534,15 +546,12 @@ ArrayList<Integer> grades; new LinkedList<String>() ``` -:::: -::: - ### Mutability #### On values -- `String`: `.charAt()` $\rightarrow$ read-only -- arrays: `[]` $\rightarrow$ read-write +- `String`: `.charAt()` function result $\rightarrow$ read-only +- arrays: `[]` variable $\rightarrow$ read-write - object containers: `.get`, `.set` $\rightarrow$ read-write #### On size @@ -621,59 +630,49 @@ default: … ### Syntax -```Java -String inFrench(int number) { - switch(number) { - case 0: return "zéro"; - case 1: return "un"; - case 2: return "deux"; - case 3: return "trois"; - default: return "baguette"; - } -} -``` - -### Semantics - -:::columns -::::column assuming -- `value`: an expression of type `t` -- `c1`, `c2`, …, `cn` are constants of type `t` -- `st1`, `st2`, …, `stn`(, `stn+1`) are statements +- `e`: an expression of type `t` +- `c1`, …, `cn` are **constants** of type `t` +- `st1`, …, `stn`(, `stn+1`) are statements + +\vspace{-0.2cm} ```Java -switch(value) { +switch(e) { case c1: s1; - case c2: s2; - … +``` +… +```Java case cn: sn; - (default: stn+1;) + default: stn+1; // optional } ``` -:::: -::::column +\vspace{-0.2cm} -is a statement which - -- evaluates `value` (side-effects ?) -- compares it to each of the constant -- evaluates **all statements** from `si` to the bottom if `ci` has the same value -- (or just `stn+1` if there was a `default` case and no constant matched) - -**Warning** +is a **statement** which -it only works on *constants* +- finds `i` such that `ci == e` (or `n+1`) +- runs **all statements** from `si` to `sn+1` -:::: -::: +### Example +```Java +String inFrench(int number) { + switch(number) { + case 0: return "zéro"; + case 1: return "un"; + case 2: return "deux"; + case 3: return "trois"; + default: return "baguette"; + } +} +``` ### `break` -remember the `jz` in assembly ? the `case` lines are just *labels*\ +the `case` lines are just *labels* $\rightarrow$ execution jumps and *continues* below from there @@ -699,9 +698,6 @@ $\rightarrow$ execution jumps and *continues* below from there assuming `s0`, `s1` and `s2` are statements -:::columns -::::column - ```Java try { s0 @@ -712,47 +708,40 @@ try { } ``` -:::: -::::column - -```Java -try { - s0 -} catch(Exception e) { - s1 -} -``` - -:::: -::: - -is a statement that +is a **statement** which - execute `s0` - if an exception occurs, execute `s1` (where variable `e` may appear) -- (for the case in the left column) executes `s2` whether `s0` has failed or not +- (executes `s2` whether `s0` has failed or not) ## More on for ### Remember for ? ```Java -for(initStatement; testExpression; interBlockStatement) { - block +for(<INITIALIZE>; <TEST>; <ITERATE>) { + <BLOCK> } ``` Actually… -- `initStatement` doesn't have to start at `0` -- `testExpression` can be any expression, a call to a (`boolean`) function -- `interBlockStatement` can be any statement (you can count up or down, by +- `<INITIALIZE>` doesn't have to start at `0` +- `<TEST>` can be any expression, a call to a (`boolean`) function +- `<ITERATE>` can be any statement (you can count up or down, by arithmetic, geometric progression or any function you want) ### A beautiful solution ```Java -for(int i = 221; i > 1; i = i % 2 == 0 ? i / 2 : 3*i+1) { +int nextCollatz(int i) { + return i % 2 == 0 ? i / 2 : 3*i+1; +} +``` +. . . + +```Java +for(int i = 221; i > 1; i = nextCollatz(i)) { System.out.println(i); } ``` @@ -773,7 +762,7 @@ do { } while(n < 2) ``` -Now `n` holds `5` +Now `n` is `5` ### `continue` @@ -816,7 +805,7 @@ class Main { #### Requirements -- entry point of the program (remember `IP` ?) +- entry point of the program ("where do we start ?") - no context yet, so can't instantiate `Main` class - $\implies$ `static`, (`public`) @@ -841,7 +830,7 @@ class Main { ### Compiling -the above saved in a file `Main.java` in current directory. +the above saved in a file `Main.java` in current folder. ``` $ ls @@ -862,13 +851,3 @@ two three four ``` - -:::columns -::::column - -:::: -::::column - -:::: -::: - diff --git a/Slides/Class3.md b/Slides/Class3.md index 8e40b506d40f582022e4b56595a56ed78ca0d072..de2047cb8bfc40817e4c058a3b0902fd051801e0 100644 --- a/Slides/Class3.md +++ b/Slides/Class3.md @@ -1,23 +1,18 @@ --- title: IST-4-JAV Java Programming -subtitle: Class 3 - Modeling +subtitle: Class 3 - Modeling the structure author: Alice BRENON `<alice.brenon@liris.cnrs.fr>` -date: 2021-09-28 +date: 2022-10-12 +institute: + \includegraphics[height=.9cm]{figures/LIRIS}\quad + \includegraphics[height=.9cm]{figures/INSA} +aspectratio: 169 header-includes: \usepackage{fdsymbol} \usepackage{textgreek} \usepackage{bclogo} - \usepackage{hyperref} - \usepackage{color} - \definecolor{yellow}{RGB}{255, 127, 0} - \definecolor{greyblue}{RGB}{58, 103, 183} - \hypersetup{ - colorlinks, - linkcolor = yellow, - urlcolor = greyblue - } - \usetheme{Frankfurt} - \usecolortheme{seahorse} + \usepackage{Beamer/beamerthemePerso} + \setcounter{tocdepth}{1} --- # Structuring objects @@ -115,13 +110,19 @@ inheritance is not rare: ### Example: Exceptions +:::columns +::::{.column width=60%}  +:::: +::::{.column width=40%} - `Throwable`: anything that can be `throw`n - `Error`: serious "physical" trouble - `Exception`: recoverable failure - `TimeoutException`: give up on blocking operation - `NullPointerException`: tried to dereference `null` +:::: +::: ### Syntax: `extends` @@ -199,7 +200,7 @@ $\rightarrow$ there was a (hidden) call to `DomesticCat();` - the automatically added call takes no argument - `DomesticCat` doesn't have a constructor with no argument ! -- we need to manually call the constructor +- we need to manually call the constructor "above" ```Java class PureBreedCat extends DomesticCat { @@ -237,24 +238,35 @@ $\rightarrow$ now we know where everything comes from ! - but sometimes we want to change their behaviour - `@Override` pragma: hint for `javac` +:::columns +::::{.column width=45%} ```Java class Cat { … void feed() { - System.out.println("hunts"); + System.out.println( + "hunts" + ); } } ``` +:::: +::::{.column width=45%} ```Java class DomesticCat { … @Override void feed() { - System.out.println("mews until a human feeds it"); + System.out.println( + "mews until a human" + + " feeds it" + ); } } ``` +:::: +::: ### Another use for super @@ -296,18 +308,24 @@ default `.toString`: *Class name* + `@` + *memory location* ```Java class DomesticCat { - public String toString() { + String toString() { return this.name + ", a cat"; } } +``` + +\vspace{-0.3cm} +```Java class PureBreedCat { - public String toString() { + String toString() { return this.name + ", a " + this.breed + " cat"; } } ``` +\vspace{-0.3cm} + ```jshell jshell> pangur pangur => Pangur, a cat @@ -348,83 +366,78 @@ class DomesticCat { - in the context where a human is passed, mews instead - a "conditional" without `if` or ternary operator. -# Structuring projects - -## Visibility +# Structuring code -### Why ? +## Access control -- hides away implementation details -- avoid mistakes -- classes as an "area" -- (remember "structure", not "data" ?) -- (access control) - -$\rightarrow$ abstraction - -### How ? +### Example: a cat's `name` -- inheritance -- packages -- modifiers applied to - - fields - - methods - - classes +can't ask its name to a cat ! -#### Keywords / visibility +. . . -\vspace{0.5cm} -\begin{tabular}{| l | c | c | c | c |} -\hline - keyword & class & package & subclass & outside world\\ -\hline -\hline - $\texttt{private}$ & Y & N & N & N\\ -\hline - (nothing) & Y & Y & N & N\\ -\hline - $\texttt{protected}$ & Y & Y & Y & N\\ -\hline - $\texttt{public}$ & Y & Y & Y & Y\\ -\hline -\end{tabular} +*but* -### Example: a cat's `name` +```Java +pangur.name; // returns a String ("Pangur") +pangur.name = "Marcel"; /* now Pangur has a different name ! */ +pangur.name; // "Marcel" +``` -can't ask its name to a cat +### The `private` keyword ```Java -public class DomesticCat { +class DomesticCat { private String name; // but still can interact with it ! - public void call(String name) { + void call(String name) { if(this.name.equals(name)) { System.out.println("mews and comes"); } else { - System.out.println("looks away and yawns"); + System.out.println( + "looks away and yawns" + ); } } } ``` -### Good practice +### Why ? -"Need to know" basis $\implies$ start `private`, and grant access as needed +- more realistic +- hides away implementation details +- avoid mistakes +- classes as an "area" +- (remember "structure", not "data" ?) -#### Model the reality +$\rightarrow$ abstraction -- who/what could get the information ? -- could it be changed from *outside* ? -- is it a convenience or something fundamental ? ### Another useful flag: `final` +:::columns +::::{.column width=45%} +```java +Math.PI +Math.E +``` +:::: +::::{.column width=10%} +$\rightarrow$ +:::: +::::{.column width=35%} +```java +static final double +``` +:::: +::: + - prevent from changing a variable -- just this variable (not what it may refer to !) +- the variable itself (not what it may refer to ! remember graphs) - again: numbers, objects… -#### Not only for variables +#### Not for variables only - **On methods**: cannot be overridden - **On class**: cannot be extended @@ -434,12 +447,12 @@ public class DomesticCat { - by default variables are read-write - read-only can be achieved by `final` - "access control": actually read-write, but can't be changed from *outside* -- notion of *view* +- notion of *view* (there doesn't have to be a corresponding field) ```Java -public class Cat { +class Cat { private int age; - public int getAge() { + int getAge() { return this.age; } } @@ -451,10 +464,16 @@ public class Cat { - separates feature / implementation ```Java -public class Cat { +class Cat { private int age; - public void setAge(int age) { - this.age = age; + void setAge(int age) { + if(age > this.age) { + this.age = age; + } + } + + void happyBirthday() { + this.age++; } } ``` @@ -465,11 +484,11 @@ public class Cat { - control the flow ```Java -public class MovingAnimal { +class MovingAnimal { private float restLevel; private Point at; static float range; - public void setAt(Point newAt) { + void setAt(Point newAt) { float distance = distance(this.at, newAt); this.at = newAt; this.restLevel *= Math.exp(-distance / range); @@ -481,11 +500,14 @@ public class MovingAnimal { ### Abstract classes and methods +*What's a **predator** ?* + +. . . + - the Idea without a Form - implements some behaviour - can't be instantiated, a "draft" - exists only to be inherited (*factorize* code) -- the "negative numbers" of classes ### Syntax: `abstract` @@ -494,7 +516,7 @@ public class MovingAnimal { - incompatible with `final` ! ```Java -abstract public class Predator { +abstract class Predator { abstract protected void catchPrey(); protected void feed() { this.catchPrey(); @@ -537,9 +559,9 @@ abstract public class Predator { ::::column ```Java -public interface Animal { - public int getAge(); - public void feed(); +interface Animal { + int getAge(); + void feed(); } ``` @@ -559,12 +581,12 @@ public interface Animal { ::::column ```Java -public class Cow implements Animal { +class Cow implements Animal { private int age; - public int getAge() { + int getAge() { return this.age; } - public void feed() { + void feed() { System.out.println("grazes"); } } @@ -580,7 +602,7 @@ public class Cow implements Animal { :::: ::: -### Advanced interfaces +### Bridges between interfaces and abstract classes #### Extending @@ -589,7 +611,7 @@ public class Cow implements Animal { #### Partial implementation -- a class may `implements` an interface but not all its methods +- a class may `implement` an interface but not all its methods - makes unimplemented `abstract` $\implies$ whole class `abstract` #### Default implementation @@ -667,14 +689,14 @@ $\leftarrow$ - hence, can be contravariant ```Java -public class Cat { - public Cat mate(Cat partner) { +class Cat { + Cat mate(Cat partner) { … } } -public class PureBreedCat extends DomesticCat { - public PureBreedCat mate(PureBreedCat partner) { +class PureBreedCat extends DomesticCat { + PureBreedCat mate(PureBreedCat partner) { … } } @@ -682,15 +704,17 @@ public class PureBreedCat extends DomesticCat { **$\rightarrow$ Not in general !** +# Structuring projects + ## Isolating parts ### Packages - applications start growing +- avoid name conflicts - structuring things also document them -- developed by different organisations - reuse some parts -- avoid name conflicts +- developed by different organisations $\rightarrow$ packages @@ -700,7 +724,7 @@ $\rightarrow$ packages ::::column ```Java -package package.the.of.name; +package name.of.the.package; ``` :::: ::::column @@ -711,7 +735,7 @@ statement must be added to each file ::: - arbitrary names (usually "company"'s domain name) -- left to right (opposite from internet domain names) +- hierarchically left to right (opposite from internet domain names) - all lowercase - use `_` to fix invalid names (reserved words, `-` and other special characters) @@ -737,9 +761,75 @@ import name.of.the.package.*; // all its classes - no "subpackages": prefix on names $\not \Rightarrow$ anything on package - `*` isn't a regex, and (see above) will catch only classes +## More about visibility + +### `public`, at last ! + +- control the boundaries at the package level +- default: nothing outside the package +- (`jshell`: same temporary package) + +\vspace{1cm} + +:::columns +::::{.column width=45%} +`public`: entirely visible +:::: +::::{.column width=45%} +`protected`: only in subclasses ("backstage" access) +:::: +::: + +### How ? + +- modifiers applied to + + fields + + methods + + classes + +#### Keywords / visibility + +\vspace{0.5cm} +\begin{tabular}{| l | c | c | c | c |} +\hline + keyword & class & package & subclass & outside world\\ +\hline +\hline + $\texttt{private}$ & Y & N & N & N\\ +\hline + (nothing) & Y & Y & N & N\\ +\hline + $\texttt{protected}$ & Y & Y & Y & N\\ +\hline + $\texttt{public}$ & Y & Y & Y & Y\\ +\hline +\end{tabular} + +### Good practice + +"Need to know" basis $\implies$ start `private`, and grant access as needed + +#### Model the reality + +- who/what could get the information ? +- could it be changed from *outside* ? +- is it a convenience or something fundamental ? + +### A subtle remark + +- `private` is very restrictive (the class to itself) +- $\rightarrow$ makes sense only *inside* a class + +. . . + +- `protected` differs from default only for inheritance +- $\rightarrow$ makes sense only *inside* a class + +## Example + ### Source code -#### fr/insa_lyon/ist_4_jav/library/SomeLibrary.java +*fr/insa_lyon/ist_4_jav/library/SomeLibrary.java* ```Java package fr.insa_lyon.ist_4_jav.library; @@ -749,14 +839,15 @@ public class SomeLibrary { } ``` +### Source code -#### fr/insa_lyon/ist_4_jav/tp3/TP3.java +*fr/insa_lyon/ist_4_jav/class3/Main.java* ```Java -package fr.insa_lyon.ist_4_jav.tp3; +package fr.insa_lyon.ist_4_jav.class3; import fr.insa_lyon.ist_4_jav.library.SomeLibrary; -public class TP3 { +public class Main { public static void main(String[] args) { System.out.println(SomeLibrary.greet); } @@ -770,7 +861,8 @@ public class TP3 { - (use autocomplete to let `java` guide you) ```shell -$ javac fr/insa_lyon/ist_4_jav/tp3/Main.java -$ java fr.insa_lyon.ist_4_jav.tp3.Main +$ javac fr/insa_lyon/ist_4_jav/class3/Main.java +$ java fr.insa_lyon.ist_4_jav.class3.Main Hi there ! ``` + diff --git a/Slides/Class4.md b/Slides/Class4.md index fe0c63bf46bd932c2712d4d6ad8f478663d922f6..d11d19066ff6f06e9793b5cc36c5fe4830d15448 100644 --- a/Slides/Class4.md +++ b/Slides/Class4.md @@ -1,245 +1,242 @@ --- title: IST-4-JAV Java Programming -subtitle: Class 4 - New heights +subtitle: Class 4 - Going graphic author: Alice BRENON `<alice.brenon@liris.cnrs.fr>` -date: 2021-10-19 +date: 2022-10-19 +institute: + \includegraphics[height=.9cm]{figures/LIRIS}\quad + \includegraphics[height=.9cm]{figures/INSA} +aspectratio: 169 header-includes: \usepackage{fdsymbol} \usepackage{textgreek} \usepackage{bclogo} - \usepackage{hyperref} - \usepackage{color} - \definecolor{yellow}{RGB}{255, 127, 0} - \definecolor{greyblue}{RGB}{58, 103, 183} - \hypersetup{ - colorlinks, - linkcolor = yellow, - urlcolor = greyblue - } - \usetheme{Frankfurt} - \usecolortheme{seahorse} + \usepackage{Beamer/beamerthemePerso} + \setcounter{tocdepth}{1} --- -# Advanced Objects -## Enumerations +# Complexity -### Need +## Simple containers -```Java -class PureBreedCat extends DomesticCat { - String breed; - … -} -``` +### Implementing interfaces -#### `String` ? +{height=80px} -1. for user: what are the possible values ? -2. possible errors (case, typos…) -3. need to validate input -4. ($\Rightarrow$ what to do with unexpected values ?) +One interface, several implementations. -$\Rightarrow$ type too "large" +### Two implementations -### A possible solution +:::columns +::::{.column width=90%} +#### List + +- a set of functionalities +- a contract to prove a class can act as a list + +. . . + +$\rightarrow$ an interface ! +:::: +::: + +\vspace{0.5cm} :::columns -::::{.column width=40%} +::::column -need a finite number of values that are +**ArrayList** -- unique -- easy to compare -- associated to names +\vspace{0.5cm} + + -$\Rightarrow$ constants of any integral type will do ! +- an array larger than the number of elements +- an index to remember where it stops :::: -::::{.column width=60%} +::::column -```Java -final static byte SIAMESE = 0; -final static byte CHARTREUX = 1; -final static byte SAVANNAH = 2; -… -``` +**LinkedList** + +\vspace{0.5cm} + + + +- a "head": the element in the current cell +- a "queue": the pointer to the rest of the list :::: ::: +### Getting element at index `i` + +:::columns +::::column + +**ArrayList** + \vspace{0.5cm} -- 1 and 2 are fixed ! -- 3 and 4 remain : ( +- check the bounds: $O(1)$ +- return cell `i`: $O(1)$ -### The `enum` types +$\Rightarrow O(1)$ -- fixed set of **symbolic** constants -- introduced by `enum` instead of `class` -- names separated by `,` (ended by `;`) -- it's a class like any other ! (fields, methods) +:::: +::::column -```Java -enum CatBreed { - SIAMESE, CHARTREUX, SAVANNAH -} +**LinkedList** -CatBreed breed = CatBreed.SIAMESE; -breed == CatBreed.SAVANNAH; // false -``` +\vspace{0.5cm} -### Advanced example +does `i == 0 ` ? -- optional constructor can't be `public` -- all values are constructed statically -- properties can be initialized +- if yes, get the head: +- otherwise, get the `i-1`\textsuperscript{th} element of the queue -```Java -enum BreedType { - NATURAL, MUTATION, HYBRID -} -enum CatBreed { - SIAMESE (BreedType.MUTATION), - CHARTREUX (BreedType.NATURAL), - SAVANNAH (BreedType.HYBRID); - private BreedType type; - CatBreed (BreedType type) { this.type = type; } - BreedType getBreedType() { return this.type; } -} -``` +$\Rightarrow O(n)$ -## Type variables +:::: +::: -### Remember containers ? +### Prepending -```Java -List<Integer> -List<Double> -List<String> -List<List<String>> -… -``` +:::columns +::::column -- a "family" of classes (infinite) -- work on any type +**ArrayList** -### Methods signatures +\vspace{0.5cm} -```Java -List<Integer> ints = new ArrayList<>(); -List<String> strings = new ArrayList<>(); -for(int i = 0; i < 10; i++) { - ints.add(i); - strings.add(Integer.toString(i)); -} -``` + -$\rightarrow$ what is the signature of `.add` ? +- create a new array large enough: $O(n)$ +- write the new element: $O(1)$ +- copy all the other elements after: $O(n)$ -### An "input" +$\Rightarrow O(n)$ -```Java -void add(Integer n) // ?? -void add(String s) // ?? -``` +:::: +::::column -- type of their methods depend on the type context -- $\rightarrow$ need to be named in the class declaration -- "input" of a class, like arguments are the inputs of a function -- **type variables** +**LinkedList** -### Generics +\vspace{0.5cm} -- an identifier (any variable name) -- inside the "diamond" `<>` -- usually a single letter: - + `N` $\rightarrow$ "number" type - + `K` $\rightarrow$ "key" in an association - + `V` $\rightarrow$ "value" in an association - + `T` $\rightarrow$ any type -- multiple parameters are comma separated `<K, V>` + -### May appear +- create a new cell with the new element pointing to the existing list: $O(1)$ -#### in classes +$\Rightarrow O(1)$ -```Java -class Box<T> { - … -} -``` +:::: +::: -#### in methods +### Performance comparison -as the last modifier, just before the return type +**So which one is best ?** -```Java -public <T> List<T> preview(List<T> full, int size); -``` +- if frequent random access is needed: `ArrayList` +- if frequent modification is needed: `LinkedList` -### Wildcards +$\Rightarrow$ No "one-size-fits-all", implementation should match the use -- the "unknown type" -- no name $\Rightarrow$ strictly less powerful (!) -- syntax: `?` +## Associating values to keys -#### Remark +### A common need -- `List<Integer>` isn't a subtype of `List<Object>` -- but it's a subtype of `List<?>` ! -- $\Rightarrow$ allows to get supertypes ! +- "white pages", phone books… +- Domain Name System +- looking up users in a table by their ID +- finding the selected action in a menu -### Bounds +```Java +interface Map<K, V> { + … + V get(Object k); +} +``` + +### Association list :::columns ::::column -#### `extends` - -- any type that derives from the given type -- useful on covariant operations -- works for generic types - ```Java -<? extends Integer> +class Pair<K, V> { + … +} ``` :::: ::::column -#### `super` - -- any type which the given type derives from -- useful on contravariant operations -- (only for wildcards ! not generics) - ```Java -<? super Integer> +class ArrayList<T> { + … +} ``` :::: ::: -### Useful with interfaces - -- conditions on input types -- like variables: reusing the name in the same formula makes the types equal -- hypothesis used in the implementation -- can be combined with `&`: \ - `<T extends Comparable & Number>` +\begin{center} +$\downarrow$ +\end{center} -#### Example +```Java +class PhoneBook<K, V> { + private ArrayList<Pair<K, V>> records; + PhoneBook (int initialSize) { + this.records = new ArrayList<>(initialSize); + } +} +``` -sorting requires ordered elements: +### Retrieving a number from a key ```Java -<T extends Comparable<T>> List<T> sort(List<T> elems); +… +V get(Object k) { + for(Pair<K, V> record: this.records) { + if(record.getKey().equals(k)) { + return record.getValue(); + } + } + return null; +} ``` -# A little bit of functional programming why not ? +- must walk the phonebook until found +- on average, `this.records.size() / 2` +- $\Rightarrow O(n)$ + +### HashMaps -## Functional interfaces +A bit of both ! + +{width=260px} + +### Properties + +#### A clever implementation + +- uses `.hashCode()` on the key: $O(1)$ +- each list as long as the number of collisions (if `.hashCode` is good, then + few): $O(c)$ +- (see birthday problem) + +#### Consequences + +- fast access +- fast insertion +- resizing costs when it gets too full (initial capacity / load factor) + +# Asynchronous programs + +## Principles ### A key distinction @@ -272,12 +269,37 @@ sorting requires ordered elements: :::: ::: -### But what if we want to… +### Program flow + +- **imperative**: "recipe", sequence of instructions +- **object**: "sections" in the program not executed linearly + +$\rightarrow$ what about reactions to events ? + +- could the program be in "several locations" at once ? +- how could each step anticipate everything that could happen ? (and always the + same anyway) +- check some central state once in a while ? + +### Use cases + +- long (> 100 ms) calls: network +- user interaction (games, anyone ?) +- graphical user interfaces (don't want everything to freeze) + +How to represent reactions ? + +. . . + +Reactions are functions so… could we pass functions after all ? + +## Functions as values + +### So what if we could… - store a function into a variable ? - associate it to a key ? (menus…) - pass it to another function ? -- use concurrency (threads) ? ```Java boolean isEven(int n) { @@ -292,7 +314,7 @@ someList.filter(isEven); // Error: cannot find symbol - passing an object is a way to pass its methods - only need a convention to find the method -$\rightarrow$ it's called an interface ! +$\rightarrow$ this is called an interface ! ```Java interface MyFunctionType { @@ -307,91 +329,81 @@ interface MyFunctionType { - conventional name to find it - (can have other methods but only 1 abstract) -$\rightarrow$ it's called a functional interface ! +$\rightarrow$ it's called a functional interface (pragma `@FunctionalInterface`) +! **Example** ```Java @FunctionalInterface -public interface Predicate<T> { - public boolean test(T t); +public interface IntPredicate { + public boolean test(int t); } ``` -## Lambda expressions +### Ad-hoc inheritance -### Concept +- `abstract` as "negative" methods +- $\rightarrow$ "settle the bill" +- actually `interface`s and `abstract` classes can be instantiated ! -:::columns -::::column - -#### From the \textlambda-calculus - -- Alonzo Church (1930s) -- base of many languages: Lisp, Ocaml, Haskell… -- the set of terms $T$ contain: - + atoms: constants $C$, variables $V$ - + abstractions: $\{\lambda x.t \ \forall v \in V, t \in T\}$ - + applications: $\{(t\ u) \ \forall t, u \in T\}$ - -:::: -::::column - -- like functions (arguments mapped to a value) -- one-liner -- anonymous - -$\Rightarrow$ function literals +```Java +@FunctionalInterface +interface IntMapping { + public int apply(int n); +} +``` -:::: -::: +. . . +```Java +IntMapping plus2 = new IntMapping() { + public int apply(int n) { + return n + 2; + } +} +``` ### Syntax assuming - `(a, b, …)` is a tuple of $n$ variables (parentheses optional when 1 only) -- `e` is an expression -- `b` is a block ending with a `return` statement +- `<VALUE>` is an expression +- `<BLOCK>` is a block ending with a `return` statement ```Java -(a, b, …) -> e -(a, b, …) -> { b } +(a, b, …) -> <EXPRESSION> +(a, b, …) -> { <BLOCK> } ``` are values for a given functional interface -**Example** +**Examples** ```Java (n, m) -> n+m x -> {System.out.println(x); return -x;} ``` -### Literal values +### A little bit shorter -**What about their types ?** - -- no "arrow" types in Java so can't really be written "`int -> String`" -- the `@FunctionalInterface` are perfect for the job ! -- (mind the conceptual gap) +The previous `plus2` becomes ```Java -@FunctionalInterface -public interface Endofunction<T> { - T apply(T t); -} -Endofunction<Integer> succ = n -> n+1; +IntMapping plus2 = n -> n + 2 ``` +It's called an inline function, sometimes also a "\textlambda" from the +\textlambda-calculus, (Alonzo Church, 1930s). + ### Method reference - what about existing functions ? -- (can be wrapped into a \textlambda, but boring: +- can be wrapped into a \textlambda, but boring: ```Java n -> someObject.someMethod(n) ``` -- can't handle regular functions except to apply them +- can't invoke regular functions except to apply them - but you can *refer* to a method with `::` ### Example @@ -407,230 +419,225 @@ class PartialSum { } } PartialSum two = new PartialSum(2); -Endofunction<Integer> add2 = two::plus; +IntMapping add2 = two::plus; ``` -### Use cases +# Graphical User Interfaces -#### "Canned computations" +## Libraries -- multi-threading (computations in parallel): `Thread` -- asynchronous computations: `Future<T>` -- (all implement `Runnable`) +### AWT -#### Higher-order operations +**Basic tooling** -- no variables, lighter to read -- "add seven to all the elements in this array" +- older +- events (key presses) +- notion of `Component` +- `Graphics` surface to draw +- definition of `Layout` ```Java -int[] newArray = new int[initialArray.length]; -for(int i = 0; i < newArray.length; i++) { - newArray[i] = initialArray[i] + 7; -} +import java.awt.*; +import java.awt.event.*; +… ``` -- map, reduce, iter… - -# Complexity - -## Simple containers - -### Implementing interfaces - -{height=80px} - -One interface, several implementations. - -### Two implementations - -#### List - -- a set of functionalities -- a contract to prove a class can act as a list - -:::columns -::::column +### Swing -#### ArrayList +**More advanced** -\vspace{0.5cm} +- more recent +- heavily depends on AWT anyway +- advanced widgets: dialogs, etc +- easier styling - +```Java +import javax.swing.*; +import javax.swing.colorchooser.*; +import javax.swing.plaf.*; // pluggable look-and-feel +``` -- an array larger than the number of elements -- an index to remember where it stops +### General idea -:::: -::::column +**a tree of components** -#### LinkedList +- you plug components into containers (also components) +- recursively up to the root window +- components can appear only once -\vspace{0.5cm} +{height=80px} - +### The 2D API -- a "head": the element in the current cell -- a "queue": the pointer to the rest of the list +- within `AWT` +- useful for: + + geometric primitives + + text + + images -:::: -::: +#### A different approach -### Getting element at index `i` +- you implement `Component` +- a `Graphics` object is passed around in the `paint` method +- you draw to it -:::columns -::::column +### Documentation -#### ArrayList +#### Packages -\vspace{0.5cm} +[https://docs.oracle.com/javase/7/docs/api/overview-summary.html](https://docs.oracle.com/javase/7/docs/api/overview-summary.html) -- check the bounds: $O(1)$ -- return cell `i`: $O(1)$ +#### Tutorials to AWT's 2D API -$\Rightarrow O(1)$ +[https://docs.oracle.com/javase/tutorial/2d/overview/index.html](https://docs.oracle.com/javase/tutorial/2d/overview/index.html) -:::: -::::column +#### Tutorials to Swing components -#### LinkedList +[https://docs.oracle.com/javase/tutorial/uiswing/components/index.html](https://docs.oracle.com/javase/tutorial/uiswing/components/index.html) -\vspace{0.5cm} +#### Swing examples -does `i == 0 ` ? +[https://docs.oracle.com/javase/tutorial/uiswing/examples/components/index.html](https://docs.oracle.com/javase/tutorial/uiswing/examples/components/index.html) -- if yes, get the head: -- otherwise, get the `i-1`\textsuperscript{th} element of the queue +## Simple Swing example -$\Rightarrow O(n)$ +### Minimal window -:::: -::: +```Java +import javax.swing.*; +public class EmptyWindow { + private static void createAndShowGUI() { + JFrame frame = new JFrame("Some window title"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.pack(); + frame.setVisible(true); + } + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> createAndShowGUI()); + } +} +``` -### Prepending +### Translation :::columns -::::column - -#### ArrayList - -\vspace{0.5cm} - - - -- create a new array large enough: $O(n)$ -- write the new element: $O(1)$ -- copy all the other elements after: $O(n)$ - -$\Rightarrow O(n)$ - +::::{.column width=45%} +```Java +import javax.swing.*; +``` +\vspace{1cm} +```Java +public class EmptyWindow { +``` +… +```Java +} +``` :::: -::::column +::::{.column width=45%} +access to -#### LinkedList +- JFrame +- SwingUtilities -\vspace{0.5cm} - - - -- create a new cell with the new element pointing to the existing list: $O(1)$ - -$\Rightarrow O(1)$ +\vspace{.5cm} +a class for our program :::: ::: -### Performance comparison - -**So which one is best ?** +### Translation -- if frequent random access is needed: `ArrayList` -- if frequent modification is needed: `LinkedList` - -$\Rightarrow$ No "one-size-fits-all", implementation should match the use - -## Associating values to keys +```Java +private static void createAndShowGUI() { + JFrame frame = new JFrame("Some window title"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.pack(); + frame.setVisible(true); +} +``` +a function to draw our window -### A common need +- A window is a `JFrame`, set its title +- make the program end when the window closes +- find a size that works for components +- show the window (yes !) -- "white pages", phone books… -- Domain Name System -- looking up users in a table by their ID -- finding the selected action in a menu +### Translation ```Java -interface Map<K, V> { - … - V get(Object k); +public static void main(String[] args) { + SwingUtilities.invokeLater(() -> createAndShowGUI()); } ``` -### Association list +- still a program like any other, needs the usual `main` +- schedule a rendering (see the lambda ?) +- where did the control flow go ? -:::columns -::::column +### With a panel ```Java -class Pair<K, V> { - … -} +import java.awt.GridLayout; + … + private static void createAndShowGUI() { + … + JPanel jpanel = new JPanel(new GridLayout(2, 2)); + frame.add(jpanel); + … + } + ``` -:::: -::::column +### With a couple widgets ```Java -class ArrayList<T> { - … -} + … + private static void createAndShowGUI() { + … + JLabel label = new JLabel("Hey there !"); + JTextField input = new JTextField(); + JButton submit = new JButton("click me"); + jpanel.add(label); + jpanel.add(input); + jpanel.add(submit); + … + } ``` -:::: -::: - -\begin{center} -$\downarrow$ -\end{center} +### Add reactions to events ```Java -class PhoneBook<K, V> { - private ArrayList<Pair<K, V>> records; - PhoneBook (int initialSize) { - this.records = new ArrayList<>(initialSize); - } -} +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + … + private static void createAndShowGUI() { + … + submit.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + System.out.println("Received " + e); + } + }); + … + } ``` -### Retrieving a number from a key +### Display image ```Java -… -V get(Object k) { - for(Pair<K, V> record: this.records) { - if(record.getKey().equals(k)) { - return record.getValue(); - } - } - return null; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import javax.imageio.ImageIO; +class ImageViewer extends Component { + private BufferedImage img; + ImageViewer(String path) { + try { + img = ImageIO.read(new File(path)); + } catch (IOException e) {} + } + public void paint(Graphics g) { + g.drawImage(this.img, 0, 0, null); + } } ``` - -- must walk the phonebook until found -- on average, `this.records.size() / 2` -- $\Rightarrow O(n)$ - -### HashMaps - -#### A clever implementation - -- uses `.hashCode()` on the key: $O(1)$ -- keeps a separate association list for each hash value -- each list as long as the number of collisions (if `.hashCode` is good, then - few): $O(c)$ -- (see birthday problem) - -#### Consequences - -- fast access -- fast insertion -- resizing costs when it gets too full (initial capacity / load factor) diff --git a/Slides/Class5.md b/Slides/Class5.md index 91ed4563f20f37ea196e1642f93bd35e2a89c2ec..69661bdbc0726276e3fb2f516892d7a05f8a9c05 100644 --- a/Slides/Class5.md +++ b/Slides/Class5.md @@ -1,25 +1,457 @@ --- title: IST-4-JAV Java Programming -subtitle: Class 5 - The devil in the details +subtitle: Class 5 - New heights author: Alice BRENON `<alice.brenon@liris.cnrs.fr>` -date: 2021-10-20 +date: 2022-10-19 +institute: + \includegraphics[height=.9cm]{figures/LIRIS}\quad + \includegraphics[height=.9cm]{figures/INSA} +aspectratio: 169 header-includes: \usepackage{fdsymbol} \usepackage{textgreek} \usepackage{bclogo} - \usepackage{hyperref} - \usepackage{color} - \definecolor{yellow}{RGB}{255, 127, 0} - \definecolor{greyblue}{RGB}{58, 103, 183} - \hypersetup{ - colorlinks, - linkcolor = yellow, - urlcolor = greyblue - } - \usetheme{Frankfurt} - \usecolortheme{seahorse} + \usepackage{Beamer/beamerthemePerso} + \setcounter{tocdepth}{1} --- +# Types + +## Enumerations + +### Need + +```Java +class PureBreedCat extends DomesticCat { + String breed; + … +} +``` + +#### `String` ? + +1. for user: what are the possible values ? +2. possible errors (case, typos…) +3. need to validate input +4. ($\Rightarrow$ what to do with unexpected values ?) + +$\Rightarrow$ type too "large" + +### A possible solution + +:::columns +::::{.column width=40%} + +need a finite number of values that are + +- unique +- easy to compare +- associated to names + +$\Rightarrow$ constants of any integral type will do ! + +:::: +::::{.column width=60%} + +. . . + +```Java +final static byte SIAMESE = 0; +final static byte CHARTREUX = 1; +final static byte SAVANNAH = 2; +… +``` + +:::: +::: + +\vspace{0.5cm} + +- 1 and 2 are fixed ! +- 3 and 4 remain : ( + +### The `enum` types + +- fixed set of **symbolic** constants +- introduced by `enum` instead of `class` +- names separated by `,` (ended by `;`) +- it's a class like any other ! (fields, methods) + +```Java +enum CatBreed { + SIAMESE, CHARTREUX, SAVANNAH +} + +CatBreed breed = CatBreed.SIAMESE; +breed == CatBreed.SAVANNAH; // false +``` + +### Advanced example + +- all values are constructed statically +- properties can be initialized +- optional constructor can't be `public` + +```Java +enum BreedType { + NATURAL, MUTATION, HYBRID +} +enum CatBreed { + SIAMESE (BreedType.MUTATION), + CHARTREUX (BreedType.NATURAL), + SAVANNAH (BreedType.HYBRID); + private BreedType type; + CatBreed (BreedType type) { this.type = type; } + BreedType getBreedType() { return this.type; } +} +``` + +## Type variables + +### Remember containers ? + +```Java +List<Integer> +List<Double> +List<String> +List<List<String>> +… +``` + +- a "family" of classes (infinite) +- work on any type + +### Methods signatures + +```Java +List<Integer> ints = new ArrayList<>(); +List<String> strings = new ArrayList<>(); +for(int i = 0; i < 10; i++) { + ints.add(i); + strings.add(Integer.toString(i)); +} +``` + +$\rightarrow$ what is the signature of `.add` ? + +### An "input" + +```Java +void add(Integer n) // ?? +void add(String s) // ?? +``` + +- type of their methods depend on the type context +- $\rightarrow$ need to be named in the class declaration +- "input" of a class, like arguments are the inputs of a function +- **type variables** + +### Generics + +- an identifier (any variable name) +- inside the "diamond" `<>` +- usually a single letter: + + `N` $\rightarrow$ "number" type + + `K` $\rightarrow$ "key" in an association + + `V` $\rightarrow$ "value" in an association + + `T` $\rightarrow$ any type +- multiple parameters are comma separated `<K, V>` + +### May appear + +**in classes** + +```Java +class Box<T> { + … +} +``` + +**in methods** + +as the last modifier, just before the return type + +```Java +public <T> List<T> preview(List<T> full, int size); +``` + +`<T>` is not the return type, it's like a flag. + +### Co/contravariance again + +is `List<Integer>` a "subtype" of `List<Object>` ? + +. . . + += "if I get a `List<Integer>`, do I have a `List<Object>` ? + +```Java +List<Integer> ints = new ArrayList<>(); +ints.add(4); +``` + +. . . + +:::columns +::::{.column width=35%} +…yes ? + +- `Object` +- $\rightarrow$ `Number` +- $\hspace{1em}\rightarrow$ `Integer` + +```Java +Object o = ints.get(0); +``` +:::: +::::{.column width=60%} +. . . + +but +```Java +ints.set(0, o); +``` + +``` +| Error: +| incompatible types: +| java.lang.Object cannot be converted +| to java.lang.Integer +| ints.set(0, o) +``` +:::: +::: + +### Wildcards + +…but it's a subtype of `List<?>` ! + +- syntax: `?` +- the "unknown type" +- $\Rightarrow$ allows to get sub/supertypes ! + +#### Remark + +no name $\Rightarrow$ strictly less powerful (!) + +### Refine a bit + +```Java +Object first(List<Object> l) { + return l.size() > 0 ? l.get(0) : null; +} +``` + +\vspace{.5cm} + +$\rightarrow$ cannot use on `ints` + +. . . + +\vspace{.5cm} + +```Java +Object first(List<? extends Object> l) { + return l.size() > 0 ? l.get(0) : null; +} +``` + +### Conversely + +```Java +List<Object> stuff = new ArrayList<>(); +void addInt(List<Integer> l) { + l.add(4); +} +stuff.add(4); // works +addInt(stuff); // does not ! +``` + +\vspace{.3cm} + +$\rightarrow$ cannot use on `stuff` + +. . . + +\vspace{.3cm} + +```Java +void addInt(List<? super Integer> l) { + l.add(4); +} +addInt(ints); // still works +addInt(stuff); // works too ! +``` + +### Bounds + +:::columns +::::column + +**`extends`** + +- any type that derives from or implements the given type +- useful on covariant operations +- works for generic types and wildcards + +```Java +<? extends Integer> +<T extends Integer> +``` + +:::: +::::column + +**`super`** + +- any type which the given type derives from +- useful on contravariant operations +- only for wildcards ! not generics + +```Java +<? super Integer> +``` +:::: +::: + +can be combined with `&`: `<T extends Comparable & Number>` + +### Use case + +```Java +static <T,U extends Comparable<? super U>> Comparator<T> + comparing(Function<? super T,? extends U> keyExtractor) +``` + +- `<T, U …>` : two type parameters (`T` and `U`) +- `U` must be comparable with any type inheriting it +- `Comparator<T>`: this returns a comparator (on objects of type `T`) +- `keyExtractor` a function + + `<? super T>` from something that inherits `T` + + `<? extends U>` to something that inherits `U` + +"If you can map `T` to a type `U` which you know how to compare, you can compare +`T`" + +## Error types + +### Warning fellow developers + +```Java +int divideByZero(int i) { + return i / 0; +} +``` + +``` +jshell> divideByZero(4) +| Exception java.lang.ArithmeticException: / by zero +| at divideByZero (#14:2) +| at (#15:1) +``` + +*runtime* errors vs. *static* errors\ +$\rightarrow$ could we make it a bit safer ? + +### Syntax `throws` + +```Java +int divideByZero(int i) throws ArithmeticException { + return i / 0; +} +``` + +:::columns +::::{.column width=48%} +- `throw` in the code (statement) +- `throws` in the type +:::: +::::{.column width=3%} +\vspace{.5cm} +$\uparrow$ +:::: +::::{.column width=40%} +. . . + +\hrule + +```Java +try { +``` +… +```Java +} catch(SomeException e) { +``` +… +```Java +} catch(OtherException e) { +``` +… +```Java +} +``` +:::: +::: + +### A real-life example + +```Java +class FileInputStream extends InputStream { +``` +… +```Java + FileInputStream(String filePath) throws FileNotFoundException +``` +… +```Java +} +``` + +```Java +abstract class InputStream { +``` +… +```Java + int read() +``` +… +```Java +} +``` + +### Implementation + +```Java +String readFile(String filePath) throws FileNotFoundException, + IOException { + InputStream input = new FileInputStream(filePath); + StringBuffer output = new StringBuffer(); + int read = input.read(); + while(read >= 0) { + output.append((char) read); + read = input.read(); + } + return output.toString(); +} +``` + +### Remark on the classes hierarchy + +- `Throwable` +- $\rightarrow$ `Exception` +- $\hspace{1em}\rightarrow$ `IOException` +- $\hspace{2em}\rightarrow$ `FileNotFoundException` + +. . . + +```Java +String readFile(String filePath) throws IOException { +``` +… +```Java +} +``` + # Architecture ## Patterns @@ -38,7 +470,7 @@ $\rightarrow$ programming as a *craft* vs. programming as *science* :::columns -::::column +::::{.column width=65%} - "Design Patterns: Elements of Reusable Object-Oriented Software" - four authors ("gang of four"), (1994) @@ -46,7 +478,7 @@ $\rightarrow$ programming as a *craft* vs. programming as *science* - presents 23 patterns :::: -::::column +::::{.column width=25%} \vspace{0.3cm} @@ -69,13 +501,13 @@ Very praised in 1994 $\rightarrow$ Part of Java's history -### Singleton: about +### Singleton - ensure one instance only - typical use: logger - like a global variable + lazy loading -### Singleton: example +### Singleton example ```Java class Logger { @@ -93,13 +525,13 @@ class Logger { ``` -### Factory: about +### Factory - hide the constructor ("alternative constructors") - level some internal complexity - decouple the consumer class and the choice of a particular implementation -### Factory: example +### Factory example: private constructors ```Java class Sound { @@ -111,6 +543,12 @@ class Sound { private Sound(Ogg oggData) { this.oggData = oggData; } +``` +… + +### Factory example: …with a public method + +```Java public fromFile(String path) { if(… == ".mp3") { return new Sound(new MP3(path)); @@ -118,9 +556,10 @@ class Sound { return new Sound(new Ogg(path)); } } +} ``` -### Decorator: about +### Decorator - add behaviour to a particular instance, not the whole class - dynamic modification of functionality @@ -129,7 +568,7 @@ class Sound { - (inheritance *à la* Javascript) - **circling around the same interface** -### Decorator: example 1/2 +### Decorator example: an interface and a base class ```Java interface Cat { @@ -143,7 +582,7 @@ class AnyCat implements Cat { } ``` -### Decorator: example 2/2 +### Decorator example: the class for decorators ```Java abstract class CatDecorator implements Cat { @@ -155,7 +594,11 @@ abstract class CatDecorator implements Cat { return this.decoratedCat.getDescription(); } } +``` + +### Decorator example: and one implementation +```Java class WithHat extends CatDecorator { public WithHat(Cat c) { super(c); } public String getDescription() { @@ -199,10 +642,8 @@ class Knob { } public void handle(String command) { switch(command) { - case "+": - this.volumeState.changeVolume(0.05f); break; - case "-": - this.volumeState.changeVolume(-0.05f); break; + case "+": this.volumeState.changeVolume(0.05f); break; + case "-": this.volumeState.changeVolume(-0.05f); break; case "m": this.volumeState.toggleMute(); break; default: System.err.println("Unknown: " + command); } @@ -245,209 +686,182 @@ class VolumeBar { } ``` -## Inline classes +# Real-world projects -### Implementing interfaces +## Javadoc -- can be done on the fly ! -- "anonymous classes", like lambdas but heavier +### Purpose -```Java -package javax.swing; -class SwingUtilities { - … - public static void invokeLater(Runnable doRun); -} -``` +:::columns +::::{.column width=40%} -commonly found in Swing examples: +\vspace{2cm} -```Java -javax.swing.SwingUtilities.invokeLater(new Runnable() { - public void run() { - createAndShowGUI(); - } -}); -``` +- normalize documentation +- make it easy to browse (HTML) +- part of the development process -### Ad-hoc inheritance +:::: +::::{.column width=55%} +{height=230px} +:::: +::: -- `abstract` as "negative" methods -- $\rightarrow$ "settle the bill" -- even `abstract` classes can be instantiated ! +### Usage +:::columns +::::{.column width=45%} ```Java -enum Color { - RED, GREEN, YELLOW, BLACK, BLUE -} -abstract class Beverage { - abstract public Color getColor(); -} -Beverage someUnknownStuff = new Beverage() { - public Color getColor() { return Color.GREEN; } -} +/** + * Here a general description + * of the method + * @param name description + * @return description + */ ``` +:::: +::::{.column width=45%} +Tags + +- `@param` +- `@return` +- `@author` +- `@deprecated` +- `@throws` / `@exception` +:::: +::: -# Graphical User Interfaces - -## Libraries - -### AWT - -**Basic tooling** - -- older -- events (key presses) -- notion of `Component` -- `Graphics` surface to draw -- definition of `Layout` - -```Java -import java.awt.*; -import java.awt.event.*; -… +```sh +javadoc [PACKAGE|SOURCE-FILE] ``` -### Swing - -**More advanced** +(don't forget about visibility !) -- more recent -- heavily depends on AWT anyway -- advanced widgets: dialogs, etc -- easier styling +### Example ```Java -import javax.swing.*; -import javax.swing.colorchooser.*; -import javax.swing.plaf.*; // pluggable look-and-feel +class StringUtil { + /** + * Replicate a String several times + * @param input the initial String + * @param n the number of repetitions + * @return the initial String concatenated the n times + */ + public static String replicate(String input, int n) { + if(times == 0) { + return ""; + } else { + return input + replicate(input, times - 1); + } + } +} ``` -### General idea +## Classpath -**a tree of components** +### In java -- you plug components into containers (also components) -- recursively up to the root window -- components can appear only once +- projects grow +- several dependencies (libraries) -{height=80px} +**Where to find the code ?** -### The 2D API +. . . -- within `AWT` -- useful for: - + geometric primitives - + text - + images +current directory (`.`) but not very flexible (compilation) -#### Another approach +. . . -- you implement `Component` -- a `Graphics` object is passed around in the `paint` method -- you draw to it +#### Cross-tool concern -### Documentation +- `jshell` +- `javac` +- `java` +- `javadoc` +- `jar` -#### Packages +### From the shell -[https://docs.oracle.com/javase/7/docs/api/overview-summary.html](https://docs.oracle.com/javase/7/docs/api/overview-summary.html) +- list of "code bases": folders or `jar` +- `:`-separated ($\equiv$ `$PATH`) +- equivalent option from all the ecosystem + + `--class-path`, `-classpath`, `-cp` + + same syntax -#### Tutorials to AWT's 2D API +```sh +echo $CLASSPATH +"path/to/some/library:path/to/another:current/project" +``` -[https://docs.oracle.com/javase/tutorial/2d/overview/index.html](https://docs.oracle.com/javase/tutorial/2d/overview/index.html) +## JAR -#### Tutorials to Swing components +### Archives -[https://docs.oracle.com/javase/tutorial/uiswing/components/index.html](https://docs.oracle.com/javase/tutorial/uiswing/components/index.html) +:::columns +::::{.column width=45%} +- contain the code +- easily distributed +- (lighter) +- independent from packages +:::: +::::{.column width=45%} +#### Syntax ($\equiv$ `tar`) -#### Swing examples +- `-t`: list +- `-c`: create +- `-x`: extract +:::: +::: -[https://docs.oracle.com/javase/tutorial/uiswing/examples/components/index.html](https://docs.oracle.com/javase/tutorial/uiswing/examples/components/index.html) +```sh +jar cvf MyApp.jar *.class +jar xvf MyApp.jar +jar tvf MyApp.jar | less +``` -## Simple example +### Using libraries -### Minimal window +*Main.java* ```Java -import javax.swing.*; -public class EmptyWindow { - private static void createAndShowGUI() { - JFrame frame = new JFrame("Some window title"); - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - frame.pack(); - frame.setVisible(true); - } - public static void main(String[] args) { - SwingUtilities.invokeLater(() -> createAndShowGUI()); - } +public class Main { + public static void main(String[] args) { + System.out.println(StringUtil.replicate(args[0], 3)); + } } ``` -### With a panel +```sh +javac Main.java +``` -```Java -import java.awt.GridLayout; - … - private static void createAndShowGUI() { - … - JPanel jpanel = new JPanel(new GridLayout(2, 2)); - frame.getContentPane().add(jpanel); - … - } +. . . ``` +Main.java:3: error: cannot find symbol + System.out.println(StringUtil.replicate(args[0], 3)); + ^ + symbol: variable StringUtil + location: class Main +``` -### With a couple widgets +### Using it -```Java - … - private static void createAndShowGUI() { - … - JLabel label = new JLabel("Hey there !"); - JTextField input = new JTextField(); - JButton submit = new JButton("click me"); - jpanel.add(label); - jpanel.add(input); - jpanel.add(submit); - … - } +assuming `../library.jar` contains `StringUtil` + +```sh +javac --class-path ../library.jar Main.java +java --class-path "../library.jar:." Main test ``` -### Add reactions to events +Let's create a JAR -```Java -import java.awt.event.ActionListener; -import java.awt.event.ActionEvent; - … - private static void createAndShowGUI() { - … - submit.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - System.out.println("Received " + e); - } - }); - … - } +```sh +jar --create -f ../main.jar Main.class ``` -### Display image +we can run the app -```Java -import java.awt.*; -import java.awt.image.BufferedImage; -import java.io.*; -import javax.imageio.ImageIO; - -class ImageViewer extends Component { - private BufferedImage img; - ImageViewer(String path) { - try { - img = ImageIO.read(new File(path)); - } catch (IOException e) {} - } - public void paint(Graphics g) { - g.drawImage(this.img, 0, 0, null); - } -} +```sh +java -cp "../library.jar:../main.jar" Main test ``` diff --git a/Slides/pictures/F8RKB6FIYV9FXJK.jpg b/Slides/pictures/F8RKB6FIYV9FXJK.jpg deleted file mode 100644 index 18010d51882d51f9c963bbbfcfda9dadb9d15189..0000000000000000000000000000000000000000 Binary files a/Slides/pictures/F8RKB6FIYV9FXJK.jpg and /dev/null differ diff --git a/Slides/pictures/Vinodol.jpg b/Slides/pictures/Vinodol.jpg deleted file mode 100644 index 1dda73ce46093ede4568d2ae0b8626bb2f50bb46..0000000000000000000000000000000000000000 Binary files a/Slides/pictures/Vinodol.jpg and /dev/null differ diff --git a/Worksheet/Worksheet1.md b/Worksheet/Worksheet1.md index 503a5304782eb350cf52dfbe5d3ed1f1a1d28f34..140e7636830e3dbc9bcec03dd42c81b709f07f4b 100644 --- a/Worksheet/Worksheet1.md +++ b/Worksheet/Worksheet1.md @@ -1,18 +1,95 @@ -# Play with types +--- +title: Worksheet 1 +--- -- assignments -- casts -- see truncatures (byte / short / int / long) -- see rounding errors (double / float, int / float) - double d = -1.237e12F - d ==> -1.236999995392E12 +# Warming-up (1h ?) -# General REPL practice +## Assignments -- the value vs. its representation -- the memory, adress vs. value (tests `==` vs. .equals) +Create an `int` variable to represent the number of sides for a polygon and +initialize it to `3` (triangle). -# Loops +- Create a `String` variable to represent the name of the person next to you + without initializing it right away. +- Now set it to its appropriate value. +- Then, change it to your own name. Finally, try to set it to the value `null`. -- problem of the "n/2 vs 3×n+1" convergence, Fibonacci ? -- spy games: ROT-13, Vigenère, XOR +Can you create a variable of type `void` ? Why ? + +## Casts + +- Create a `short` variable representing the current year number in the + Gregorian Calendar. +- Now cast it to `byte`: what happens ? +- Store the resulting value into a `byte` variable. Do you get your value back + when casting this second variable back to `short` ? What's going on ? + +- Create a `byte` variable representing the current month in the same calendar. +What happens if you cast it to `short` ? And if you cast a second time back to +`byte` on to of the value obtained after the first `short` cast (sprinkle +parenthesis liberally) ? + +## Statements and Expressions + +### Printing vs. evaluating + +Print the name of the person next to you (use `System.out.println`). Is the +output of `jshell` any different from when you simply have it evaluate the +variable containing it ? Why ? + +Can you copy the content of this variable to a new variable ? Can you do the +same with the printing statement (`String copy = +System.out.println(neighborName)`) ? + +### Computing new values + +Now dynamically create a `String` value containing an at sign (`@`) immediately +before the name of the person next to you. Store the value you get to a new +variable called `nick`. + +- Look up the documentation for the `String` class and find how to compute a new + string skipping the first characters from a given input string. +- Use it to print your neighbor's name using the `nick` variable instead of the + original variable containing it. +- Store the corresponding value to a new variable called `computedNeighborName`. + +### Comparing + +- Evaluate `3 == 4`. What does `jshell` return ? Is that an expression or a +statement ? +- What about `4 == 4` ? +- What about `neighborName` == `neighborName` ? +- And what about `neighborName` == `computedNeighborName` ? +- How can you explain what you observe ? + +# Loops (1h ?) + +## The ASCII set + +Use casts to perform conversions between a character and its code (both to and +from). + +Now, iterate over the $[0, 255]$ range to print each character next to its code. +You got yourself an ASCII table ! + +## Rot13 + +Cæsar's Rot13 was a clever (well at the time at least) scheme to cipher +messages. From a given input message, he would replace all letters with the +letter 13 ranks after in the alphabet (wrapping at 'z' of course). + +Find a way to compute the replacement letter for a given initial letter. + +Now declare a String variable holding a message and write a loop to print its +Rot13 encoding (you want to look `.charAt()` up). + +## Collatz conjecture + +Pick any integer number you want and save it as `int currentValue`. Now apply +the current rule: + +- if `currentValue` is even, divide it by 2 +- otherwise, multiply it by 3 and add 1 + +Repeat a couple times. What do you observe ? Can you make a conjecture ? When +will it stop ? Write a `while` loop verifying it. diff --git a/Worksheet/Worksheet2.md b/Worksheet/Worksheet2.md index b3ee19497c8ce8d4c90618a5c36f0d187c54001e..17a6e3f755a34386eb69fd6d45be105d12f9cc3d 100644 --- a/Worksheet/Worksheet2.md +++ b/Worksheet/Worksheet2.md @@ -2,87 +2,116 @@ title: Worksheet 2 --- -# Warming-up with objects - -## `instanceof` - -### Matching variables and types - -Create three variables: `someString`, `someInteger` and `someInt` of types -`String`, `Integer` and `int` respectively and initialize them with . We're -going to give `instanceof` a try. What happens when testing (pay attention to -the content of error messages if you get any): - -- `someString instanceof String` ? -- `someInteger instanceof Integer` ? -- `someString instanceof Integer` ? -- `someInteger instanceof String` ? -- `someInteger instanceof int` ? -- `someInt instanceof Integer` ? - -### What about non-variables ? - -Let's see now what happens if we try it with non-variable values. Again, read -the error messages carefully: - -- `"" instanceof String` ? -- `((Integer) 4) instanceof Integer` ? -- `"" instanceof Integer` ? -- `((Integer) 4) instanceof String` ? - -## Points - -- Declare a simple class to model a geometric point in the plane (2D space). -- Add a `distance` method to compute the (euclidian) distance between two - points. - -## Sharing space with `static` - -- Declare a class `Serial` having only one `long` field and one constructor - taking as argument the number to "wrap" as a `Serial`. -- Now modify it to add a `static` field to "remember" the last number given as a - `Serial`. -- Remove the argument to the constructor, and use the previous field instead, - while incrementing it. What do we get ? -- Complete the class with an `.olderThan` method that takes another `Serial` and - is able to return `true` if and only if it was created after the target - object. - -# Fun with functions - -## Don't forget to `return` ! - -- Take the snippet from slide 14, and enter it `jshell`. It should work. -- Play a bit with it to test if it can, indeed, find a sequence of identical - characters of the requested size. -- Now delete the last line: `return null` and enter it again. What happens ? Why - ? - -## Pass by value, pass by reference - -- Declare an `int` value `i` and assign it any value you want. -- Create a (`void`) function that increments its (`int`) argument. Is it working - when you call it on `i` ? -- Now declare a wrapper class `N` having a unique field `intValue` (similar to step 1 of - the above exercice with `static`). -- Create a similar function to the previous one, but operating on `N`. -- Instantiate `N` and test your function on the resulting object. Is working any - better ? - -## Return of the ROT-13 - -- Declare a function `encodeCharacter` that transforms a letter represented as a - `char` into the letter 13 ranks after it in the alphabet, starting over to - `'a'` after `'z'`. How would you handle the non-letters ? How about the case ? -- A property of ROT-13 is to be involutive: the transformation is its own - inverse (because $13 \times 2 = 26 \equiv 0 \mod 26$). Check this by applying - the previous function once, then twice ($f(c), f(f(c))$). -- From a given `String s`, declare a `char[]` of the same length. -- From the previous experiment, declare a function `stringToArray` which - converts a `String` to an array containing all its characters in the same - order. -- Browse the documentation of `String` and find a function that could turn a - `char[]` into a `String` containing the same characters. -- Now declare a function `encodeString` which takes a `String` and return it - encoded with ROT-13. Again, verify that the transformation on the whole - `String` is involutive. +# Fun with funs + +## Collatz returns ! + +Remember what we did from slide 9 to 14, turning the implementation idea from +slide 13 ("Implementing the body") into a proper Java function ? + +Look at the code from slide 5 giving a solution for the last exercise of +practice 1 printing a Collatz sequence from a given number. + +- identify the *interface* of this procedure: what argument(s) does it need ? + what are their types ? +- it's a procedure: what will its return type be ? +- can you describe what this function is doing ? Find a good name for it. +- now turn this one-time snippet into a proper function + +Now you can easily visualize Collatz sequences from any input number you want. +Use it to manually check that the Collatz conjecture holds for all integers +between `1` and `10`. + +## Namespace occupation + +The euclidian norm in a 2D-space ("plane") can be defined as a function of the +coordinates $(x_A, y_A)$ of a given point $A$. + +$$ |A| = \sqrt{x_A^2 + y_A^2}$$ + +Implement this as a function with signature: `double norm(double x, double y)`. +You may have to browse the documentation to find functions to compute the square +and square root of a given input number. + +Test it on some values where you know the result in advance: the origin `(0, +0)`, the unit on respectively the *x* and *y* axis `(1, 0)` and `(0, 1)`, the +opposite corner from the origin on the unit square `(1, 1)` (remember that +$\sqrt{2} \approx 1.414$). + +Now, let's define the same function but for a 3D-space. Can you keep the same +name ? What do you suggest ? + +# Objects + +## Sharing the namespace + +### 2D-Points + +- Declare a simple class `Point2D` to model a geometric point in the plane (2D + space). What fields must it contain ? What type will you use for them ? +- Add a `norm` method to compute the same metric as previously. How will the + signature differ from the signature of the function defined above ? + +### 3D-Points + +- Now create a new class to represent points in a 3D space. +- Add the corresponding `norm` method to it too. Is there any naming conflict ? + +## Pass by value / pass by reference + +- Declare an `short` value `age` and assign it to `4`. +- Create a (`void`) function called `increment` that increases the value of its + only (`short`) argument by `1` (modifies it without returning it). +- Apply it on `age`. Did you get any error ? Was `age` modified ? + +A native value is nothing more than a (temporary) value in the processor. +There's no memory location available. When a function is called in Java, it is +passed a copy of its arguments. They are "passed by value". Passing by value is +simpler and closer to the mathematical intuition of functions, but it can be +costly for huge data structures. + +We're now going to define a special wrapper for the `short` type where we have +access to the inner value : `RWShort`. This class should have one field of type +`short` named `value`. + +- Declare a `RWShort` value called `rwAge` holding the same value `4`. +- Modify `increment` so that it now works on `RWShort` and not `short` +- Use it on the `rwAge`. Is it modified now ? Why ? + +Java passes arguments by value; but since the value of objects are their +reference in memory, this actually amounts to passing by reference ! We get the +best of both worlds. + +## Automatically numbering instances with `static` + +- Declare a class called `Serial` having only one `long` field and one + constructor taking as argument the number to "wrap" as a `Serial`. +- Now modify it to add a `static` field initialized to `0`. +- Remove the argument to the constructor, and use the value of the `static` + field instead, while incrementing it. The `static` field is keeping track of + the highest number and "magically" guarantees to generate distinct numbers. +- Complete the class with an `.olderThan` method that takes another `Serial` as + argument and is able to return `true` if and only if it was created after the + target object (the one on which the method is applied). + +This pattern can be very useful to keep track of objects created throughout an +application. + +# Executable code + +You will now create your first command-line program. + +- Create an empty `Main` class holding the structure for an empty program (draw + inspiration from the last section of the slides). +- Now add a method to this class using the code from the function defined in the + first exercise ("Collatz returns !"). Should this method be `static` or not ? +- Which `static` method from the `Integer` class lets one convert a `String` to + an `int` value ? Read its documentation to understand what happens when its + argument doesn't represent a number. +- Modify the `main` function of your class to + + make sure only one argument is passed to your program + + convert it to an `int` and don't forget to handle the errors which may arise + + pass it to the collatz method you've imported +- Compile and run your program from a shell: you now have an executable which + can display the Collatz sequence from a number passed to it, and it doesn't + require its users to type Java or to know anything about the `jshell`. diff --git a/Worksheet/Worksheet3.md b/Worksheet/Worksheet3.md index 34d1bf749dd486e19496ecaefa5d39885648ec2d..9659f278b31ffd97cf4ea8c6e44cb016305f74a9 100644 --- a/Worksheet/Worksheet3.md +++ b/Worksheet/Worksheet3.md @@ -2,111 +2,215 @@ title: Worksheet 3 --- -# Command-line tools - -## Wiring it all to a function - -### A greeter - -- Create a simple "helloworld" program in a class called `Greeter` -- Create a `static` method taking the name of a person as argument and greeting - that person by their name -- Now modify the `main` function to check there is exactly one argument on the - command-line, pass it to the previous method when there is and print a helpful - message otherwise -- Compile the program and launch it with different names as input - -### Rot-13 - -- Create a "helloworld" main class -- Create a separate `Rot13` class exposing an implementation of the rot-13 - algorithm like we've seen last time -- As previously, check and wire the first and only argument of `main` in the - main class to this function in the `Rot13` -- Compile and use the program to encrypt messages -- Since messages can be decoded by re-encoding them, check your implementations - by exchanging encrypted messages with your classmates which you should be able - to read by re-encoding them on your machine - -### CLI calculator - -- Create a new package at `fr.insa_lyon.ist_4_jav.calculator` -- Create a class called `Sum` to hold an array of integers and expose a method - computing their sum -- Create a main class to pass all the command-line arguments to this function - and print the result (don't forget the types ! `String[]` $\neq$ `int[]`) -- Compile and test -- Add a new class called `Product` to the `fr.insa_lyon.ist_4_jav.calculator` - package doing what you expect (the same as `Sum` with the product of all the - integers in the array) -- Now modify the main function to expect the first argument to be `+` or `*`, - and pass all the other arguments to `Sum` or `Product` respectively -- Some parts in `Sum` and `Product` should look very similar. Add an `abstract` - class called `Reducer` implementing all that can be implemented and leaving - the `operator` method abstract -- Modify the previous `Sum` and `Product` methods to extend `Reducer` instead - -## Dialogs - -### Looping - -- Start over from the greeter, but modify it to read the name of the person from - standard input instead of from the command-line the program was called on - (look up `System.console.readLine()` and friends for usage and help) -- Print a message explaining that the user should enter their name before the - call to the previous function -- Compile and test -- Modify it to detect if the user entered the litteral value `quit` and print a - special message in that case -- Add a boolean variable to hold whether the program should keep running or not - and initialized to `true` and make the block handling `quit` set it to `false` -- Now modify the main function to become a `while` loop which checking the state - of this variable to continue, and simply keep printing the name otherwise - -### Multiline printing - -- From the previous, start detecting other particular values and write custom - reactions for those cases -- Now the prompt message should still be asking the user for their name. Not - very accurate. Modify it to fit what your program now does. In particular, add - a line for each of the "particular values" (let's call them *commands* from - now on) you detect documenting it to the user, and stating clearly the command - name like so +# A little cryptography -``` -[quit] Quit this program -``` +## Caesar + +Remember *Rot13* from [Worksheet +1](https://perso.liris.cnrs.fr/abrenon/no-backup/Worksheet1.pdf) ? It is a +substitution cipher said to have been invented by the roman emperor Caesar which +consists in shifting the letters in the source message, starting over from 'A' +if a letter "greater than" 'Z' is needed. Caesar is said to have always shifted +the letters by 13 ranks in the alphabet, making the process an involution: with +this value for the key, encoding and decoding become the same process (because +$13 + 13 = 26 \equiv 0 [26]$, total number of letters in the latin alphabet). In +practice other values can be used as long as the sender and recipient agree on +it and this choice acts as a "key": a secret protecting the original text and +allowing to retrieve it. For instance, let us use the key $6$ on some input +message: + +`"CRASSUS IS DUMB"` + +$\hspace{1cm}\downarrow + 6$ + +`"IXGYYAY OY JASH"` + +Decoding is then performed substracting the key instead of adding it (or, +equivalently, adding its complement to 26, here $26 - 6 = 20$). Starting from +your previous implementation (or over if you skipped it) in Worksheet 1 +generalize it into a function `caesar` taking the key and the source message as +inputs and returning the encrypted text. + +### Design + +- How will you name its arguments ? +- Last time, we had only printed the encrypted message on the console (`stdout` + with `System.out.println`) but now we want to be able to handle the returned + value. What should its signature be ? + + +### Implementation + +Remember that we can't modify characters in a `String`. + +- What other data structure can we use internally during the encryption / + decryption process and eventually convert to `String` ? +- How to create it ? +- How to access its individual characters ? +- How to retrieve a `String` from it ? + +Look up the documentation (or the slides from class 2) if you don't remember. +Also, keep in mind that Caesar's cipher is only concerned with letters and +ignores spaces which were probably not considered as proper characters at the +time. Make sure your function leaves all non-alphabetical characters unchanged. + +Test it with the above message, manually passing it a key or its opposite to +encrypt or decrypt. Check that *Rot13* is an involution, i.e., that using key +`13`, you can decrypt a message by re-encrypting it as if it were a plain text. + +## Vigenère + +In practice, Caesar's cipher is very weak because there are only 25 possible +keys, and since it keeps the statistical repartition of letters unchanged, in +particular double letters, it is reasonably easy to break it without even trying +all of them. Another classic substitution method, called the *Vigenère* cipher, +addresses this issue. You can view it as a kind of Caesar where the offset +changes for each letter. In practice, the lists of different offsets (looped +when the source message is longer) is memorized through its alphabetic +equivalent, becoming a textual key instead of a numeric one. For instance, the +key "BRUTUS" may be used on the previous message, meaning that the first letter +should be offset by 2 (the rank of 'B' is 2), the second one by 18, third by 21… and +looping to 2 for the seventh letter. + +`"CRASSUS IS DUMB"` + +$\hspace{1cm}+$ + +`"BRUTUSB RU TUSB"` + +$\hspace{1cm}\downarrow$ -- (as a bonus, make sure all your commands have a different initial and modify - your detector to also work for the initial only) +`"EJVMNNU AN XPFD"` -### A menu class +### Design -- The previous exercice was a bit tedious, we do not want to do the same another - time for another menu. We should factorize what can be factorized. Create a - class to represent a menu entry, associating a full name and shortcut to a - normalized name -- Create a `Menu` class to hold several entries, a title and a prompt -- Modify the previous to use the new class -- Now create new sub-menus, and add commands in your main menu to call those - submenus. +- How will the names of the arguments for this new function differ from the + previous one ? +- How about their types ? -# Modeling objects +### Implementation time ! -## Tic Tac Toe +- What is the major difference with `caesar`'s implementation ? +- What additional local variable will you need to represent this ? +- Remember how we left non-alphabetical characters out in `caesar` ? There are + two ways to "align" the looped key in `vigenere` : including the unchanged + characters or not. In the example above we have chosen to align the key with + the transformed characters only. Make sure you follow this convention in your + implementation. -- Create a new package called `fr.insa_lyon.ist_4_jav.games` -- Define a class to represent a Tic Tac Toe game. It should be able to hold the - state of a game, to print a textual representation of it -- Define a class to represent a move -- Add a (`private`) method to check if a move is valid for a given grid -- Add a (`public`) method to return a new grid from a move if it's valid +## Factorizing -## Open modeling +Both being substitution ciphers, there should be similarities in the above +functions. What could be shared between `caesar` and `vigenere` ? + +Factorize those bits into subfunctions. Check that your code still works. In +particular, `vigenere` should allow you to reproduce what you could already do +with `caesar` (*Rot13* is just *Vigenere* cipher with key `"M"`). + +What are the remaining similarities between both functions ? Can we factorize +them any further ? + +# Structuring + +The concept of inheritance we have covered today allows us to capture similar +behaviours and share parts of the implementation. In addition, having objects +exposing the previous functionalities will easily take care of the notion of +state that needed to be maintained during the computations. + +## Declare an interface + +First it can be useful to underline the "common shapes" between two classes and +name them. This will allow us to handle various ciphers in the same way later in +the code. + +- Create an interface called `Cipher` representing the ability to both + encrypt and decrypt messages. +- What should be the signatures of the corresponding methods ? + +## A common behaviour + +- We have called both *Caesar* and *Vigenère* "substitution" ciphers. This will + reflect on our code as an abstract class: saying a cipher belongs to this + family means they it will share a common behaviour with them (namely, that it + ciphers characters separately and that the image of each will depend on its + rank in the alphabet). Create this class named `Substitution`. +- In the previous factorization process, you should have created a function + performing the shift of individual characters. Create the corresponding method + on your class. Should it be `static` or not ? What will be the implications ? +- To generalize substitution ciphers, we need to say that they have a specific + (`int`) offset which can change over the execution (constant for *Caesar* but + looping over the key in *Vigenère*. Add a corresponding `abstract protected + int` method to your class (its state is tied to a particular instance of the + class which is why it should not be `static`) +- In the first part, we noticed that encrypting and decrypting was basically the + same operation, only affecting the way they key was applied (added or + substracted). Implement this general process as a common method taking a + factor of `+1` or `-1` as argument. What visibility should it have ? +- Implement both `encrypt` and `decrypt` for `Substitution` using this + additional method. This was the structure which we hadn't been able to + factorize at the end of the previous part. + +## Inheriting + +- Inheriting the above `abstract class`, implement both `Caesar` and `Vigenere` +- See how their implementation becomes mostly "administrative" tasks handling + their respective internal states to align with the common behaviour captured + by `Substitution` ? + +# A usable tool + +Let us now package the above into a proper command line ciphering suite. + +## The logic + +- We will call our tool `i4j-crypto` and package its logic as a library under + the virtual path `fr.insa_lyon.ist_4_jav.crypto`. Create the empty folder + structure for it. +- Create a file for each of the above entity (interface and classes) and fill it + with the code you've written in the previous part. +- Don't forget to add the appropriate `package` mentions +- What about the visibility ? Which interface or classes need to be `public` ? + Can they be `private` or `protected` ? Why ? What would be the implication of + the abstract class `Substitution` not being `public` ? + +## The tool + +- Create an empty `Main` class with the appropriate `main` method. +- Check that everything compiles. + +## Design + +We propose the following syntax for our tool: + +```bash +i4j-crypto [caesar|vigenere] -k <KEY> [-e|-d] <MESSAGE> +``` -- Let's assume we want to build a D'n'D-like game. Let's think about the kind of - objects we want: quest item, clothes, characters, potions, weapons, spells… -- How can we organize them ? -- What behaviour can be factorized ? what behaviours define `interface`s ? -- Group the objects you defined into classes (possibly `abstract`) and add - `interfaces` as you deem appropriate. +meaning that the command should be followed either by the mode name `caesar` or +`vigenere`, then by the option `-k` with a key as argument and finally by either +the `-e` or `-d` flag (respectively to make the program encrypt or decrypt the +remaining `<MESSAGE>` text). + +- Edit your `main` function so that it enforces the above behaviour, printing + helpful error messages and exiting with status `1` when it detects an invalid + syntax (see `System.exit`). +- In particular, pay attention to fact that depending on the cipher used, the + `<KEY>` argument should be handled as an integer or a text. + +## Wiring it all + +- Add the `import` statement required in the `Main` class to show that it is + using our cryptographic library. +- Now handle the correct cases by creating a `Cipher` variable while parsing the + command line and finally calling its `encrypt` or `decrypt` method, depending + on the value of the corresponding flag. See how having a common type thanks to + the `Cipher` interface simplifies our code ? +- Most command-line tools display their syntax and available options when + started with the `--help` (or `-h`) flag. This is useful for people + discovering new tools to understand what they expect and how they are supposed + to work. Handle this new special cases. +- Test your tool to encrypt and decrypt messages with the people around you in + class. +- You can create another "entry point" (main class) to your program performing + several encryption, decryption, or mix thereof one after another. Notice any + bug(s) ? How could we modify the previous implementation(s) to fix them ? diff --git a/Worksheet/Worksheet4.md b/Worksheet/Worksheet4.md index c650f56bc27246f5fb36e8d20d52fbb6b6fe5a7e..ec68320e6360854fc33f1953bd1e5d974dbb6c15 100644 --- a/Worksheet/Worksheet4.md +++ b/Worksheet/Worksheet4.md @@ -25,23 +25,27 @@ long fibonacci(int n); ## Let's add some logging -- Modify the previous function to extract the sum (call to the operator `+`) - into a separate function. Check that everything is still working. -- Now modify the sum function to display both its arguments before returning its - result. Retry the small values. What do you notice ? +- Modify the previous function to log its argument each time it is called. +- Retry the previous calls with the small values. What do you notice ? ## Keeping answers -- Now we'll need a place to store terms, so let's create a class `Fibonacci` - with a `static` array named `cache` to hold all the terms already found. As - we've seen, terms around $f_{40}$ are already quite large, so we are likely to - hit the `long` overflow if we consider terms for indices too high so may want - to limit ourselves to a hundred terms, and dimension this cache - accordingly. Don't forget to initialize the first two cells of the cache for - $f_0$ and $f_1$ (hint: the value for this `static` field could be returned by - a `static` function). -- Add your previous functions as `static` methods of this new class, keep `sum` - and rename `fibonacci` into `get`. +A simple way to address the issue we have just underlined is *memoization*: we +trade a little space (in memory) against some time (to run the algorithm). If +our program could somehow "remember" the answers it gives it wouldn't have to +compute the same sums over and over. + +- We'll need a place to store terms, so let's create a class `Fibonacci` + with a `static` array named `cache` to hold all the terms already found. + Regarding its type, as we've seen, terms around $f_{40}$ are already quite + large, so we are likely to hit the `long` overflow if we consider terms for + indices too high so may want to limit ourselves to a hundred terms, and + dimension this cache accordingly. Don't forget to initialize the first two + cells of the cache for $f_0$ and $f_1$ (hint: the value for this `static` + field could be returned by a `static` function). +- Add your previous function as a `static` method of this new class, renaming it + from `fibonacci` to `get` (so we can write `Fibonacci.get` and it kind of + makes sense). - Now modify `get` to check if the result is missing from the cache first, compute the sum and store it only in that case, and finally return the content of the cache. @@ -49,33 +53,85 @@ long fibonacci(int n); observe regarding logging messages ? In particular, what happens when you compute the same term twice ? -# Subtyping - -## Wildcards - -- We want to count the number of occurrences of elements in lists. Implement a - function which given a list `objects` and a particular `target` to look for in - the list returns an `int` value counting the number of occurrences of `target` - found within `objects` - -```Java -int countOccurrences(List<Object> objects, Object target); -``` - -- Now declare a list of `Integers`, populate it with a couple values and test - your function `countOccurrences` on it. What happens ? Why ? -- Wildcards are helpful in this situation, replace `List<Object>` by `List<?>` - in the previous definition. - -## Generics - -- Test it again. Declare a `List<String>`, check that it works too. Can you look - for a `String` in the `List<Integer>` ? Is that a good thing ? -- Replace the wildcard by a generic type `T` to force the type of the list to - equal the type of the `target`. Try again to look for a `String` in a - `List<Integer>`. Better ? - -## Bounds - -- Now let's assume we want to count all elements smaller than the `target`. Our - function will hence work only on types which can be [compared](https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html) now. Implement this change on the previous function. +# Graphical User Interface + +Let us now create a graphical widget to expose the model of the Fibonacci +sequence we have previously implemented. + +## The Window + +- Starting from the Swing example in the class, create a new file `FiboGUI.java` + containing a `FiboGUI` class to hold the be the entry point of your program. + Make it create an empty window for now. +- As in the example on the slide, create a second `static` method called + `createAndShowGUI` to populate the window. +- Add a `JPanel` to structure the view and use a `GridLayout` for it as in the + example in the slides (2×2 should be enough). Remember that adding components + should go before calling `.pack()`. +- Then add two components to the `JPanel`: + + a `JLabel` to print a message describing the expected input + + a second `JLabel` to print the result + +## Number input + +Now we'll create a `JSpinner` to let the user pick a number. This requires quite +some work so instead of creating it directly inline, we will create a separate +class named `FiboInput` to handle it. Create a new file holding this class which +should inherit `JSpinner`. + +- The constructor for the parent class `JSpinner` requires a + [`SpinnerModel`](https://docs.oracle.com/javase/7/docs/api/javax/swing/SpinnerModel.html). + We will use the + [`SpinnerNumberModel`](https://docs.oracle.com/javase/7/docs/api/javax/swing/SpinnerNumberModel.html) + which requires four `Integer` values: + + an initial value + + a minimum value + + a maximum value + + a step value to say by how much to increase or decrease the current value + each time an arrow is pressed +- However, when calling `super` in a constructor, it should be the first line so + we'll need to create our `SpinnerModel` in one fell swoop. Add a `static` + method called `getRange` to return a `SpinnerModel`. It should create four + `Integer` variables as above, initialize them with sensible values, and return + a call to the constructor for `SpinnerNumberModel` on the four previous + variables. Why can the method return type `SpinnerModel` and not + `SpinnerNumberModel` (type returned by the call to the constructor) ? +- Implement `FiboInput`'s constructor by simply passing the result of `getRange` + to the `super` constructor. +- We can go back to `createAndShowGUI`, add a `FiboInput` variable called + `input`. Add it (as in `panel.add(…)`) between both `JLabel`s (intuitively, I + expect the input to be next to the label describing it and the label + presenting the result to come after, but this is my layout choice, you can + design your application differently). + +## Wiring the logic + +- Create a file named `Fibonacci.java` in the same directory as your application + and fill it with the previous class for your memoized code (you can remove the + debug lines, we don't need them any more). +- We will now need to modify the `FiboInput` to react to input: update the + header of the class to make it implement the [`ChangeListener` + interface](https://docs.oracle.com/javase/7/docs/api/javax/swing/event/ChangeListener.html). + In order to respect this "contract", a class needs to have a `public void + stateChanged(ChangeEvent e)` method. Add one to the class and have it log the + event `e` to the console. Register it to the Swing engine by calling the + `addChangeListener` on `super` in the constructor. What argument should be + passed to this method ? +- Recompile your application, run it, play with the number input and look at the + lines getting logged to the console. +- Now we'd like something more useful to happen when the value is changed: we'll + need access to the `JLabel output` from an instance of `FiboInput`. Add a + corresponding (`private`) field to the class and an argument to the + constructor which you'll use to set it. Update the code of the `stateChanged` + handler to write something to `this.output`. Don't forget to update + `createAndShowGUI` in `FiboGUI` to call the modified constructor for + `FiboInput` properly. +- All that remains is to have the handler use `Fibonacci.get` from the first + part. Retrieve the rank from the value of the `FiboInput` (remember: + `FiboInput` is a `JSpinner`, we made it inherit the class for this reason ! + what method could be useful to retrieve its current value ? read the + documentation carefully: what type does it return ? what could we do about it + ?). Pass it to `Fibonacci.get`, convert the (`long`) result to `String` and + set the output to that. + +Recompile everything. We got ourselves a simple Fibonacci sequence calculator !