```java
-// ./java/M08_RectangleFunctions.java#L2-L16
+// ./java/M08_RectangleFunctions.java#L4-L18
static double area(double a, double b) {
return a * b;
@@ -18,11 +18,11 @@ static boolean isSquare(double a, double b) {
}
public static void main(String[] args) {
- System.out.println("area(1, 5) = " + area(1, 5));
- System.out.println("area(1.5, 2.3) = " + area(1.5, 2.3));
+ Out.println("area(1, 5) = " + area(1, 5));
+ Out.println("area(1.5, 2.3) = " + area(1.5, 2.3));
- System.out.println("isSquare(1, 5) = " + isSquare(1, 5));
- System.out.println("isSquare(5, 5) = " + isSquare(5, 5));
+ Out.println("isSquare(1, 5) = " + isSquare(1, 5));
+ Out.println("isSquare(5, 5) = " + isSquare(5, 5));
}
```
@@ -58,73 +58,6 @@ print("is_square(5, 5) =", is_square(5, 5))
---
-## Pass by "Object Reference" / "Assignment"
-
-In a nutshell, Python has the same passing behavior as Java - although, Python lacks [**primitive types**](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html).
-
-
-
-```java [|3-9|12-18|]
-// ./java/M08_PassByObjectReference.java#L4-L20
-
-static void replace(List numbers) {
- numbers = Arrays.asList(42, 43, 44);
-}
-
-static void append(List numbers) {
- numbers.add(42);
-}
-
-public static void main(String[] args) {
- List oneTwoThree = new LinkedList<>(Arrays.asList(1, 2, 3));
-
- replace(oneTwoThree);
- System.out.println(Arrays.toString(oneTwoThree.toArray()));
-
- append(oneTwoThree);
- System.out.println(Arrays.toString(oneTwoThree.toArray()));
-}
-```
-
-```py [|3-8|11-17|]
-# ./python/m08_pass_by_object_reference.py
-
-def replace(numbers):
- numbers = [42, 43, 44]
-
-
-def append(numbers):
- numbers.append(42)
-
-
-one_two_three = [1, 2, 3]
-
-replace(one_two_three)
-print(one_two_three) # > [1, 2, 3]
-
-append(one_two_three)
-print(one_two_three) # > [1, 2, 3, 42]
-
-```
-
-
-
-
-
-**Arguments are ALWAYS passed by-value**, in Java and also in Python.
-When your argument is an object, the reference to that object is passed.
-
-- In Java, when you pass a primitive type like `int`, the value is copied.
-- Python has NO primitives. If you pass an `int`, the object reference is passed and NO data is copied.
- But, since `int` is [**immutable**](https://docs.python.org/3/reference/datamodel.html), you can't change the value of the original object either. \*
-
-\* From here on, things get complicated. Learn more about the technical details by [Robert Heaton. 2014. "Is Python pass-by-reference or pass-by-value?"](https://robertheaton.com/2014/02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/)
and [Sreejith Kesavan. 2012. "Understanding Python Variables and Memory Management"](http://foobarnbaz.com/2012/07/08/understanding-python-variables/).
-
-
-
-
----
-
## What else is different with Python functions? 1/3
diff --git a/slides/content/m09_classes.md b/slides/content/m09_classes.md
index 292b0a8..4a8d979 100644
--- a/slides/content/m09_classes.md
+++ b/slides/content/m09_classes.md
@@ -9,7 +9,7 @@ Python is object-oriented, but follows a more lean approach towards classes.
```java
-// ./java/M09_PassengersProgram.java#L3-L40
+// ./java/M09_PassengersProgram.java#L4-L37
class Passenger {
@@ -22,28 +22,24 @@ class Passenger {
}
void display() {
- System.out.printf("%s %s %n", firstName, lastName);
+ Out.println(firstName + " " + lastName);
}
+}
- static Passenger fromInput() {
- Scanner scanner = new Scanner(System.in);
-
- System.out.print("Enter first name: ");
- String firstName = scanner.nextLine();
- System.out.print("Enter last name: ");
- String lastName = scanner.nextLine();
+class PassengersProgram {
- scanner.close();
+ static Passenger createPassengerFromInput() {
+ Out.print("Enter first name: ");
+ String firstName = In.readLine();
+ Out.print("Enter last name: ");
+ String lastName = In.readLine();
return new Passenger(firstName, lastName);
}
-}
-
-class PassengersProgram {
public static void main(String[] args) {
Passenger lisa = new Passenger("Lisa", "Ha");
- Passenger user = Passenger.fromInput();
+ Passenger user = createPassengerFromInput();
lisa.display();
user.display();
@@ -51,7 +47,7 @@ class PassengersProgram {
}
```
-```py [|3|4-6|8-9|11-16|20-24|19|]
+```py [|3|4-6|8-9|12-16|19-24|19|]
# ./python/m09_passengers_program.py
class Passenger:
@@ -60,19 +56,19 @@ class Passenger:
self.last_name = last_name
def display(self):
- print(f"Passenger: {self.first_name} {self.last_name}")
+ print(self.first_name + " " + self.last_name)
- @staticmethod
- def from_input():
- first_name = input("Enter first name: ")
- last_name = input("Enter last name: ")
- return Passenger(first_name, last_name)
+def create_passenger_from_input():
+ first_name = input("Enter first name: ")
+ last_name = input("Enter last name: ")
+
+ return Passenger(first_name, last_name)
if __name__ == "__main__":
lisa = Passenger("Lisa", "Ha")
- user = Passenger.from_input()
+ user = create_passenger_from_input()
lisa.display()
user.display()
@@ -106,155 +102,9 @@ if __name__ == "__main__":
-#### Static methods
-
-- A **static method** needs the `@staticmethod` [**decorator**](https://docs.python.org/3/glossary.html#term-decorator) and omits the `self` parameter
-- A static method just means that it won't access any class properties
-
-
-
-
#### Instantiation
- Creating a new object works similar, but you omit the `new` keyword
- The `main` method in Python is actually a condition - we will learn more in the next modules
-
----
-
-## Informal Interfaces
-
-
-
-```java
-// ./java/M09_ShapesProgram.java
-
-interface Shape {
- double area();
-}
-
-class Circle implements Shape {
-
- final double radius;
-
- Circle(double radius) {
- this.radius = radius;
- }
-
- @Override
- public double area() {
- return 3.14159 * radius * radius;
- }
-}
-
-class Square implements Shape {
-
- final double length;
-
- Square(double length) {
- this.length = length;
- }
-
- @Override
- public double area() {
- return length * length;
- }
-}
-
-class ShapesProgram {
-
- public static void main(String[] args) {
- Shape[] shapes = { new Circle(5), new Square(10) };
- for (Shape shape : shapes) {
- System.out.println(shape.area());
- }
- }
-}
-
-```
-
-```py [|3-5|8-13|16-21|24-26|]
-# ./python/m09_shapes_program.py
-
-class Shape:
- def area(self):
- pass
-
-
-class Circle(Shape):
- def __init__(self, radius):
- self.radius = radius
-
- def area(self):
- return 3.14159 * self.radius * self.radius
-
-
-class Square(Shape):
- def __init__(self, length):
- self.length = length
-
- def area(self):
- return self.length * self.length
-
-
-shapes = [Circle(5), Square(10)]
-for shape in shapes:
- print(shape.area())
-
-```
-
-
-
-
-
-### What do we notice here?
-
-- There is no `interface` type in Python, instead we use a normal `class` and inhert from it
-- Methods are overridden without an explicit annotation - they are always replaced
-- No type checks are enforced by Python, try removing `Shape` or renaming the `area()` method ...
-
-
-
----
-
-## Duck-Typing
-
-Since there is NO type-checking at compile-time, we may also solely rely on [**duck-typing**](https://docs.python.org/3/glossary.html#term-duck-typing).
-An `AttributeError` is thrown at runtime, if the method you are calling wouldn't exist. \*
-
-```py [|3-16|19-21|21|]
-# ./python/m09_shapes_duck_typing.py
-
-class Circle:
- def __init__(self, radius):
- self.radius = radius
-
- def area(self):
- return 3.14159 * self.radius * self.radius
-
-
-class Square:
- def __init__(self, length):
- self.length = length
-
- def area(self):
- return self.length * self.length
-
-
-shapes = [Circle(5), Square(10)]
-for shape in shapes:
- print(shape.area())
-
-```
-
-
-
-### But, how can I have a "real" interfaces and inheritance in Python?
-
-- Use abstract classes via the [**`abc` module**](https://docs.python.org/3/library/abc.html)
-- Learn more about formal interfaces at [realpython.com/python-interface](https://realpython.com/python-interface/)
-
-
-
-
\* Look into [**type hints**](https://docs.python.org/3/library/typing.html) to have better type-checking at runtime and even before you run your code.
diff --git a/snippets/java/M03_MaximumValue.java b/snippets/java/M03_MaximumValue.java
index e794d34..34405cc 100644
--- a/snippets/java/M03_MaximumValue.java
+++ b/snippets/java/M03_MaximumValue.java
@@ -1,10 +1,10 @@
-import java.util.*;
+import inout.Out;
class MaximumValue {
public static void main(String[] args) {
- List
numbers = Arrays.asList(1, -10, 0, -5, -1000, 100, 7);
+ int[] numbers = {1, -10, 0, -5, -1000, 100, 7};
- int maximum = numbers.get(0);
+ int maximum = numbers[0];
for (int number : numbers) {
if (number > maximum) {
@@ -12,6 +12,6 @@ public static void main(String[] args) {
}
}
- System.out.println("The maximum value is " + maximum);
+ Out.println("The maximum value is " + maximum);
}
}
diff --git a/snippets/java/M04_StringConcatenation.java b/snippets/java/M04_StringConcatenation.java
deleted file mode 100644
index 5c36a29..0000000
--- a/snippets/java/M04_StringConcatenation.java
+++ /dev/null
@@ -1,11 +0,0 @@
-class StringConcatenation {
- public static void main(String[] args) {
- String a = "How";
- String b = "to";
- String c = "concatenate";
- String d = "strings";
-
- String result = String.join(" ", a, b, c, d);
- System.out.println(result);
- }
-}
diff --git a/snippets/java/M04_StringConversion.java b/snippets/java/M04_StringConversion.java
index 69d124f..0ff2a52 100644
--- a/snippets/java/M04_StringConversion.java
+++ b/snippets/java/M04_StringConversion.java
@@ -1,6 +1,8 @@
+import inout.Out;
+
class StringConversion {
public static void main(String[] args) {
int num = 42;
- System.out.println("The number is " + num);
+ Out.println("The number is " + num);
}
}
diff --git a/snippets/java/M07_BasicControlFlow.java b/snippets/java/M07_BasicControlFlow.java
index c1f976b..208c589 100644
--- a/snippets/java/M07_BasicControlFlow.java
+++ b/snippets/java/M07_BasicControlFlow.java
@@ -1,19 +1,21 @@
+import inout.Out;
+
class BasicControlFlow {
public static void main(String[] args) {
int x = 0;
switch (x) {
case 0:
- System.out.println("The value is 0");
+ Out.println("The value is 0");
break;
case 1:
- System.out.println("The value is 1");
+ Out.println("The value is 1");
break;
case 2:
- System.out.println("The value is 2");
+ Out.println("The value is 2");
break;
default:
- System.out.println("The value is something else");
+ Out.println("The value is something else");
}
}
}
diff --git a/snippets/java/M07_EnumeratingOverElements.java b/snippets/java/M07_EnumeratingOverElements.java
index 44ab62f..d140615 100644
--- a/snippets/java/M07_EnumeratingOverElements.java
+++ b/snippets/java/M07_EnumeratingOverElements.java
@@ -1,10 +1,12 @@
+import inout.Out;
+
class EnumeratingOverElements {
public static void main(String[] args) {
String[] names = {"Lisa", "John", "Susan", "Alex"};
int i = 0;
while (i < names.length) {
- System.out.println(i + " " + names[i]);
+ Out.println(i + " " + names[i]);
i++;
}
}
diff --git a/snippets/java/M07_IteratingElementsByIndex.java b/snippets/java/M07_IteratingElementsByIndex.java
index 0cb8063..106b6ce 100644
--- a/snippets/java/M07_IteratingElementsByIndex.java
+++ b/snippets/java/M07_IteratingElementsByIndex.java
@@ -1,9 +1,11 @@
+import inout.Out;
+
class IteratingElementsByIndex {
public static void main(String[] args) {
int[] numbers = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
for (int i = 5; i < 8; i++) {
- System.out.println(numbers[i]);
+ Out.println(numbers[i]);
}
}
}
diff --git a/snippets/java/M07_IteratingElementsByValue.java b/snippets/java/M07_IteratingElementsByValue.java
index 04bbdec..fc754b1 100644
--- a/snippets/java/M07_IteratingElementsByValue.java
+++ b/snippets/java/M07_IteratingElementsByValue.java
@@ -1,9 +1,11 @@
+import inout.Out;
+
class IteratingElementsByValue {
public static void main(String[] args) {
String[] names = {"Lisa", "John", "Susan", "Alex"};
for (String name : names) {
- System.out.println(name);
+ Out.println(name);
}
}
}
diff --git a/snippets/java/M07_PriceTax.java b/snippets/java/M07_PriceTax.java
index fc5c61f..c6c7f6b 100644
--- a/snippets/java/M07_PriceTax.java
+++ b/snippets/java/M07_PriceTax.java
@@ -1,18 +1,16 @@
-import java.util.*;
+import inout.Out;
class PriceTax {
public static void main(String[] args) {
- List prices = Arrays.asList(12.3, 5.2, 8.7, 1.2, 8.0);
- List gross = new ArrayList();
+ double[] prices = {12.3, 5.2, 8.7, 1.2, 8.0};
+ double[] gross = new double[5];
- for (double price : prices) {
- if (price > 8) {
- gross.add(price * 1.2);
- }
+ for (int i = 0; i < prices.length; i++) {
+ gross[i] = prices[i] * 1.2;
}
for (double price : gross) {
- System.out.println(price);
+ Out.println(price);
}
}
}
diff --git a/snippets/java/M07_SumOfAllDigits.java b/snippets/java/M07_SumOfAllDigits.java
index 08a0341..04212d7 100644
--- a/snippets/java/M07_SumOfAllDigits.java
+++ b/snippets/java/M07_SumOfAllDigits.java
@@ -1,12 +1,10 @@
-import java.util.*;
+import inout.In;
+import inout.Out;
class SumOfAllDigits {
public static void main(String[] args) {
-
- Scanner scanner = new Scanner(System.in);
- System.out.print("Enter a number: ");
- int n = scanner.nextInt();
- scanner.close();
+ Out.print("Enter a number: ");
+ int n = In.readInt();
int digitSum = 0;
@@ -15,6 +13,6 @@ public static void main(String[] args) {
n = n / 10;
}
- System.out.println("The digit sum is " + digitSum);
+ Out.println("The digit sum is " + digitSum);
}
}
diff --git a/snippets/java/M08_PassByObjectReference.java b/snippets/java/M08_PassByObjectReference.java
deleted file mode 100644
index 39cd62b..0000000
--- a/snippets/java/M08_PassByObjectReference.java
+++ /dev/null
@@ -1,21 +0,0 @@
-import java.util.*;
-
-class PassByObjectReference {
- static void replace(List numbers) {
- numbers = Arrays.asList(42, 43, 44);
- }
-
- static void append(List numbers) {
- numbers.add(42);
- }
-
- public static void main(String[] args) {
- List oneTwoThree = new LinkedList<>(Arrays.asList(1, 2, 3));
-
- replace(oneTwoThree);
- System.out.println(Arrays.toString(oneTwoThree.toArray()));
-
- append(oneTwoThree);
- System.out.println(Arrays.toString(oneTwoThree.toArray()));
- }
-}
diff --git a/snippets/java/M08_RectangleFunctions.java b/snippets/java/M08_RectangleFunctions.java
index 56386fd..93a1b00 100644
--- a/snippets/java/M08_RectangleFunctions.java
+++ b/snippets/java/M08_RectangleFunctions.java
@@ -1,3 +1,5 @@
+import inout.Out;
+
class RectangleFunctions {
static double area(double a, double b) {
return a * b;
@@ -8,10 +10,10 @@ static boolean isSquare(double a, double b) {
}
public static void main(String[] args) {
- System.out.println("area(1, 5) = " + area(1, 5));
- System.out.println("area(1.5, 2.3) = " + area(1.5, 2.3));
+ Out.println("area(1, 5) = " + area(1, 5));
+ Out.println("area(1.5, 2.3) = " + area(1.5, 2.3));
- System.out.println("isSquare(1, 5) = " + isSquare(1, 5));
- System.out.println("isSquare(5, 5) = " + isSquare(5, 5));
+ Out.println("isSquare(1, 5) = " + isSquare(1, 5));
+ Out.println("isSquare(5, 5) = " + isSquare(5, 5));
}
}
diff --git a/snippets/java/M09_PassengersProgram.java b/snippets/java/M09_PassengersProgram.java
index f197e09..337876b 100644
--- a/snippets/java/M09_PassengersProgram.java
+++ b/snippets/java/M09_PassengersProgram.java
@@ -1,4 +1,5 @@
-import java.util.*;
+import inout.In;
+import inout.Out;
class Passenger {
@@ -11,28 +12,24 @@ class Passenger {
}
void display() {
- System.out.printf("%s %s %n", firstName, lastName);
+ Out.println(firstName + " " + lastName);
}
+}
- static Passenger fromInput() {
- Scanner scanner = new Scanner(System.in);
-
- System.out.print("Enter first name: ");
- String firstName = scanner.nextLine();
- System.out.print("Enter last name: ");
- String lastName = scanner.nextLine();
+class PassengersProgram {
- scanner.close();
+ static Passenger createPassengerFromInput() {
+ Out.print("Enter first name: ");
+ String firstName = In.readLine();
+ Out.print("Enter last name: ");
+ String lastName = In.readLine();
return new Passenger(firstName, lastName);
}
-}
-
-class PassengersProgram {
public static void main(String[] args) {
Passenger lisa = new Passenger("Lisa", "Ha");
- Passenger user = Passenger.fromInput();
+ Passenger user = createPassengerFromInput();
lisa.display();
user.display();
diff --git a/snippets/java/M09_ShapesProgram.java b/snippets/java/M09_ShapesProgram.java
deleted file mode 100644
index 9ced0b0..0000000
--- a/snippets/java/M09_ShapesProgram.java
+++ /dev/null
@@ -1,41 +0,0 @@
-interface Shape {
- double area();
-}
-
-class Circle implements Shape {
-
- final double radius;
-
- Circle(double radius) {
- this.radius = radius;
- }
-
- @Override
- public double area() {
- return 3.14159 * radius * radius;
- }
-}
-
-class Square implements Shape {
-
- final double length;
-
- Square(double length) {
- this.length = length;
- }
-
- @Override
- public double area() {
- return length * length;
- }
-}
-
-class ShapesProgram {
-
- public static void main(String[] args) {
- Shape[] shapes = { new Circle(5), new Square(10) };
- for (Shape shape : shapes) {
- System.out.println(shape.area());
- }
- }
-}
diff --git a/snippets/java/inout/In.java b/snippets/java/inout/In.java
new file mode 100644
index 0000000..eb89d29
--- /dev/null
+++ b/snippets/java/inout/In.java
@@ -0,0 +1,475 @@
+package inout;
+
+import java.io.*;
+import java.util.LinkedList;
+
+/**
+ * Simple input from the keyboard or from a file.
+ * Copyright (c) 2005 Hanspeter Moessenboeck, University of Linz
+ *
+ * This class is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This class is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * This class allows reading formatted data either from the keyboard
+ * or from a file. It is intended to be used in an introductory
+ * programming course when classes, packages and exceptions are unknown
+ * at the beginning. To use it, simply copy In.class into the
+ * source file directory.
+ *
+ * All input comes from the current input file, which is initially
+ * the keyboard. Opening a file with open() makes it the new current
+ * input file. Closing a file with close() switches back to the previous
+ * input file.
+ *
+ * When reading from the keyboard, reading blocks until the user has entered
+ * a sequence of characters terminated by the return key. All methods read
+ * from this input buffer (including the terminating '\r' and '\n') until the
+ * buffer is fully consumed. When a method tries to read beyond the end
+ * of the buffer, it blocks again waiting for the next buffer.
+ *
+ * End of file detection: When reading from the keyboard, eof can be
+ * signaled as ctrl-Z at the beginning of a new line. When reading from a file,
+ * eof occurs when an attempt is made to read beyond the end of the file.
+ * In either case In.done() returns false if the requested data could not
+ * be read because of eof.
+ */
+@SuppressWarnings("unused")
+public class In {
+
+ /**
+ * End of file indicator returned by read() or peek() when no more
+ * characters can be read.
+ */
+ public static final char eof = '\uffff';
+
+ private static final int empty = '\ufffe';
+
+ private static final char eofChar = '\u0005'; // ctrl E
+ private static final LinkedList inputStack;
+ private static final LinkedList bufferStack;
+ private static final char[] LS; // line separator (eol)
+
+ private static InputStream in;
+ private static boolean done; // true if recent operation was successful
+ private static char buf; // last read character
+
+ private static char charAfterWhiteSpace() {
+ char c;
+ do c = read(); while (done && c <= ' ');
+ return c;
+ }
+
+ private static String readDigits() {
+ StringBuilder b = new StringBuilder();
+ char c = charAfterWhiteSpace();
+ if (done && c == '-') {
+ b.append(c);
+ c = read();
+ }
+ while (done && Character.isDigit(c)) {
+ b.append(c);
+ c = read();
+ }
+ buf = c;
+ return b.toString();
+ }
+
+ private static String readFloatDigits() {
+ StringBuilder b = new StringBuilder();
+ char c = charAfterWhiteSpace();
+ if (done && (c == '+' || c == '-')) {
+ b.append(c);
+ c = read();
+ }
+ while (done && Character.isDigit(c)) {
+ b.append(c);
+ c = read();
+ }
+ if (done && (c == '.')) {
+ b.append(c);
+ c = read();
+ while (done && Character.isDigit(c)) {
+ b.append(c);
+ c = read();
+ }
+ }
+ if (done && (c == 'e' || c == 'E')) {
+ b.append(c);
+ c = read();
+ if (done && (c == '+' || c == '-')) {
+ b.append(c);
+ c = read();
+ }
+ while (done && Character.isDigit(c)) {
+ b.append(c);
+ c = read();
+ }
+ }
+ buf = c;
+ return b.toString();
+ }
+
+
+ /**
+ * Read a raw character (byte).
+ * If an attempt is made to read beyond the end of the file,
+ * eof is returned and done() yields false. Otherwise, the read byte
+ * is in the range 0..255.
+ */
+ public static char read() {
+ char c;
+ if (buf != empty) {
+ c = buf;
+ if (buf != eof) buf = empty;
+ } else {
+ try {
+ c = (char) in.read();
+ if (c >>> 5 == 6) { // UTF8 110xxxxx 10xxxxxx
+ char d = (char) in.read();
+ c = (char) (((c % 32) << 6) + (d % 64));
+ }
+ } catch (IOException e) {
+ done = false;
+ c = eof;
+ buf = eof;
+ }
+ }
+ if (c == eofChar && inputStack.size() == 0) {
+ c = eof;
+ buf = eof;
+ }
+ done = c != eof;
+ return c;
+ }
+
+ /**
+ * Current available raw characters.
+ * In case of an error 0 is returned and done() yields false.
+ */
+ public static int available() {
+ int avail;
+ try {
+ avail = in.available();
+ } catch (IOException exc) {
+ avail = 0;
+ done = false;
+ }
+ return avail;
+ }
+
+ /**
+ * Read a character, but skip white spaces (byte).
+ * If an attempt is made to read beyond the end of the file,
+ * eof is returned and done() yields false. Otherwise, the read byte
+ * is in the range 0..255.
+ */
+ public static char readChar() {
+ return charAfterWhiteSpace();
+ }
+
+ /**
+ * Read a boolean value.
+ * This method skips white space and tries to read an identifier. If its value
+ * is "true" the method returns true otherwise false. If the identifier is neither
+ * "true" nor "false" done() yields false.
+ */
+ public static boolean readBoolean() {
+ String s = readIdentifier();
+ done = true;
+ if (s.equals("true")) {
+ return true;
+ } else {
+ done = s.equals("false");
+ return false;
+ }
+ }
+
+ /**
+ * Read an identifier.
+ * This method skips white space and tries to read an identifier starting
+ * with a letter and continuing with letters or digits. If a token of this
+ * structure could be read, it is returned otherwise the empty string is
+ * returned and done() yields false.
+ */
+ public static String readIdentifier() {
+ StringBuilder b = new StringBuilder();
+ char c = charAfterWhiteSpace();
+ if (done && Character.isLetter(c)) {
+ b.append(c);
+ c = read();
+ while (done && (Character.isLetter(c) || Character.isDigit(c))) {
+ b.append(c);
+ c = read();
+ }
+ }
+ buf = c;
+ done = b.length() > 0;
+ return b.toString();
+ }
+
+ /**
+ * Read a word.
+ * This method skips white space and tries to read a word consisting of
+ * all characters up to the next white space or to the end of the file.
+ * If a token of this structure could be read, it is returned otherwise
+ * an empty string is returned and done() yields false.
+ */
+ public static String readWord() {
+ StringBuilder b = new StringBuilder();
+ char c = charAfterWhiteSpace();
+ while (done && c > ' ') {
+ b.append(c);
+ c = read();
+ }
+ buf = c;
+ done = b.length() > 0;
+ return b.toString();
+ }
+
+ /**
+ * Read a line of text.
+ * This method reads the rest of the current line (including eol) and
+ * returns it (excluding eol). A line may be empty.
+ */
+ public static String readLine() {
+ StringBuilder b = new StringBuilder();
+ char c = read();
+ while (done && c != LS[0]) {
+ // Ignore '\r' on non-windows
+ if (c != '\r') {
+ b.append(c);
+ }
+ c = read();
+ }
+
+ int i = 0;
+ while (c == LS[i]) {
+ ++i;
+ if (i >= LS.length) {
+ break;
+ }
+ c = read();
+ }
+
+ if (i < LS.length) {
+ buf = c;
+ } else {
+ buf = empty;
+ }
+ if (b.length() > 0) {
+ done = true;
+ }
+ return b.toString();
+ }
+
+ /**
+ * Read the whole file.
+ * This method reads from the current position to the end of the
+ * file and returns its text in a single large string. done() yields
+ * always true.
+ */
+ public static String readFile() {
+ StringBuilder b = new StringBuilder();
+ char c = charAfterWhiteSpace();
+ while (done) {
+ b.append(c);
+ c = read();
+ }
+ buf = eof;
+ done = true;
+ return b.toString();
+ }
+
+ /**
+ * Read a quote-delimited string.
+ * This method skips white space and tries to read a string in the form "...".
+ * It can be used to read pieces of text that contain white space.
+ */
+ public static String readString() {
+ StringBuilder b = new StringBuilder();
+ char c = charAfterWhiteSpace();
+ if (done && c == '"') {
+ c = read();
+ while (done && c != '"') {
+ b.append(c);
+ c = read();
+ }
+ if (c == '"') {
+ c = read();
+ done = true;
+ } else {
+ done = false;
+ }
+ } else {
+ done = false;
+ }
+ buf = c;
+ return b.toString();
+ }
+
+ /**
+ * Read an integer.
+ * This method skips white space and tries to read an integer. If the
+ * text does not contain an integer or if the number is too big, the
+ * value 0 is returned and the subsequent call of done() yields false.
+ * An integer is a sequence of digits, possibly preceded by '-'.
+ */
+ public static int readInt() {
+ String s = readDigits();
+ try {
+ done = true;
+ return Integer.parseInt(s);
+ } catch (Exception e) {
+ done = false;
+ return 0;
+ }
+ }
+
+ /**
+ * Read a long integer.
+ * This method skips white space and tries to read a long integer. If the
+ * text does not contain a number or if the number is too big, the
+ * value 0 is returned and the subsequent call of done() yields false.
+ * A long integer is a sequence of digits, possibly preceded by '-'.
+ */
+ public static long readLong() {
+ String s = readDigits();
+ try {
+ done = true;
+ return Long.parseLong(s);
+ } catch (Exception e) {
+ done = false;
+ return 0;
+ }
+ }
+
+ /**
+ * Read a float value.
+ * This method skips white space and tries to read a float value. If the
+ * text does not contain a float value or if the number is not well-formed,
+ * the value 0f is returned and the subsequent call of done() yields false.
+ * A float value is as specified in the Java language description. It may
+ * be preceded by a '+' or a '-'.
+ */
+ public static float readFloat() {
+ String s = readFloatDigits();
+ try {
+ done = true;
+ return Float.parseFloat(s);
+ } catch (Exception e) {
+ done = false;
+ return 0f;
+ }
+ }
+
+ /**
+ * Read a double value.
+ * This method skips white space and tries to read a double value. If the
+ * text does not contain a double value or if the number is not well-formed,
+ * the value 0.0 is returned and the subsequent call of done() yields false.
+ * A double value is as specified in the Java language description. It may
+ * be preceded by a '+' or a '-'.
+ */
+ public static double readDouble() {
+ String s = readFloatDigits();
+ try {
+ done = true;
+ return Double.parseDouble(s);
+ } catch (Exception e) {
+ done = false;
+ return 0.0;
+ }
+ }
+
+ /**
+ * Peek at the next character.
+ * This method skips white space and returns the next character without removing
+ * it from the input stream. It can be used to find out, what token comes next
+ * in the input stream.
+ */
+ public static char peek() {
+ char c = charAfterWhiteSpace();
+ buf = c;
+ return c;
+ }
+
+ /**
+ * Open a text file for reading
+ * The text file with the name fn is opened as the new current input
+ * file. When it is closed again, the previous input file is restored.
+ */
+ public static void open(String fn) {
+ try {
+ InputStream s = new FileInputStream(fn);
+ bufferStack.add(buf);
+ inputStack.add(in);
+ in = s;
+ done = true;
+ } catch (FileNotFoundException e) {
+ done = false;
+ }
+ buf = empty;
+ }
+
+ /**
+ * Close the current input file.
+ * The current input file is closed and the previous input file is
+ * restored. Closing the keyboard input has no effect but causes
+ * done() to yield false.
+ */
+ public static void close() {
+ try {
+ if (inputStack.size() > 0) {
+ in.close();
+ in = inputStack.removeLast();
+ buf = bufferStack.removeLast();
+ done = true;
+ } else {
+ done = false;
+ buf = empty;
+ }
+ } catch (IOException e) {
+ done = false;
+ buf = empty;
+ }
+ }
+
+ /**
+ * Check if the previous operation was successful.
+ * This method returns true if the previous read operation was able
+ * to read a token of the requested structure. It can also be called
+ * after open() and close() to check if these operations were successful.
+ * If done() is called before any other operation it yields true.
+ */
+ public static boolean done() {
+ return done;
+ }
+
+ static { // initializer
+ done = true;
+ in = System.in;
+ buf = empty;
+ inputStack = new LinkedList<>();
+ bufferStack = new LinkedList<>();
+ String lineSeparator = System.getProperty("line.separator");
+ if (lineSeparator == null) {
+ LS = new char[]{'\n'};
+ } else {
+ char[] temp = lineSeparator.toCharArray();
+ if (temp.length == 0) {
+ LS = new char[]{'\n'};
+ } else {
+ LS = temp;
+ }
+ }
+ }
+
+}
diff --git a/snippets/java/inout/Out.java b/snippets/java/inout/Out.java
new file mode 100644
index 0000000..e94efe7
--- /dev/null
+++ b/snippets/java/inout/Out.java
@@ -0,0 +1,217 @@
+package inout;
+
+import java.io.*;
+
+/**
+ * Simple output to the console and to files.
+ * Copyright (c) 2005 Hanspeter Moessenboeck, University of Linz
+ *
+ * This class is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This class is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ * This class allows printing formatted data either to the console
+ * or to a file. It is intended to be used in an introductory
+ * programming course when classes, packages and exceptions are unknown
+ * at the beginning. To use it, simply copy Out.class into the
+ * current directory.
+ *
+ * All output goes to the current output file, which is initially
+ * the console. Opening a file with open() makes it the new current
+ * output file. Closing a file with close() switches back to the previous
+ * output file.
+ */
+@SuppressWarnings("unused")
+public class Out {
+
+ private static final PrintStream[] stack;
+
+ private static PrintStream out;
+ private static int sp;
+ private static boolean done;
+
+ /**
+ * Return true if the previous Out operation was
+ * successful, otherwise return false.
+ */
+ public static boolean done() {
+ return done && !out.checkError();
+ }
+
+ /**
+ * Print the boolean value b either as "true" or "false".
+ */
+ public static void print(boolean b) {
+ out.print(b);
+ }
+
+ /**
+ * Print the character value c.
+ */
+ public static void print(char s) {
+ out.print(s);
+ }
+
+ /**
+ * Print the integer value i.
+ */
+ public static void print(int i) {
+ out.print(i);
+ }
+
+ /**
+ * Print the long value l.
+ */
+ public static void print(long l) {
+ out.print(l);
+ }
+
+ /**
+ * Print the float value f.
+ */
+ public static void print(float f) {
+ out.print(f);
+ }
+
+ /**
+ * Print the double value d.
+ */
+ public static void print(double d) {
+ out.print(d);
+ }
+
+ /**
+ * Print the character array a.
+ */
+ public static void print(char[] a) {
+ out.print(a);
+ }
+
+ /**
+ * Print the String s.
+ */
+ public static void print(String s) {
+ out.print(s);
+ }
+
+ /**
+ * Print the Object o as resulting from String.valueOf(o).
+ */
+ public static void print(Object o) {
+ out.print(o);
+ }
+
+ /**
+ * Terminate the current line by writing a line separator string.
+ * On Windows this is the character sequence '\r' and '\n'
+ */
+ public static void println() {
+ out.println();
+ }
+
+ /**
+ * Print the boolean value b and terminate the line.
+ */
+ public static void println(boolean b) {
+ out.println(b);
+ }
+
+ /**
+ * Print the character value c and terminate the line.
+ */
+ public static void println(char s) {
+ out.println(s);
+ }
+
+ /**
+ * Print the integer value i and terminate the line.
+ */
+ public static void println(int i) {
+ out.println(i);
+ }
+
+ /**
+ * Print the long value l and terminate the line.
+ */
+ public static void println(long l) {
+ out.println(l);
+ }
+
+ /**
+ * Print the float value f and terminate the line.
+ */
+ public static void println(float f) {
+ out.println(f);
+ }
+
+ /**
+ * Print the double value d and terminate the line.
+ */
+ public static void println(double d) {
+ out.println(d);
+ }
+
+ /**
+ * Print the character array a and terminate the line.
+ */
+ public static void println(char[] a) {
+ out.println(a);
+ }
+
+ /**
+ * Print the String s and terminate the line.
+ */
+ public static void println(String s) {
+ out.println(s);
+ }
+
+ /**
+ * Print the Object o as resulting from String.valueOf(o)
+ * and terminate the line.
+ */
+ public static void println(Object o) {
+ out.println(o);
+ }
+
+ /**
+ * Open the file with the name fn as the current output file.
+ * All subsequent output goes to this file until it is closed.
+ * The old output file will be restored when the new output file is closed.
+ */
+ public static void open(String fn) {
+ try {
+ PrintStream s = new PrintStream(new FileOutputStream(fn));
+ stack[sp++] = out;
+ out = s;
+ } catch (Exception e) {
+ done = false;
+ }
+ }
+
+ /**
+ * Close the current output file.
+ * The previous output file is restored and becomes the current output file.
+ */
+ public static void close() {
+ out.flush();
+ out.close();
+ if (sp > 0) {
+ out = stack[--sp];
+ }
+ }
+
+ static { // initializer
+ done = true;
+ out = System.out;
+ stack = new PrintStream[8];
+ sp = 0;
+ }
+
+}
diff --git a/snippets/python/m04_string_concatenation.py b/snippets/python/m04_string_concatenation.py
deleted file mode 100644
index 0376e73..0000000
--- a/snippets/python/m04_string_concatenation.py
+++ /dev/null
@@ -1,8 +0,0 @@
-a = "How"
-b = "to"
-c = "concatenate"
-d = "strings"
-
-# we learn more about lists in the next modules ...
-result = " ".join([a, b, c, d])
-print(result)
diff --git a/snippets/python/m05_dict_operations.py b/snippets/python/m05_dict_operations.py
deleted file mode 100644
index d7b9ed5..0000000
--- a/snippets/python/m05_dict_operations.py
+++ /dev/null
@@ -1,20 +0,0 @@
-grades = {
- "math": 2,
- "programming": 1,
- "literature": 3
-}
-
-# alternative syntax
-grades = dict(math=2, programming=1, literature=3)
-
-
-grades["math"] # get elements by key
-grades["math"] = 5 # set elements by key
-grades["electronics"] = 4 # add a new element
-
-# remove an element (will raise an error if the key does not exist)
-if "math" in grades:
- del grades["math"]
-
-grades.keys() # get all the keys as a list
-grades.values() # get all the values as a list
diff --git a/snippets/python/m05_set_arithmetic.py b/snippets/python/m05_set_arithmetic.py
deleted file mode 100644
index ddaa2ac..0000000
--- a/snippets/python/m05_set_arithmetic.py
+++ /dev/null
@@ -1,10 +0,0 @@
-a = {1, 2, 3, 4, 5}
-b = {4, 5, 6, 7, 8}
-
-print("a | b =", a | b) # union
-print("a & b =", a & b) # intersection
-print("a - b =", a - b) # difference
-
-# > a | b = {1, 2, 3, 4, 5, 6, 7, 8}
-# > a & b = {4, 5}
-# > a - b = {1, 2, 3}
diff --git a/snippets/python/m05_set_operations.py b/snippets/python/m05_set_operations.py
deleted file mode 100644
index dfb71d8..0000000
--- a/snippets/python/m05_set_operations.py
+++ /dev/null
@@ -1,14 +0,0 @@
-numbers = {1, 1, 2, 3, 5} # notice how the '1' is only appended once after all
-
-numbers.add(7) # add new elements
-numbers.add(1) # add elements that already exist (no effect)
-
-1 in numbers # check for existence (much faster than with lists)
-
-# remove elements (will raise an error if the element does not exist)
-if 2 in numbers:
- numbers.remove(2)
-
-# iterate over set elements
-for val in numbers:
- print(val)
diff --git a/snippets/python/m07_price_tax.py b/snippets/python/m07_price_tax.py
index 96b3684..424279f 100644
--- a/snippets/python/m07_price_tax.py
+++ b/snippets/python/m07_price_tax.py
@@ -2,13 +2,12 @@
gross = []
for price in prices:
- if price > 8:
- gross.append(price * 1.2)
+ gross.append(price * 1.2)
print(gross)
# or, with list comprehension
prices = [12.3, 5.2, 8.7, 1.2, 8.0]
-gross = [price * 1.2 for price in prices if price > 8]
+gross = [price * 1.2 for price in prices]
print(gross)
diff --git a/snippets/python/m08_pass_by_object_reference.py b/snippets/python/m08_pass_by_object_reference.py
deleted file mode 100644
index 75518dc..0000000
--- a/snippets/python/m08_pass_by_object_reference.py
+++ /dev/null
@@ -1,15 +0,0 @@
-def replace(numbers):
- numbers = [42, 43, 44]
-
-
-def append(numbers):
- numbers.append(42)
-
-
-one_two_three = [1, 2, 3]
-
-replace(one_two_three)
-print(one_two_three) # > [1, 2, 3]
-
-append(one_two_three)
-print(one_two_three) # > [1, 2, 3, 42]
diff --git a/snippets/python/m09_passengers_program.py b/snippets/python/m09_passengers_program.py
index 333ef5a..dcbbb19 100644
--- a/snippets/python/m09_passengers_program.py
+++ b/snippets/python/m09_passengers_program.py
@@ -4,19 +4,19 @@ def __init__(self, first_name, last_name):
self.last_name = last_name
def display(self):
- print(f"Passenger: {self.first_name} {self.last_name}")
+ print(self.first_name + " " + self.last_name)
- @staticmethod
- def from_input():
- first_name = input("Enter first name: ")
- last_name = input("Enter last name: ")
- return Passenger(first_name, last_name)
+def create_passenger_from_input():
+ first_name = input("Enter first name: ")
+ last_name = input("Enter last name: ")
+
+ return Passenger(first_name, last_name)
if __name__ == "__main__":
lisa = Passenger("Lisa", "Ha")
- user = Passenger.from_input()
+ user = create_passenger_from_input()
lisa.display()
user.display()
diff --git a/snippets/python/m09_shapes_duck_typing.py b/snippets/python/m09_shapes_duck_typing.py
deleted file mode 100644
index 0cd9ee9..0000000
--- a/snippets/python/m09_shapes_duck_typing.py
+++ /dev/null
@@ -1,19 +0,0 @@
-class Circle:
- def __init__(self, radius):
- self.radius = radius
-
- def area(self):
- return 3.14159 * self.radius * self.radius
-
-
-class Square:
- def __init__(self, length):
- self.length = length
-
- def area(self):
- return self.length * self.length
-
-
-shapes = [Circle(5), Square(10)]
-for shape in shapes:
- print(shape.area())
diff --git a/snippets/python/m09_shapes_program.py b/snippets/python/m09_shapes_program.py
deleted file mode 100644
index eca9423..0000000
--- a/snippets/python/m09_shapes_program.py
+++ /dev/null
@@ -1,24 +0,0 @@
-class Shape:
- def area(self):
- pass
-
-
-class Circle(Shape):
- def __init__(self, radius):
- self.radius = radius
-
- def area(self):
- return 3.14159 * self.radius * self.radius
-
-
-class Square(Shape):
- def __init__(self, length):
- self.length = length
-
- def area(self):
- return self.length * self.length
-
-
-shapes = [Circle(5), Square(10)]
-for shape in shapes:
- print(shape.area())