Python Crash Course
Download
Report
Transcript Python Crash Course
Programming in the Large
Advanced Software Engineering
Stefan Maetschke
School for Information Technology and Electrical Engineering
The University of Queensland
2nd Semester 2008
Text book:
J. Niño and F.A. Hosch.
An Introduction to Programming and Object Oriented Design using Java Version 5.0.
3rd Edition!
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Introduction
1
Ch 1
Quote
First things first, but not necessarily in that order.
Doctor Who
course topics
Week
1
2
3
4
5
6
7
8
9
10
11
12
13
Topic
Introduction
Data abstraction/Class design
Data abstraction/Class design
Specification and Testing
Design
Interfaces
Inheritance
Exceptions and File I/O
Threads
(semester break)
Graphical User Interfaces
Collections
Generics/Iterators
... we can change that!
Chapters
0
1, 2
3, 4
5,6
7, 8
9
10, 11
15, 16
17
17
12, 14
20/22
there is much more
there is much more we don't talk about
Version control systems
Setup integration server
Testing methodologies
...
you see only my point of view
but there are many others ...
This course covers the basics of Java and Software Engineering.
There is much more to learn ...
two question
What is the percentage of large
software projects that fail?
> 30 developers
Failure: not in budget, not in time or
functionality missing
What is the main reason that large
software projects fail?
why this course
70% of large software projects "fail"
(budget, time, function)
(The Chaos Report (2009))
big != small
combinatorial explosion in complexity
abstraction/decomposition/simplicity are paramount
abstraction, modules, interfaces and unit tests
main problems: management, ignoring the user, ...
=> extreme programming
=> Scrum
There is much more bad than good code out there!
It is up to you to do better!
secrets to success
Confidence Level
Success Factors
Executive support
18
User involvement
16
Experienced project manager
14
Clear business objectives
12
Minimized scope
10
Standard software infrastructure
8
Firm basic requirements
6
Formal methodology
6
Reliable estimates
5
Other criteria
5
Chaos Report (2000), http://www.softwaremag.com/archive/2001feb/collaborativemgt.html
why Java
"modern" language
object-oriented
garbage collector
Java-doc
generics, exceptions, ...
widely used
rock solid
excellent documentation
huge library (> 3000 classes)
more strict than Python, Perl, Scheme
=> suited for large projects
googliness
google for: X language
C
Java
C++
C#
Perl
Python
Ruby
Scala
Haskell
kilo-hits
2008
2009
53,000
7,760
1,290
1,020
1,150
527
470
394
212
199,000
26,200
14,100
7,870
4,870
7,680
4,970
2,960
418
and the winner is…
http://shootout.alioth.debian.org/
median relative execution time,
Ubuntu : Intel® Q6600® quad-core, 13 Benchmarks, 20.07.09
eclipse - JDT
Java IDE based on the Eclipse framework
Free
Huge community
Very stable and active, new milestone version every six weeks
Java, SWT, JFace
Fast, "native" user interface
Platforms: Windows, Linux, HP-UX, AIX, Solaris, QNX, Mac OS X
Auto Building, Perspectives, Folding editor, Syntax
highlighting, Content assist, Auto Completion, Quick Fix,
Local History, Code Formatter, ...
Good JUnit integration
CVS, Subversion
Ant, Maven
RCP: Rich Client Applications
some eclipse plug-ins
Over 1000 plugins: http://eclipseplugins.2y.net/eclipse/plugins.jsp
Some highlights
CheckStyle: Checks coding standards:
http://eclipse-cs.sourceforge.net/
FindBugs: Uses rules to find (possible) bugs:
http://findbugs.sourceforge.net/
PDM: Finds possible bugs:
http://pmd.sourceforge.net/
Metrics: Calculates software metrices
http://metrics.sourceforge.net/
Sysdeo: Web development
http://www.sysdeo.com/eclipse/tomcatplugin
Profiler: A profiler
http://eclipsecolorer.sourceforge.net/index_profiler.html
Mini-Tute Problem
def digit_sum(s):
Simplify
v = 0.0
for i in range(0,len(s)):
if ord(s[i]) > ord('9') or
ord(s[i]) < ord('0'):
raise ValueError
v = v + (ord(s[i])-ord('0'))
return int(v)
Example: digit_sum("1234") -> 10
Mini-Tute Solution
def digit_sum(s):
return sum(map(int,s))
Much nicer,
isn't it?
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Introduction
1
Ch 1
Quote
Let me put it this way: today is going to be a
learning experience.
Unknown
contents
A bit of Scheme, Python, Perl, Java,
Scala
Java in anger
Short demo of Eclipse/JDK
Guidelines for good code
Analysis of some Java code
Mini-tutorial
Scheme :-|
fact(n) = 1*2*3*...*n
(define (fact n)
(if (= n 0)
1
(* n (fact (- n 1)))))
(fact 7)
there are
certainly enough
brackets
Perl :-(
sub fact {
my $prod = 1;
$prod *= $_ for 2..shift;
return $prod;
}
&fact(7)
really
ugly!
Python :-)
def fact(n):
prod = 1
for i in range(2,n+1):
prod *= i
return prod
straight forward but
neither elegant nor
efficient!
def fact(n):
short and
efficient
return reduce(lambda a,b: a*b, xrange(2,n+1), 1)
def fact(n):
return n*fact(n-1) if n else 1
recursive
and elegant
Java :-O
public class MyMath {
public static long fact(int n) {
long prod = 1;
for(long i=2; i<=n; i++)
prod *= i;
return prod;
}
public static void main(String[] args) {
System.out.println(MyMath.fact(7));
}
}
wow!
Scala :-))
def fact(n :Int): Int = if(n==0) 1 else n*fact(n-1)
def fact(n :Int) = (1/:(2 to n))(_*_)
cool!
Java in anger - compilation
e.g. Eclipse
editor
interprets
byte code
javac Hello.java
Hello.java
code,
a text file
compiler
Hello.class
byte code
JVM
Java in anger - types, variables
type
variable
name(s)
int x, y;
variable declaration
String str;
x = 1;
y = 0;
value assignment
str = "text";
int z = x+1;
combined declaration and assignment
Java in anger - control structures
if(x==0) {
for(int i=0; i<10; i++) {
return 0;
}
System.out.println(i);
}
else {
return x/y;
}
int i = 0;
while(i<10) {
switch(ch) {
case '1': x=1; break;
case '2': x=2; break;
default : x=0;
}
System.out.println(i++);
}
Java in anger - method
public class MyClass {
access
modifier
return
type
method
name
parameters
public double dist(double x, double y) {
double d = x-y;
local variable
return d*d;
}
}
return
statement
return
value
methods are always part of a class!
Java in anger - classes
package au.edu.uq.csse2002.helloworld;
package declaration
public class HelloWorld {
class definition
private static void output(String text) {
System.out.println(text);
class method
}
public static void main(String[] args) {
HelloWorld.output("Hello World");
}
}
main method
Eclipse demo
code analysis
What a software developer thinks…
What I look for when I mark…
Criteria
Proper formatting (style guide)
Complete java doc
Simplicity
Robustness
Encapsulation
Extensibility
good code
1.
2.
3.
4.
5.
6.
line length ≤ 80
complexity ≤ 10
no code duplication
follows language style
value-adding comments
automated tests
This is the
most important
slide of the
entire course!
just because your code is complex does not make it good code.
simplicity is the ultimate sophistication - Leonardo da Vinci
example code
bad and good
Mini-Tute Problem
class NameTable(object):
"""A table of names"""
def __init__(self, nameList):
self.__table = nameList
def set(self, i, name):
self.__table[i] = name
def __str__():
return " ".join(self.__table)
nameList = ["Calvin", "Luther"]
nameTable = NameTable(nameList)
nameTable.set(1,"Hobbes")
print nameTable
-> Calvin Hobbes
print nameList
This is a
tricky one!
Encapsulatio
n broken
here!
What's the
output?
Mini-Tute Solution
class NameTable(object):
"""A table of names"""
def __init__(self, nameList):
self.__table = nameList[:]
def set(self, i, name):
self.__table[i] = name
def __str__():
return " ".join(self.__table)
This fixes
the problem!
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Data Abstraction/Classes
2
Ch 1,2
quote
If you lie to the compiler, it will get its revenge!
Henry Spencer
contents
Dynamic versus static typing
Object Oriented Paradigm
Template for a class
Implementation genomic sequence class
Implementation test class
dynamic/static typing
dynamic typing: Type of variable, method is automatically
determined and can be changed:
Python: pi = 3.14; pi = "three point four"
def square(x): return x*x
static typing: Type of variable, method must be specified
explicitly and cannot be changed:
Java, C, C++, C#: double pi = 3.14;
int square(int x) { return x*x; }
type inference: Type of variable is inferred from type of given
value, variable, parameter:
Scala: def square(x :Int) = x*x;
Java types (primitives): boolean, byte, char, int, long, float,
double
object oriented programming
Object models some data and functions of a real
world entity/object
Object Oriented (OO) means aggregation of data
and corresponding functions plus more
Encapsulation
Abstraction
Polymorphism
Inheritance
Class is a template of an object
Object is an example of a class
Instance is a realization of a specific object
class in Python
The
template
class Person:
def __init__(self, name, age):
self.age
= age
self.name = name
constructor
member variables
homer = Person("Homer Simpson", 36)
An instance
instantiation
class in Java
Simplified!
This is not
the true
way!
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
in contrast to Python we need type and new here
Person homer = new Person("Homer Simpson", 36);
template executable class
public class ClassName {
// here go the constants/member variables
public ClassName() {
// Constructor
// initialization of member vars and other stuff
}
// here go the methods
public static void main(String[] args) {
// main method
}
}
human genome
first human genome sequenced (draft) in 2000
($300 million US)
~ 25000 genes
3 billion base pairs (= 750MB)
$1000 genome in a few years
The 1000 genomes project started in 2008
exponential increase in sequence data
deoxyribonucleic acid (DNA)
sequence browser
genomic sequence class
Specification
DNA: 4 letter alphabet (A,C,T,G)
circular genomes exist (bacteria)
biological coordinates start at 1
extraction of subsequences
immutable (or maybe not)
much, much more ...
Test
toy implementation of JUnit
Mini-Tute
This is
horrible
code!!!
class LousyModuloCounter {
int max1, inc2, c;
public LousyModuloCounter(int max, int inc) {
max1 = max;
/* init max */
inc1 = inc;
// init inc
c = 1;
// init c
Write
}
something
public void inc() {
better!
c = c + inc1;
for(int i=100; i>0; i = i-1) {
int imax;
if(c >= i*imax) {c = c - i*imax; break;}
}}}
Mini-Tute Solution
class ModuloCounter {
private int modulus;
private int increment;
private int counter;
public ModuloCounter(int increment, int modulus) {
this.increment = increment;
this.modulus
= modulus;
this.counter
= 0;
}
public void increment() {
counter = (counter+increment) % modulus;
}
public int get() {
return counter;
}
}
No javadoc for
brevity but
should be
there.
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Data Abstraction/Classes
2
Ch 1,2
quote
Simplicity rules!
me
contents
Defensive programming
Encapsulation
Implementation genomic sequence class
Implementation test class
defensive programming
anticipate modifications/usage/bugs that would
cause the code to break
What's a
potential
problem?
int i = 0;
while(i != 100) {
// do something
i++;
}
techniques:
design by contract
(assertions)
exceptions
HMB
//
//
//
//
post- & preconditions
app still "crashes"
you have to handle them
"Hat of the Mean Bastard"
encapsulation
hide internal variables, methods and
implementation from outside
=> provide stable interface/specification
=> interns can be changed without
affecting depending code
=> functionality can be extended/modified easily
keep interface as general/small as possible
access qualifiers
Access for variables and methods
public: from the outside
protected: only from derived class
private: only within the class
genomic sequence class
Specification
DNA: 4 letter alphabet (A,C,T,G)
circular genomes exist (bacteria)
biological coordinates start at 1
extraction of subsequences
immutable (or maybe not)
much, much more ...
Test
toy implementation of JUnit
Mini-Tute
class MyLittleMathLib {
public double frac(double x, double y) {
return x/y;
}
public boolean equals(double x, double y) {
return x==y;
}
public int fact(int n) {
if(n==0) return 1;
return n*fact(n-1);
}
}
Make it
more
robust!
Mini-Tute Solution
class MyLittleMathLib {
private static double EPS = 1e-10;
public double frac(double x, double y) {
if(Math.abs(y) < EPS) return Double.Nan;
return x/y;
}
public boolean equals(double x, double y) {
return Math.abs(x-y) < EPS;
}
public long fact(int n) {
if(n>50) throw new IllegalArgumentException(“...”);
long prod = 1;
for(int i=2;i<=n; i++) prod *= i;
return prod
}
}
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Data Abstraction/Classes
3
Ch 3,4
quote
It's OK to figure out murder mysteries,
but you shouldn't need to figure out code.
You should be able to read it.
Steve McConnell
contents
Static methods and variables
Final classes, methods and variables
Sequence class continued
Alphabet
Alphabet Factory
JUnit
Static
Distinguishes between class and instance variables
Static variable is class specific
Static method can access static variables directly but
not others
Used for constants, instance IDs, Factories,
Singletons, ...
See also Math package
http://java.sun.com/docs/books/tutorial/java/javaOO/cla
ssvars.html
Final
variables: a final variable can be set once and only once.
Essentially a constant.
Instance vars: a final instance var can be set only once
methods: a final method cannot be overridden nor
hidden
classes: a final class cannot be extended
a final reference does not protect the referenced object
against modification!
final can increase efficiency (allows optimization)
http://renaud.waldura.com/doc/java/final-keyword.shtml
Sequence class cont...
Alphabet
AlphabetFactory
Mini-Tute
/**
* Lousy implementation that prints out
* names of account holders and current amounts.
* @param names Array of account holder names
* @param amounts Array of account amounts
**/
public void printAccounts(String[] names, Integer[] amounts) {
for(int i=0; i<names.length; i++)
System.out.println(names[i]+": "+amounts[i]);
}
it works
but we
can do
better!
Mini-Tute Solution better but not good enough
class Account {
public String name;
public int
amount;
}
one array
instead of two
is better but
...
good naming!
"accountsArray
" would be
sub-optimal!
public void printAccounts(Account[] accounts) {
for(int i; i<accounts.length; i++) {
Account account = accounts[i];
System.out.println(account.name+": "+account.amount);
}
}
Mini-Tute Solution - much better
class Account {
private String name;
private int
amount;
...
// constructor and other stuff here
public String toString() {
return name+": "+amount;
}
}
class Accounts implements Iterable {
private ArrayList<Account> accounts;
... // getter, setter and other stuff here
}
public void print(Accounts accounts) {
for(Account account : accounts)
System.out.println(account);
}
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Data Abstraction/Classes
4
Ch 3,4
quote
Adding manpower to a late software project
makes it later.
Brooks Law
contents
Design by contract
Design Patterns
Factory
Singleton
Sneak peak inheritance
JUnit
Sequence class continued
design by contract - DbC
Contract between client and server
Precise description of interface specification
Precondition: What is expected?
Postcondition: What is guaranteed?
Invariant: What is maintained?
DbC frameworks
Python: PyDBC
Scheme: PLT Scheme extension
Java: C4J, jContractor, Modern Jass, ...
Integral part of Eiffel
DbC example
public class MyMath {
private static double epsilon = 1e-10; // numerical accuracy
public static void setEpsilon(double epsilon) {
this.epsilon = epsilon;
a tiny bit
}
artificial!
...
/**
* @requires n >= 0 && n < 50
* @ensures this.factorial(n) > 0
Contract
* @invariant eps
**/
public static double factorial(int n) {
if(n==0) return 1;
return n*factorial(n-1);
artificial too
}
}
DbC: javadoc & implementation
javadoc: only words...
@requires: precondition
@ensures: postcondition
@invariant: class invariants
implementation…
if statements
assertions
exceptions
DbC frameworks
(=>
(=>
(=>
(=>
clutters code)
kills app)
preferred)
recommended)
C4J example
@ContractReference(contractClassName = "CalculatorContract")
public class Calculator {
public double divide(double x, double y) {
return x / y;
}
}
public class CalculatorContract {
public void classInvariant() {
// Nothing to do here
}
public void pre_divide(double x, double y) {
assert y != 0;
}
}
design patterns
… so I implemented a Factory method to create Singleton
instances and used a Façade to …
Recipes for reoccurring problems in software design
Gang of Four (GoF):
E. Gamma, R. Helm, R. Johnson, and J. Vlissides
Design Patterns: Elements of Reusable Object-Oriented
Software, 1995
GoF describe 23 patterns => Creational, structural
and behavioral patterns
http://en.wikipedia.org/wiki/Design_Patterns
factory method
to create objects...
public class AlphabetFactory {
static final Alphabet alphabetDNA = new Alphabet("ACTG");
static final Alphabet alphabetRNA = new Alphabet("ACUG");
public static Alphabet create(String alphabetName) {
if(alphabetName.equals("DNA"))
return alphabetDNA;
if(alphabetName.equals("RNA"))
return alphabetRNA;
throw new IllegalArgumentException(
"Invalid alphabet: "+alphabetName);
}
}
singleton
public class Singleton {
private static Singleton instance;
private Singleton() {...}
public static Singleton getInstance() {
if(instance == null)
instance = new Singleton();
return instance;
}
}
there is always only one instance
private constructor
static instance
Singleton singleton = Singleton.getInstance();
preview inheritance
Generalization: is-a
relationship
derived class inherits
attributes/methods from
base class
JUnit
Greatest invention since
Sliced Bread!
Testing framework for
automated tests to
test the code
document spec
find bugs quickly
allow refactoring
Mini-Tute
import static java.lang.Double.NaN;
public double divide(double x, double y) {
double result;
if(y == 0) {
result = NaN;
That's an
}
easy one!
else {
Simplify!
result = x/y;
}
return result;
}
Mini-Tute Solution
import static java.lang.Math.abs;
import static java.lang.Double.*;
public double divide(double x, double y) {
return abs(y)<=MIN_VALUE ? NaN : x/y;
}
import static java.lang.Double.*;
public double divide(double x, double y) {
try { return x/y; }
catch(ArithmeticException ae) { return Nan; }
}
...or with
exceptions
!
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Specification & Testing
4
Ch 5,6
quote
Any fool can write code that a computer can
understand. Good programmers write code
that humans can understand.
Martin Fowler
contents
KISS or MISS
Design by contract - some advice
Assertions - quickly
Testing - a bit more
KISS or MISS
That simply
means
KISS!
The most consequential impediment to
writing correct, maintainable code is
complexity.
Nino & Hosch, Chapter 5,
Programming and object oriented design using Java
KISS: Keep it Simple, Stupid!
MISS: Make it Simple, Stupid!
Design by Contract
Recap:
@require: precondition: What is expected?
@ensure: postcondition: What is guaranteed?
class invariant: What is maintained?
my suggestions: in real life
if DbC then it needs to be automated, e.g. C4J
use exceptions for preconditions in public methods
use assertions only for postconditions/invariants
prefer functionality to assertions/exceptions
assertions: enable for development, disable in
release
assertion
assert bool_expr;
assert bool_expr : error_str;
assert y!=0 : "Division by zero";
must be enabled
can be caught and re-thrown but exception is then the better
solution
try {
assert y!=0: "Division by zero";
}
catch( AssertionError ae ) {
// exception handler
System.out.println("Gotcha!");
throw ae;
// re-throw
}
assertions - enable
Assertions must be
enabled
VM argument "-ea"
Eclipse: Run Dialog
testing
Functional testing
black box test
tests behavior of entire system
use cases
frequently not automated :-(
low coverage :-(
performed by test department
Unit testing
white box test
tests individual methods
test driven development
automated :-)
high coverage :-)
implemented by developer
IMHO: Unit tests are more important than functional tests
unit tests
test now or never
required coverage depends on application:
(nuclear power station <-> personal stamp collection
management system)
automated tests <= JUnit testing frameworks
test border cases
test examples from equivalency groups
test only within current context
the more complex the method the more extensive the
test
full coverage is usually impossible
you can test for invalid input => Exception
write simple methods and testing is easy
JUnit 3 and 4
New in JUnit 4
no inheritance from junit.framework.TestCase required
anymore
uses annotation:
@Test
Parametric tests:
@Parameters
Exception tests:
Timeout tests
Ignore tests:
@Test(expected=IndexOutOfBoundsException.class)
@Test(timeout=1)
@Ignore("not ready yet")
and more ...
JUnit 4 & Eclipse
JUnit test case wizard
Run dialog
Mini-Tute
a
b
c
1
2
3
CyclicString cs =
new CyclicString("abc");
cs.charAt(1); // -> 'a'
cs.charAt(0); // -> 'c'
cs.charAt(2); // -> 'b'
cs.charAt(3); // -> 'c'
cs.charAt(4); // -> 'a'
public class CyclicString {
private String string;
CyclicString(String string) {
this.string = string;
}
public char charAt(int index) {
...
}
}
Implement
this!
Mini-Tute Solution
public char charAt(int index) {
int length = string.length();
if(index < 1)
index += length;
if(index > length) index -= length;
return string.charAt(index-1);
}
public char charAt(int index) {
int length = string.length();
index = (index-1) % length;
if(index < 0) index += length;
return string.charAt(index);
}
Doesn’t
deal with
multiple
wraps!
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Design
5
Ch 7,8,16
quote
Programming can be fun, so can cryptography;
however they should not be combined.
Kreitzberg and Shneiderman
contents
UML
Stream based IO
ArrayList & HashSet
Sequence class continued … maybe
Mini tute
UML
Unified Modeling Language (1996)
J. Rumbaugh, G. Booch, I. Jacobson
"... is a graphical language for visualizing,
specifying, constructing, and documenting the artifacts
of a software-intensive system."
UML models can be automatically transformed into Java
developed to describe object oriented systems
supports three different views
Behavior
Structure
Dynamics
13 diagrams
UML - diagram types
http://en.wikipedia.org/wiki/Unified_Modeling_Language
UML - use case diagram
http://dn.codegear.com/article/31863
UML - class diagram
http://dn.codegear.com/article/31863
UML - sequence diagram
http://dn.codegear.com/article/31863
Input/Output streams
Input
stream
Output
stream
http://java.sun.com/docs/books/tutorial/essential/io/streams.html
Stream based IO
Tutorial: http://java.sun.com/docs/books/tutorial/essential/io/
Byte streams: raw binary data
Character streams: characters
Buffered streams: optimized streaming
Scanning and formatting: Scanner, format
IO from command line: stdin, stdout, stderr
Data streams: primitive data types and strings
Object streams: serialization
File readers and writers
File Output
try {
BufferedWriter out =
new BufferedWriter(
new FileWriter("example.txt"));
out.write("Mary Poppins\n");
out.flush();
// flush Mary
out.write("supercalifragilistic\n");
out.close();
}
catch (IOException ioe) {
// do something
}
http://www.exampledepot.com/egs/java.io/WriteToFile.html?l=rel
File Input
try {
BufferedReader in =
new BufferedReader(
new FileReader("example.txt"));
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
in.close();
}
catch (IOException ioe) {
// do something
}
http://www.exampledepot.com/egs/java.io/ReadLinesFromFile.html
ArrayList<Object>
import java.util.ArrayList;
Generics
ArrayList<String> names = new ArrayList<String>();
names.add("Calvin");
names.add("Hobbes");
names.add("Susi");
Can't be a
primitive
type!
System.out.println(names.get(1));
// print Hobbes
for(String name : names)
System.out.println(name);
// print all
names.clear();
// all gone
http://www.exampledepot.com/egs/java.io/ReadLinesFromFile.html
HashSet<Object>
Generics
again
import java.util.HashSet;
HashSet<String> nameSet = new HashSet<String>();
nameSet.add("Calvin");
nameSet.add("Hobbes");
nameSet.add("Hobbes");
// duplicate!
System.out.println(nameSet.size());
// -> 2
if(nameSet.contains("Susi")
System.out.println("Susi is there");
for(String name : nameSet)
// print "Calvin","Hobbes"
System.out.println(name);
http://www.exampledepot.com/egs/java.io/ReadLinesFromFile.html
Mini-Tute
public class NameTable {
Mutable or
private String[] names;
immutable?
public NameTable(int size) {
this.names = new String[size];
}
public String get(int index) {return names[index];}
public String set(int index, String name) {names[index]=name;}
public int size() {return names.length;}
public (static) copy(NameTable nameTable) {
Bit
NameTable newTable = new NameTable(nameTable.size());
for(int i=0; i<nameTable.size(); i++)
newTable.set(nameTable.get(i));
Find a better
return newTable;
}
solution!
}
NameTable newTable = (new NameTable(0)).copy(otherTable);
NameTable newTable = NameTable.copy(otherTable);
ugly!
Mini-Tute Solution 1
public class NameTable {
private String[] names;
public NameTable(int size) {
this.names = new String[size];
}
public NameTable(NameTable that) {
Copy
this(that.size);
for(int i=0; i<size(); i++)
this.names[i] = that.names[i];
}
public String get(int index) {...}
public String set(int index, String name) {...}
public int size() {...}
}
NameTable newTable = new NameTable(otherTable);
constructor
What if we want
to have an
immutable one?!
Mini-Tute Solution 2
public class NameTable {
private String[] names;
public NameTable(String[] names) {
this.names = new String[names.length];
for(int i=0; i<names.length; i++)
this.names[i] = names[i];
}
public NameTable(NameTable that) {
this(that.names);
}
public String get(int index) {...}
// no more set() -> immutable
public int size() {...}
}
What about:
this.names = that.names
No loop: is that cool?
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Design
5
Ch 7,8
quote
Optimism is an occupational hazard of
programming: feedback is the treatment.
Kent Bent
contents
Software life cycle
Top-down & bottom-up
Ends of the spectrum
Waterfall Model
Extreme Programming
Agile methods
Intro Generics
software design
Software life cycle
http://www.acerimmeronline.com/vb/html/software_development.html
top-down & bottom-up
Top-Down
starts with skeleton code
stepwise refinement
integration of components usually simple
extensive specification required
lots of mock code required
unit-testing more difficult
less likely to produce reusable components
less likely to produce superfluous code
Bottom-Up
implement basic functions first (libraries)
typical for object oriented programming
more agile
leads to reusable components
easier to maintain (components are less interlinked)
integration/interface problems are more likely
danger of over-engineering
Usually a
mix of
both!
I recommend
to favor
bottom-up
Waterfall model
you can't go
back!
Only for tiny
problems or
as high level
guideline.
http://www.integrationarchitect.org/wp-content/uploads/2008/02/waterfall_model1.png
Waterfall Model
purely sequential (no feedback loops)
very extensive planning and specification
comprehensive documentation
simple to use
requires highly accurate analysis
requires almost perfect design
changes are not supported
works only for very small or very stable problems
outdated!
Waterfall with feedback
Still assumes
you are
finished when
you are
finished...
http://www.wittmannclan.de/ptr/cs/slcycles.html
Spiral model
What you deliver
is not what the
customer wants!
... and here we go
again...
More realistic and
successful!
http://www.outsource2india.com/software/process.asp
Extreme Programming
User stories
on-site customer
pair programming
small, frequent releases
1-3 weeks iterations
test driven (unit tests)
constant refactoring
simplicity
http://www.extremeprogramming.org
XP - Process
http://www.vtt.fi/inf/pdf/publications/2002/P478.pdf
Agile Methods
incremental with rapid cycles
(weeks)
cooperative
(customer and developer working together)
straightforward
(methods is easy to learn/apply/modify)
adaptive
(able to change quickly)
http://www.vtt.fi/inf/pdf/publications/2002/P478.pdf
Comparison
There are book-shelves of
literature on software
methodology!
•Scrum
•Extreme Programming
•Lean Software Development
•Unified Process
•Rational Unified Process
•Dynamic Systems Development Method
•Prince2
•Microsoft Solutions Framework
•Capability Maturity Model Integration
•Feature Driven Development
•Crystal
•...
http://www.vtt.fi/inf/pdf/publications/2002/P478.pdf
Generics - toy example
@SuppressWarnings("unchecked")
// extremly ugly!
public class Stack<E> {
private E[] stack = (E[])new Object[1000]; // ugly but needed
private int n = 0;
public void push(E element) {
stack[n++] = element;
}
public E pop() {
return stack[--n];
}
}
Stack<String> stack = new Stack<String>();
stack.push("foo");
String elem = stack.pop();
Error
checking and
other stuff is
missing!
Mini-Tute
Which of the following conditional statements is true?
"abc" == "abc"
"abc".equals("abc")
"abc".equals(new String("abc"))
"abc" == new String("abc")
"abc" == (new String("abc")).intern()
Easy, apart
from this
one.
Guess...
Mini-Tute Solution
"abc" == "abc"
TRUE
"abc".equals("abc")
TRUE
"abc".equals(new String("abc"))
TRUE
"abc" == new String("abc")
FALSE
"abc" == (new String("abc")).intern()
TRUE
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Interfaces
6
Ch 9
quote
There are two ways of constructing a software design:
One way is to make it so simple that there are obviously
no deficiencies, and the other way is to make it so
complicated that there are no obvious deficiencies.
The first method is far more difficult.
C.A.R Hoare
contents
interfaces
subtyping
strategy pattern
interfaces
interface
only specifies abstract methods (and constants)
no implementation
cannot be instantiated
introduces layer of abstraction
substitute for multiple inheritance
(avoids diamond problem)
public interface ISearch {
public final int NOT_FOUND = -1;
public int search(String str);
public int searchNext(int oldPos, String str);
}
interface implementation
public class EditBox implements ISearch {
private String text;
public int search(String str) {
return text.indexOf(str);
}
public int searchNext(int oldPos, String str) {
return text.indexOf(str, oldPos);
}
public int length() {
// not from interface!
return text.length();
}
}
subtype
EditBox is subtype of ISearch
ISearch
EditBox
A
B
subtype is more powerful or at least as
powerful as the supertype
(added functionality)
subtype inherits all the non-private methods
of the supertype
signatures of methods must match
subtype can have (and usually has)
additional methods
IF B is a subtype of A
THEN B can be used wherever A can be used!
subtyping - examples
B is subtype of A
class A {…}
class B extends A {…}
A
B≥A
B
A
B
A
B
a
b
a
b
=
=
=
=
new
new
new
new
A()
B()
B()
A()
x
interface A {…}
class B implements A {…}
interface A {…}
interface B extends A {…}
void foo(A a) {…}
=> foo(new A())
=> foo(new B())
void foo(B b) {…}
=> foo(new A()) x
=> foo(new B())
dynamic & static type
A
A foo(A a) {
return a
}
A
A
B
B
a
a
b
b
=
=
=
=
foo(new A())
foo(new B())
foo(new B())
(B)foo(new B())
Need to cast though!
x
B
Static type mismatch!
Dynamic types match!
dynamic type - bad example!
class AlphabetDNA {…}
class AlphabetAA {…}
not related
urgs!
class AlphabetFactory {
public Object create(String name) {
if(name.equals(“AA”)
return new AlphabetAA();
if(name.equals(“DNA”)
return new AlphabetDNA();
}
}
cast required!
possible runtime error!
Alphabet alphabet = (Alphabet)AlphabetFactory.create("DNA");
dynamic type - good example
interface Alphabet {…}
class AlphabetDNA implements Alphabet {…}
class AlphabetAA implements Alphabet {…}
super class
phew, better
class AlphabetFactory {
public Alphabet create(String name) {
if(name.equals(“AA”)
return new AlphabetAA();
if(name.equals(“DNA”)
return new AlphabetDNA();
}
}
no casting, save!
Alphabet alphabet = AlphabetFactory.create("DNA");
dynamic/duck vs. static typing
Python: What does
it do?
Java: What does it
do?
def add(a,b):
return a+b
public int add(int a, int b) {
return a+b;
}
add(1,2) # 3
add('a','b') # 'ab'
add([1],[2]) # [1,2]
public String add(String a, String b)
add('1',2)
public Tree add(Tree a, Tree b)
add('1',2);
runtime error :(
compile time error :)
def add(a:Int, b:int) = a+b
Scala: Type inference
comparable<T>
public interface Comparable<T> {
public int compareTo(T o);
}
compare returns
• a negative value if this < o
• zero if this equals o
• a positive value if this > o
java.lang
Collections.sort - comparable
Collections.sort(List<T> list)
ArrayList<Students> students = new ArrayList<Students>();
Collections.sort(students);
class Student implements Comparable<Student> {
private String name;
private int age;
public int compareTo(Student that) {
return this.name.compareTo(that.name);
}
}
java.util
comparator<T>
public interface Comparator<T> {
public int compare(T o1, T o2);
public boolean equals(Object obj);
}
compare returns
• a negative value if o1 < o2
• zero if o1 equals o2
• a positive value if o1 > o2
usually no need to override equals()
java.util
Write your own!
Collections.sort - comparator
Collections.sort(List<T> list, Comparator<? super T> c)
ArrayList<Students> students = new ArrayList<Students>();
Collections.sort(students, new NameComparator());
Collections.sort(students, new AgeComparator());
class NameComparator implements Comparator<Student> {
public int compare(Student s1, Student s2) {
return s1.name.compareTo(s2.name);
}
}
class AgeComparator implements Comparator<Student> {
public int compare(Student s1, Student s2) {
return s1.age - s2.age;
}
}
java.util
anonymous class
ArrayList<String> strings = new ArrayList<String>();
// sort according to string length
Collections.sort(strings,
new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.length() - s2.length();
}
}
);
strategy pattern
strategy pattern - UML
strategy pattern - skeleton
interface ISpellChecker {
class SpellChecker {
public void run(String text);
private ISpellChecker spellChecker; }
public void setSpellChecker(ISpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
public void run(String text) {
spellChecker.run(text);
}
}
class CheckEnglish implements ISpellChecker {
public void run(String text) {...}
}
class CheckGerman implements ISpellChecker {
public void run(String text) {...}
}
mini tutorial
Mini-Tute
reduce: 1+2+3+4 = 10
1*2*3*4 = 24
public int reduce(char op, int[] data) {
Ugly &
int result = data[0];
Inefficient!
for(int i=1; i<data.length; i++) {
Write a better
if(ch=='+') result = result+data[i];
version!
if(ch=='-') result = result-data[i];
if(ch=='*') result = result*data[i];
if(ch=='/') if(data[i]!=0) result = result/data[i];
}
return result;
}
Mini-Tute Solution
public interface IOperator {
public int calc(int a, int b);
}
Operator interface
public class OperatorDivision implements IOperator {
public int calc(int a, int b) {
Operator implementation:
return b==0 ? 1 : a/b;
handles special case nicely
}
}
public int reduce(IOperator op, int[] data) {
int result = data[0]
for(int i=1; i<data.length; i++)
Guess what!
result = op.calc(result, data[i])
Strategy pattern!
return result;
}
Mini-Tute Example
int[] data = new int[]{1,2,3,4};
reduce(new OperatorPlus(), data);
reduce(new OperatorMinus(), data);
anonymous class
reduce(new IOperator() {
public int calc(int a, int b) {
return a % b;
// modulo
}});
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Interfaces
6
Ch 9
quote
Inside every large program, there is a small
program trying to get out.
C.A.R. Hoare
contents
static casting
autoboxing
multiple inheritance
iterable interface
instanceof
abstract classes
observer pattern
model-view-controller architecture
static casting
up-casting:
down-casting:
auto-casting:
(double)314
(int)3.14
10*3.14
double d = 3.14;
int i = (int)d;
int min = ...
int max = ...
double progress = i/(double)(max-min);
double progress = i/(max-min);
usuall
y
wrong!
Autoboxing
nope!
ArrayList<int> numbers = new ArrayList<int>();
ArrayList<Integer> numbers = new ArrayList<Integer>();
without
for(int i=0; i<100; i++)
numbers.add(new Integer(i));
“auto”boxin
int sum = 0;
g
for(Integer number : numbers)
sum += number.intValue()*number.intValue();
for(int i=0; i<100; i++)
numbers.add(i);
int sum = 0;
for(Integer number : numbers)
sum += number*number;
with
autoboxin
g
instanceof
checks the type of an object
try to avoid – it’s BAD
if possible use polymorphism instead
String name(Object o) {
if(o instanceof A)
return "is A";
if(o instanceof B)
return "is B";
}
ugly: run-time errors,
inefficient, error prone
interface INamed {
String name();
}
String name(INamed o) {
return o.name();
}
elegant: compile-time errors,
efficient, robust
"multiple" inheritance
interface
extends
interface
class
extends
interface
interface
implements
class
class
class
class
class
extends
class
interface
Iterable<T> interface
Implementing this interface allows an object to be the target of the "foreach" statement.
Iterable set of
public class Students implements Iterable<Student> {
private Set<Student> set = new HashSet<Student>();
unique students
...
public Iterator<Student> iterator() {
implementation
return set.iterator();
Iterable interface
}
}
Students students = new Students();
for(Student student : students)
System.out.println(student.name):
foreach loop uses
Iterable interface
abstract classes
indicated by keyword "abstract"
partial implementation
cannot be instantiated
between an instantiable class and an interface
interface methods are implicitly abstract
AbstractDrawable
public abstract class AbstractDrawable {
private Position position = new Position(0,0);
public void moveTo(Position position) {
this.position.set(position);
}
Circle
public abstract void draw();
}
public class Point extends AbstractDrawable {
public void draw() {};
}
http://java.sun.com/docs/books/tutorial/java/IandI/abstract.html
Point
example ArrayList
Marker interfaces: no spec. of methods
Serializable, RandomAccess => instanceof
// good practice
List<String> list = new ArrayList<String>();
example HashSet
// good practice
Set<String> set = new HashSet<String>();
oberver pattern - UML
event handling
user interfaces
Model-view-controller architecture
one to many relationship
Java
Observer interface
Observable class
Model-View-Controller
view selection
View
state change
state query
user gestures
notify change
Controller
Model
e.g. Powerpoint
Controller: Menus
Views: Normal view, Print view, Slide show, Slide sorter, ...
Model: List of graphical objects plus more ...
Mini-Tute
public class VectorInt {
protected int[] data;
public VectorInt(int n) { data = new int[n]; }
}
Someone didn't
switch on
his/her brain!
public class VectorDouble {
protected double[] elems;
public VectorDouble(int size) { elems = new double[size]; }
}
Does it
public class VectorMath {
work?
public static product(Object vector1, Object vector2) {
double sum = 0.0;
if(vector1 instanceof VectorInt)
for(int eindex=0; eindex < ((VectorInt)vector1).data.length; eindex++)
sum += ((VectorInt)vector1).data[eindex]*
((VectorInt)vector2).data[eindex];
if(vector1 instanceof VectorDouble )
for(int eindex=0; eindex < ((VectorDouble)vector1).data.length; eindex++)
sum += ((VectorDouble)vector1).elems[eindex]*
((VectorDouble)vector2).elems[eindex];
This is simply
return sum;
DISGUSTING
}
!
}
Mini-Tute Questions
what's good about that code?
nothing ...
alright, next to nothing. At least there are classes.
what's bad about that code?
1.
different names of instance vars in vector classes
(data vs. elems)
2. instance variables in vector classes are not encapsulated
3. direct access to vector memory
4. Objects as parameters for product()
5. usage of instanceof
6. no error checking for proper input types
(e.g. product(new Blah(), new Bang()) returns 0)
7. "eindex" as an index variable in loop
8. code duplication (two for loops)
9. forced casting to vector type
10. ...
Mini-Tute Solution
public interface IVector {
public double get(int index);
public int size();
}
Ppublic class VectorInt implements IVector {
private int[] data;
public VectorInt(int n) { data = new int[n]; }
public double get(int index) { return data[index]; }
public int size() { return data.length; }
}
public class VectorDouble implements IVector {
private double[] data;
public VectorDouble(int n) { data = new double[n]; }
... // same as for VectorInt
}
public class VectorMath {
public static product(IVector vector1, IVector vector2) {
double sum = 0.0;
for(int i=0; i < Math.min(vector1.size(),vector2.size()); i++)
sum += vector1.get(i)*vector2.get(i);
return sum;
}
}
Mini-Tute Solution 2
Generic
s
public class Vector<T> implements IVector {
private T[] data;
public VectorInt(int n) { data = (T[])new Object[n]; }
public double get(int index) { return data[index]; }
public int size() { return data.length; }
}
less code but
more memory
and a bit
slower.
IVector vector = new Vector<Integer>(100);
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Inheritance
7
Ch 10,11
quote
Prolific programmers contribute to certain
disaster.
Niklaus Wirth
contents
inheritance
equals()
hashCode()
HashTable<K,E>
inheritance
no inheritance for private attributes/methods
no inheritance for final classes or methods
no inheritance for constructors
derived class must call constructor of super class
(or default constructor of super class is called
automatically)
no multiple inheritance for classes
(only for interfaces)
transitive (C≥B≥A => C≥A)
http://java.sun.com/docs/books/tutorial/java/concepts/inheritance.html
class extension
B extends A
class A {
public void a() {...}
}
A
+a()
B≥A
B
+b()
class B extends A {
public void b() {...}
}
A a = new A()
=> a.a()
=> a.b() x
B b = new B()
=> b.b()
=> b.a()
A a = new B()
=> a.a()
=> a.b()
x
=> ((B)a).b()
class extension - access
Access level modifiers:
class A {
public
pub() {...}
protected pro() {...}
private
pri() {...}
}
class B extends A {
...
}
B b = new B()
=> b.pub()
=> b.pro()
=> b.pri() x
no way to protect a method in a
class and its derived classes!
Same for
class
attributes
You cannot extend
final classes!
final class C {
...
}
super duper
class A {
public A() {...}
}
class B extends A {
don't
public B(...) {
have too
super();
}
}
class A {
public A(p1, p2, ...) {
...
}
}
class B extends A {
public B(...) {
super(p1, p2, ...);
}
}
without super the default
constructor is called
if there is no default
constructor super(...) must
be called!
super(...) must be first line
in constructor of subclass
don't call overridable
methods in constructor
class A {
}
you
have
default
constructor
class B extends A {
public B(...) {
super();
don't
}
have too
}
constructor & overriding
constructors should not use overridable methods
use final to protect methods against overriding and classes against
extension
public class B extends A {
private int[] data;
public class A {
public A() {
init();
}
super()
public B(int n) {
// init data
data = new int[n];
init();
}
uh!
public void init() {
... // do something
}
public void init() {
for(int i=0; i<data.length; i++)
data[i] = 1;
}
}
public final void init() {
... // do something
}
Boom!
}
inheritance is transitive
A
+a()
B≥A
B
+b()
C≥B
C
+c()
=> C ≥ A
class A {
public void a() {...}
}
class B extends A {
public void b() {...}
}
class C extends B {
public void c() {...}
}
A.a()
B.a(), B.b()
C.a(), C.b(), C.c()
overloading
means multiple methods with the same name but different
parameter(s) (type, number)
different return type is not sufficient
overloading happens at compile time (static)
invocation depends on type
Doesn'
class PrintStream {
void print(int i);
void print(Object obj);
void print(String s);
class Nope {
int find();
String find();
}
print(42);
print(new Integer(42))
print("42")
void write(int b);
void write(byte[] buf, int off, int len);
}
t work!
overriding
method with same name and parameters but different
implementation in subclass
class A {
public int foo(int x) {
// do THIS
}
}
class A {
public int foo(int x) {
// do THIS
}
}
class B extends A {
public int foo(int x) {
// do THAT
}
Overridin
}
g
class B extends A {
public int foo(int x) {
super.foo(x); // do THIS
// and then do THAT
}
}
foo() from
super class!
overriding
overriding happens at run time (dynamic)
class A {
public void foo() {
// do THIS
}
}
A a = new A();
a.foo();
// A.foo()
class B extends A {
public void foo() {
// do THAT
}
}
((A)b).foo();
B b = new B();
B.foo();
// B.foo()
// B.foo()
A a = new B();
a.foo();
// B.foo()
equals
implemented in root class Object
determines whether some other Object is "equal to" this one
consistent: multiple invocations of x.equals(y) return same
value
reflexive: x.equals(x)
symmetric: x.equals(y) ==> y.equals(x)
transitive: x.equal(y) && y.equals(z) ==> x.equals(z)
null:
x.equals(null) == false
// implementation in Object
public boolean equals(Object o) {
return o == this;
}
equals - how to
implement equals for Object and not for a subtype
use the == operator to check if references are equal
use the instanceof operator to check for correct type
cast the argument to the correct type
check equality of significant fields
must be reflexive, symmetric, transitive, consistent
implement only for immutable objects
override hashCode
public boolean equals(Object o) {
if(o == this) return true;
if(o instanceof X) {
Only for
X x = (X)o;
efficiency!
return x.foo.equals(this.foo);
}
return false;
}
equals - example
public class Address {
private String street;
private int number;
public boolean equals(Object o) {
if(o == this) return true;
if(o instanceof Address) {
Address a = (Address)o;
return a.street.equals(this.street) &&
a.number == this.number;
}
return false;
}
}
hashCode
implemented in root class Object
must be overridden if equals() is overridden
must be consistent
if two objects are equal() they must have the same hash code
if two objects are NOT equal() they should have different hash
codes but need not
public class Address {
private String street;
private int number;
public int hashCode() {
return 17 + street.hashCode() + 37 * number;
}
}
Prime is
always cool!
HashMap
generic hash, see also HashSet and Hashtable in java.util
stores key-value pairs
uses hashCode()
public class AddressBook {
private HashMap<Address, String> map;
public AddressBook() {
map = new HashMap<Address, String>();
}
public add(Address address, String name) {
map.put(address, name);
}
public String getName(Address address) {
map.get(address);
}
}
Only works when
hashCode() is
overridden
Hash table
approx. constant access time
used in HashSet, HashMap, ...
maps integers to memory cells/bins
1
= mod 4
0
12
Collision
hashCode - how to
real good hash code implementation is tricky!
but a reasonably good approximation is:
start with some prime number, e.g. 17
convert each field compared in equals as follows
boolean
byte, char, short
long
double
Object
c
c
c
c
c
=
=
=
=
=
field ? 1 : 0
(int)field
(int)(field ^ (field >>> 32))
(int)Double.doubleToLongBits(field)
field.hashCode()
aggregate via result = 37 * result + c
public int hashCode() {
int result = 17;
result = 37 * result + c_1;
result = 37 * result + c_2;
...
result = 37 * result + c_n;
return result;
}
Mini-Tute
public class GeometricalThingy {
private int type, x1,y1,x2,y2;
... // Some constructors here
public String name() {
switch(type) {
case 0: return "Point";
case 1: return "Line";
case 2: return "Rectangle";
}
}
Another
piece of
disgustin
g code!
public int length() { // only for lines
if(type == 1) // Line
return sqrt(sqr(x1-x2)+sqr(y1-y2));
throw new UnsupportedOperationException("Length only for lines.");
}
public int area() {...} // only for rectangles
}
Mini-Tute Solution
public abstract class GeometricalThingy {
private String name;
protected int x, y;
protected GeometricalThingy(String name) { this.name=name; }
public String name() { return name; }
}
public class GeometricalPoint extends GeometricalThingy {
public GeometricalPoint() { super("Point"); }
}
public class GeometricalLine extends GeometricalThingy {
private int x2, y2;
public GeometricalLine() { super("Line"); }
public int length() {...}
}
public class GeometricalRectangle extends GeometricalThingy {
...
public int area() {...}
}
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Inheritance and Stuff
7
Ch 10, 11
quote
True refinement seeks simplicity.
Bruce Lee
contents
enums
inheritance & composition
adapter pattern
regular expressions
enums
// classic approach
public static final
public static final
public static final
Old style!
for
int
int
int
enums
SEQTYPE_DNA = 0
SEQTYPE_RNA = 1
SEQTYPE_AA = 2
not type safe (you can pass another int value)
no namespace (prefix, e.g. SEQTYPE_ is required)
no string representation
(print out of constant gives only number)
// enums, since 5.0
enum SeqType {DNA, RNA, AA}
there is a lot
more to it!
enums - more
enums can have data and/or methods assigned
enums are iterable (.values())
enums have string representation
public enum Operation {
PLUS
{ double eval(double
MINUS { double eval(double
TIMES { double eval(double
DIVIDE { double eval(double
x,
x,
x,
x,
double
double
double
double
y)
y)
y)
y)
{
{
{
{
return
return
return
return
x
x
x
x
// Do arithmetic op represented by this constant
abstract double eval(double x, double y);
}
http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html
+
*
/
y;
y;
y;
y;
}
}
}
}
},
},
},
};
enums - and more
public static void main(String args[]) {
double x = Double.parseDouble(args[0]);
double y = Double.parseDouble(args[1]);
for (Operation op : Operation.values())
System.out.printf("%f %s %f = %f\n", x, op, y, op.eval(x,y));
}
$ java Operation 4 2
4.000000 PLUS 2.000000 = 6.000000
4.000000 MINUS 2.000000 = 2.000000
4.000000 TIMES 2.000000 = 8.000000
4.000000 DIVIDE 2.000000 = 2.000000
inheritance & composition
inheritance skeleton
<- interface
IThingy
AbstractThingy
Dingus
Gimzo
Doodad
<- abstract class
Whatsis
<- classes
extension vs composition
extension: better code reuse, polymorphism, easy
composition: better encapsulation, higher flexibility, tricky
extension
composition
Superclass
is-a
ComposedClass
has-a
CoreClass
Subclass
=> prefer composition over extension (simpler, more robust)
adapter pattern
adapter pattern - UML
simply a wrapper
makes two interfaces/classes compatible to each other
adaptor contains instance of the class it wraps
used when extension of adaptee is not possible
or when there are many targets (=> avoid interface clutter)
adapter pattern - example
Target
public interface IVector {
public void set(int index, float value);
public float get(int index);
}
Client
public class LinAlgebra {
public static double product(IVector v1, IVector v2);
}
MyVector implements IVector
would not work! Why?
public class MyVector {
public void set(double value, int index);
public double get(int index);
Adapter
}
public class VectorAdapter implements IVector {
private MyVector myVector;
Adaptee
public void set(int index, float value) {
myVector.set(value, index);
}
public float get(int index) {
return (float)myVector.get(index);
}
}
regular expressions
Reg(ular)?\s+Ex(pres{2}ions)?
intro
succinct syntax to describe string patterns:
colou?r(ed|s)? -> color, colour, colors, coloured, ...
not necessarily very readable:
\d\d?[\.\-]\d\d?[\.\-]\d\d(\d\d)?
Ken Thompson, QED editor, 1966
natively in Perl, Ruby, ...
as library in Python, Java, ...
java.util.regex
http://java.sun.com/docs/books/tutorial/essen
tial/regex/index.html
Regex - basics
abc
a|b
a*
a+
a?
a{2,3}
[abc]
[^abc]
[a-zA-Z]
(ab)|b
.
(.)\1
->
->
->
->
->
->
->
->
->
->
->
->
abc
a, b
Ø, a, aa, aaa, ...
a, aa, aaa, ...
Ø, a
aa, aaa
a, b, c
not a, b, c
a..z, A..Z
ab, b
matches every letter
matches all pairs
NFA
Nondeterministic Finite Automaton (NFA)
backtracking
sub-expressions: ( )
back-references: \1
(a | b)*abb
abb, aabb, babb, ...
http://www.codeproject.com/KB/recipes/regex.aspx
Pattern & Matcher
Pattern: compiled regular expression
Matcher: Matching engine
Pattern pattern = Pattern.compile("a?b");
Matcher matcher = pattern.matcher("ababbb");
if(matcher.matches())
System.out.println("Matches entire string");
while(matcher.find()) {
String match = matcher.group();
int start
= matcher.start();
int end
= matcher.end();
}
regex in
Java
examples
public String reduceWhitespace(String str) {
Pattern pattern = Pattern.compile("\\s+");
Matcher matcher = pattern.matcher(str);
return matcher.replaceAll(" ");
}
"a
small test" => "a small test"
public List<String> extractTime(String str) {
List<String> matches = new ArrayList<String>();
Pattern pattern = Pattern.compile("(\\d?\\d:\\d\\d(pm|am)?)");
Matcher matcher = pattern.matcher(str);
while(matcher.find())
matches.add(matcher.group());
1:35pm
return matches;
12:01
}
...
special characters
character classes
predefinded char classes
boundary matchers
Mini-Tute
I
i()
A
C
B
c()
a()
ab()
b()
Mini-Tute Solution?
This isn't it!
I
interface
+i()
no implementation
A
B
C
+a()
+b()
+c()
+ab()
+ab()
+i()
+i()
+i()
Mini-Tute Solution
Most likely!
There are
others
AB
I
interface
+i()
no implementation
abstract
C
+ab()
+c()
+i()
+i()
A
B
+a()
+b()
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
code review
8
Ch 15,16
quote
Susie: You’d get a good grade without doing any work.
Calvin: So?
Susie: It’s wrong to get rewards you haven’t earned.
Calvin: I’ve never heard of anyone who couldn’t live with
that.
Calvin & Hobbes
contents
code review
code review
systematic examination of code
frequently as peer review
extremely time consuming
very useful to bring novices up to speed
also to achieve consistent coding style
highly effective in finding flaws/bugs
pair-programming is a light-weight alternative
http://en.wikipedia.org/wiki/Code_review
the solution
there were only three interesting pieces
of code, the rest was supposed to be
trivial and boring - "supposed to be"!
solution - contains
This was supposed to be
trivial and boring!
Can't get any simpler!
Read the java doc and
know what is available!
solution - record
Consistent,
straightforward variable
name. Don't invent
anything fancy
This was the only
slightly interesting part
solution - constructor NGramSet
intern() to store
identical n-grams
only once.
Was not expected!
solution - similarity
There are
alternatives but this
is straightforward
for-each loop
count/(double)keySet.size()
would have been shorter.
Maybe helper
variable for
keySet.size()
unit test for this
case is actually
missing
solution - find
-1 guarantees that there is
always one match.
bad naming. Should
have been: bestSigma
and bestRecord
you need to store the best
record AND the best similarity
code review / feedback
a lot of it ...
code review
one @param tag for
each parameter
comment
not aligned
wrong comment
variable names
should start in lower
case
new variable is not
necessary:
text = text.toLowerCase()
ngramSet would
have been better.
No "of"
brackets not
necessary but
save
code review
line comment (//)
would have been
sufficient
inconsistent
indentation. Tabs ?
explicit iterator not
necessary but good
name: Copy and Paste
is good!
double for a counter:
avoids casting but is,
hmm
casting since iter is not
typed but should have
upper case variable
name
if-else here is a bit complex. There is
a shorter way but good to take care
of keySet.size() == 0
code review
Why not just
"text".
"givenData" is
very generic.
inconsistent
indentation.
Tabs ?
line too long
Can be done
shorter
code review
upper case
variable
names
init with zero will cause prob. later
on. What if there is only matches
with sim = 0
bad choice for
variable name:
Meaning is wrong
can't work:
BestSimScore is
not updated
use line
comment
instead
code review
A state machine!
to split a string
into n-grams.
Way too complex
but fun ;-)
Otherwise
very nice
code!
And it works
too!
But the complexity is
dangerous. Nobody
would dare to touch
that code.
code review
Author of
the state
machine!
What SIGMA is
may not be
known!
double counter not
necessary since casting
later one.
typed iterator this time.
for-each loop would have
been better.
surrounding
brackets not
needed
casting here, therefore
not double intersect
needed
maybe "keySize"
instead
code review
indentation
no helper variable
required
The solution.
One line!
nGramSet has a
contains() method.
Overly complex
code review
Good doc, but parameter
description should start with
upper case letter.
Two loops are not need. There
is a substring() method
no var names
in uppercase
Test not needed. Just convert
every letter to lower case
Adding up strings is inefficient. Use
StringBuilder for this
code review
Too much
commenting!
Elegant solution!
A bit less efficient than
counting but good.
good names!
not needed.
NGramSet has size()
method
Without
comments more
readable
code review
non-ASCII
characters!
Copy and Paste
from Word/PDF
code duplication
code duplication
code review
I wouldn't use this here.
easier to store reference
to the record instead of
index
for-each loop over
records would be
simpler
good name but should
be "tempSet"
inefficient.
Similarity is
calculated twice
Too much commenting. Don't
write complete sentences
code review
oops!
unnecessary
comment
good comment
nice
intern() ensures that
identical n-grams are
stored only once.
code review
for-each over records is
good
here is a confusion.
Similarity is compared
against an index. Can't
work
Again, better to store best
record instead index of best
record
code review
Too many blank lines.
When more than ten
block in groups of at
least two
Nice comments but a
bit too much,
e.g. this is obvious
method does
nothing in case
of an error, hmm
no need to count
elements in a set:
nGramSet.size()
code review
start with
upper case
line too long
good
blocking of
lines
I wouldn't use that
many brackets but
it is okay
variable name "n"
is okay. Type
"double" is hmm
code review
not needed.
this can never
be null!
I wouldn't use
this here but it
is okay
indentation
unnecessary if-else. It is
a boolean expression
already. Return it
code review
start with
upper case
unnecessary counter.
recordArray.length does
the job.
code review
naming could
be better
close call. use >
later on and it
doesn't work
for-each loop
would be better
good line
blocking, good
comments
code review
loop var should be
declared within loop
line comments!
code review
don't start with
upper case
variable name
too long
redundant
comment
line comments
right above
line. Too many
blank lines
I don't think this
works. Operator
precedence!
one case would
have been
sufficient
code review
C/C++ style. In
Java define vars
where needed
line comments!
And indentation!
See how difficult it
is to decide what is
a new method and
what a code block
not needed
and again: for-each loop
and storing of record
reference would have
been better
code review
goes beyond spec. We
implement that latter
not needed
should be before the text
manipulations and is not needed
too long
code review
avoid describing "how"
(spec does that). Describe
"what" instead.
not needed
good
implementation
"record" would
have been
perfect
code review
not a good name. "i" is
for indices only
just "Records:\n" is
more efficient
StringBuilder style. Isn't
more efficient than "+"
for strings though
code review
not a good name.
comment
redundant
not needed
not needed
loop runs to
long
code review
takes longer to
read the comment
than the code
helper variable not
needed. Comment
would have done the
job
not "usually". Always!
code review
set? Should be ngram
conveys no information
if-else not needed
and confusing.
code review
missing param description
not needed
Looks like static method
call now. Use lower case
names for variables
code review
Python style
Way too complex! It
implies that it does
something complex but it
actually does not!
limbo?
limboo?
not needed
code review
Python style
maybe not. line comment there is not good
overly complex
code
C/C++ style
code review
character wise copy
of an immutable
string object into a
character array.
No needed and
overly complex
code review
storing all sigma for each
record in extra array and
then searching that array
for max sigma is
inefficient and overly
complex. If your code is
more than 10 lines long,
something is probably
wrong
code review
indentation and other
problems.
Don't mix tabs and
spaces. See how ugly it
gets. Use spaces only!
code review
Bracket position is C
style. Some Java people
do that too but I don't
recommend it.
(other problems too)
code review
Too many helper
variables. Use them only
if you need them.
(other problems too)
code review
15 lines where one is
needed. Overly
complex
code review
Python style
This is beautiful.
I like that!
Never thought
about that.
a bit too much
commenting for my
taste
not for the "test".
there is a reason
beyond that
code review
redundant
comment
see that!
dangerous!
no helper variable
required
code review
variable
names!
too much
commenting
variable
names!
see how
difficult that
becomes to
read!
summary
highly interesting and educating
common problems
ignoring available methods
=> overly complex or awkward code
overly complex code
=> slow, error prone, hard to maintain, difficult to read, ...
variable names
meaningful, consistent, < 10 chars
comments
meaningful, short, only when needed
indentation
follow language style, no tabs!
there were perfect solutions - it's possible!
philosophical
Code is to a programmer like a
chess board is to a chess player.
me
An experienced coder/player can see with one glance whether it makes sense,
what it does and whether there is a problem (for short pieces of code < 10 lines).
Use an awkward chess board with additional pieces and you don't see anything
anymore (follow the style, simple code).
For short code it takes longer to read the comment than to read the code
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Exceptions/Cloning
8
Ch 15,16
questions & quotes
The best way to get a project done faster is to
start sooner.
Jim Highsmith
contents
exceptions
cloning
exceptions
avoid code cluttering
replace if-statements and error return codes
separating error-handling code from "regular" code
allow to group or to differentiate errors
are automatically propagated
can be forwarded or re-thrown (chained)
can be checked or unchecked
you can make up your own
http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html
non-exception vs exception
http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html
exceptions - skeleton
try {
// something that
}
catch (Exception1 e)
// handle case 1
}
catch (Exception2 e)
// handle case 2
}
.
.
.
finally {
// always executed
}
can go boom!
throwing zone
{
{
catching zone
regardless what happens
exceptions - example
try {
reader = new FileReader(new File("MyFile.txt"));
...
}
catch (FileNotFoundException fnf) {
System.out.println("Can't find file!\n"+fnf);
}
catch (IOException ioe) {
System.out.println("Can't access file!\n"+ioe);
}
catch (Exception e) {
System.out.println("Something went wrong!\n"+e);
}
finally {
reader.close();
}
exception propagation
c
b
a
call stack
a(b(c()))
http://java.sun.com/docs/books/tutorial/essential/exceptions/definition.html
forward exceptions
pass exception handling to calling method
you have to declare checked exceptions
if there is no good way to deal with an exception
in the current context, leave it to the caller
public String readFile(String fname)
throws IOException, FileNotFoundException {
FileReader reader = new FileReader(new File(fname));
}
public String readFile(String fname) throws Exception {
FileReader reader = new FileReader(new File(fname));
}
When you
react the
same way in
any case
exceptions class hierarchy
Throwable
Error
Exception
checked
unchecked
RuntimeException
MyException
MyException
checked and unchecked
checked
try - catch required or must be listed in the procedure’s header
inherited from Exception
use when the exception can be expected during normal
execution, or is hard to avoid, or beyond the control of the
programmer
unchecked
try - catch not required, no need to be listed in the procedure’s
header
inherited from RuntimeException
use when the exception is unlikely to occur
Tendency is to go away from checked exceptions
chained exceptions
catch clause throws a new exception
useful to change exception type or to add information
frequently used to make checked exceptions unchecked,
which is a questionable practice!
try {
...
}
catch (Exception e) {
throw new OtherException("File problem!", e);
}
creating exceptions
Do you need an exception type that isn't represented by those
in the Java platform?
Would it help users if they could differentiate your exceptions
from those thrown by classes written by other vendors?
Does your code throw more than one related exception?
public class MyException extends Exception
public MyException() {
super();
}
public MyException(String s) {
super(s);
}
}
http://java.sun.com/docs/books/tutorial/essential/exceptions/creating.html
best practice
use checked exception if client can do something useful,
otherwise unchecked
use standard Java exceptions if you don't provide additional
information
use "finally" to clean up code (open files, database
connections, ...)
document exceptions (@throws) and test them (unit test)
do not use catch(Exception e) to avoid dealing with different
exception types. Catch specific exceptions if possible.
do not ignore/suppress exceptions
(though there is sleep and clone)
do not use exception for flow control
http://java.sun.com/docs/books/tutorial/essential/exceptions/creating.html
don't misuse
Exceptions only for exceptions!
public void frac(int[] array) {
for(int i=0; i<array.length; i++) {
try {
array[i] = 1/array[i];
}
catch(Exception e) {
array[i] = 0;
}
}
this is not
the way!
}
http://java.sun.com/docs/books/tutorial/essential/exceptions/creating.html
cloning
cloning
Sheep dolly2 = (Sheep)dolly1.clone();
purpose: create a copy (shallow/deep) of an object
default implementation creates a shallow copy
ugly:
clone() returns an instance of type Object,
checked CloneNotSupportedException(),
clone() is not supported by abstract classes e.g. List,
problems with final attributes,
copies transient attributes,
...
=> avoid clone and use copy constructors or
factory method instead.
cloning - example
public class Student implements Cloneable {
protected String name;
// immutable
protected Address address;
// mutable!
public Object clone() throws CloneNotSupportedException {
Student copy = (Student)super.clone();
copy.name
= name;
// no need to clone!
copy.address = (Address)address.clone();
deep copy
return copy;
}
}
copy constructor
public class Student {
protected String name;
protected Address address;
}
// immutable
// mutable!
no need to copy
public Student(Student student) {
immutables
this.name
= student.name;
this.address = new Address(student.address);
copy
}
constructor
Constructor that takes the same object it constructs as
parameter
code simpler than with cloning and no exceptions!
mini-tutorial
public abstract class AbstractRecordReader implements Iterable<Record> {
public Record find(String key) {
...
for (Record record : records)
...
}
Why an
abstract
super class?
}
public class RecordReader extends AbstractRecordReader {
...
records.add(new Record(text));
...
}
How do we get records
from here to
AbstractRecordReader?
mini-tutorial : intermezzo
for(Type element : Iterable<Type> )
recap for-each loop
What comes in here?
It is a reference to an
instance of a class that
has the Iterable<Type>
interface
works?
for(Record record : records)
YES, but we don't have it
for(Record record : AbstractRecordReader)
NO, not an instance
for(Record record : new RecordReader())
YES, but doesn't make sense
for(Record record : this)
YES, cool! But why
mini-tutorial : a solution
public abstract class AbstractRecordReader implements Iterable<Record> {
private Records records = new Records();
records in abstract class
public void add(Record record) {
records.add(record);
}
public Record find(String key) {
for (Record record : records) ...
}
public Iterator<Record> iterator() {
returns records.iterator();
}
add method to fill records
}
public class RecordReader extends AbstractRecordReader {
...
add(new Record(text));
...
}
Boring, a bit
complex, but works.
Alternatively: pass
records via
constructor
but as usual we
can do better!
mini-tutorial : solution
public abstract class AbstractRecordReader implements Iterable<Record> {
public Record find(String key) {
...
for (Record record : this)
...
}
this is it!
}
public class RecordReader extends AbstractRecordReader {
private Records records = new Records();
...
records.add(new Record(text));
...
public Iterator<Record> iterator() {
returns records.iterator();
}
}
Why/how
does it work?
Why is this
better than the
other stuff?
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Graphical User Interfaces
9
Ch 17
quote
The best performance improvement is the
transition from the nonworking state to the
working state.
John Ousterhout
contents
graphical user interfaces
history
examples
design rules
swing - first steps
Graphical User Interface (GUI)
A GUI provides graphical elements (Icons, Menus, Buttons, ...)
to perform actions.
easier to learn
less efficient than CLI in the long run
(CLI: Command Line Interface)
a lot more work to implement!
http://en.wikipedia.org/wiki/Graphical_user_interface
history
GUI - the beginning
http://www.catb.org/~esr/writings/taouu/html/ch02s05.html
1973, Xerox Alto
606*808
monochrome
display.
3-button mouse.
2.5 MB
removable disks.
16-bit microcode
programmable
CPU custom-built
from TTL chips.
A total address
space of 64 KB
GUI - the beginning 2
Alto (1973): Icons, Windows,
Scrollbars, Sliders
Star (1981): Desktop metaphor
30 years ago: Lousy progress !
http://www.catb.org/~esr/writings/taouu/html/ch02s05.html
GUI History
1973, Alto, Xerox PARC.
1990, Windows 3.0, Microsoft
1984, Macintosh, Apple
1999, GNOME 1.0
2001, Windows XP, Microsoft
1985, C64, Geos
1985, Windows 1.0, Microsoft
http://toastytech.com/guis/guitimeline.html
design
GUI Design
Designing a good GUI is an art* and
a crucial part for the success of a
system
(see iPhone)
There are design rules and style
guides
(to avoid the biggest mistakes)
There are even design patterns
In the end, it again boils down to
simplicity!
(http://www.cs.helsinki.fi/u/salaakso/patterns/)
*just like designing good software is an art.
UI - Guidelines?
Always use cute icons, buttons, and graphics. Everyone loves big red
hearts, pink bunnies, and yellow smily faces.
Don't be afraid to experiment with colors! Use as many as you can.
Your application should play fun sounds while operating to keep the users
entertained.
Never, ever, under any circumstance use the OS-native graphical controls or
widgets. Users get bored of the same old buttons, text boxes, and stuff.
Avoid including a preferences or options dialog. Instead, let the user use
the standard OS provided text editor or an editor of their choosing to edit
text configuration files. .
Users need time to think about what they are doing and get coffee. Your
application should always take at least 5 minutes to load even on the
fastest available computer.
To get the most screen space, force your application to always run
maximized.
Use the most exotic fonts you can find.
File browsing dialogs are not needed, users can easily remember and type
in long file paths.
If your program implements keyboard shortcuts be original and make them
completely different from any other applications.
...
http://toastytech.com/guis/uirant.html
bad examples 1
Popup dialog under
linux
Appears when closing
Inkscape and I always press
the wrong button
Occurred while
copying a file from
inside a zip archive
bad examples 2
Download your
driver!
Meaning?
Sure of
what?
bad examples 3
Part of a user manual.
Can you read it?!
A bit unorganized I
would say!
interface hall of shame
There are many more...
Have a look at the
Interface hall of shame
(http://homepage.mac.com/bradster/iarchitect/shame.htm)
conventions
conventions are arbitrary
but important
decimal system
angles
weights
...
Decimal Clock, French Revolution, 1793
follow the conventions of the domain you
develop software for!
10 design rules
Visibility of system status
Keep users informed about what is going on.
System should speak the users' language.
Support undo and redo.
Follow platform conventions.
Either eliminate error-prone conditions or check for them beforehand.
Minimize the user's memory load by making objects, actions, and options visible.
Allow users to tailor frequent actions (Shortcuts).
Dialogues should not contain information which is irrelevant or rarely needed.
Error messages in plain language, indicate the problem, suggest a solution.
Provide help, list concrete steps, be succinct.
Match between system and the real world
User control and freedom
Consistency and standards
Error prevention
Recognition rather than recall
Flexibility and efficiency of use
Aesthetic and minimalist design
Help users recognize, diagnose, and recover from errors
Help and documentation
http://www.useit.com/papers/heuristic/heuristic_list.html
swing
Swing
Swing:
Set of libraries to build graphical user interfaces
hundreds of classes!
complex
Demos:
c:\Program Files\Java\jdk\demo\jfc\
Tutorials:
http://java.sun.com/docs/books/tutorial/ui/index.html
http://java.sun.com/docs/books/tutorial/uiswing/start/inde
x.html
http://zetcode.com/tutorials/javaswingtutorial/
http://www.javabeginner.com/java-swing-tutorial.htm
HelloWorld
import javax.swing.*;
Hello World
public class HelloWorld extends JFrame {
public HelloWorld() {
add(new JLabel("Hello World"));
setSize(100, 100);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String args[]) {
new HelloWorld();
}
}
hierarchical structure
JFrame
JFrame
JPanel
JButton
containers
JPanel
JLabel
components
JButton
JLabel
mini - tutorial
mini - tutorial 1
What's
wrong
here?
Red color for an
okay operation
An erroneous operation
"completed
successfully"!
Should be check boxes
instead of radio buttons
and only two of them of
course.
Hard to read. Green for
deletion of a db!?
mini - tutorial 2
Too many tabs!
And a
few
more?
Terrible colors and shapes
Too unspecific!
I don't know what
to say!
Too much text
and setting up a
key mapping is
not an error
(wrong icon)!
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
User interfaces
9
Ch 17
quote
contents
Swing
Components
Containers
Event listeners
JTable
Survey
AWT/Swing & SWT/JFace
AWT (Abstract Window Toolkit)
Swing
Sun
sits on top of AWT
lightweight => not directly related to native peer
more comprehensive then AWT
"higher order" functions
SWT (Standard Widget Toolkit)
the beginning
heavyweight => rendered by native peer on specific platform
minimum common denominator
Used by Eclipse
closer to AWT then to Swing
faster, more native then Swing but less object oriented and
less support, documentation
JFace
Used by Eclipse
sits on top of SWT
"higher order" function
Eclipse
JFC
Java Foundation Classes
Abstract Window Toolkit (AWT)
Swing
Java2D
Look And Feel (LAF)
Internationalization
...
Swing class hierachy
http://www.javabeginner.com/java-swing-tutorial.htm
components - principle
component = class
Properties
Methods
Events
JButton
JButton button = new JButton("Cancel");
button.setForeground(Color.blue);
button.requestFocus();
button.addActionListener(new ActionListener...);
components - 1
Buttons
Combo boxes
Lists
Menus
Sliders
Text Fields
Labels
components - 2
Tool tips
Progress bars
Colour choosers
File choosers
Tables
Text
Trees
typical structure
JFrame
JFrame
JPanel
containers
JButton
JPanel
JLabel
components
JButton
JLabel
bottom up
Listener
Create:
Frame
Panel
Components
Listeners
Add:
JLabel
JButton
JPanel
listeners to components
components into panel
panel into frame
JFrame
layout manager
layout manager
A layout manager determines the size and position of the
components within a container
Components can provide size and alignment hints but a
container's layout manager has the final say
It is an object that implements the LayoutManager interface
and of course you can implement your own one
http://java.sun.com/docs/books/tutorial/uiswing/layout/visual.html
some layouts
BorderLayout
FlowLayout
CardLayout
NORTH
WEST
CENTER
EAST
Left to right,
One at a time
Top to bottom
SOUTH
GridLayout
GridBagLayout
JButton
null
none,
manual setting
of coordiantes
http://java.sun.com/docs/books/tutorial/uiswing/layout/visual.html
layout examples
http://java.sun.com/docs/books/tutorial/uiswing/layout/visual.html
aggregation of layouts
JButton
JButton
JTextArea
aggregation of layouts
JButton
JButton
JFrame
NORTH
JPanel: FlowLayout
JPanel: BorderLayout
CENTER
JTextArea
event listeners
event listener
register at an event source, e.g. JButton, JPanel, ...
event source has list of all registered listeners and
notifies about events, e.g. button pressed, mouse
moved, ...
Event
Source
register
register
notify
Listener_1
Listener_2
implementation listener
implement listener interface
application class
inner class
anonymous class
listener should return quickly
(runs in dispatch thread!)
app implements listener
public class MyApp implements ActionListener {
private int clickCounter;
public MyApp() {
...
JButton button = new JButton("Cancel");
button.addActionListener(this);
...
}
private void actionPerformed(ActionEvent e) {
clickCounter++;
}
}
inner listener class
public class MyApp {
private int clickCounter;
public MyApp() {
...
JButton button = new JButton("Cancel");
button.addActionListener(new MyListener());
...
}
private class MyListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
clickCounter++;
}
}
}
anonymous listener class
public class MyApp {
private int clickCounter;
public MyApp() {
...
JButton button = new JButton("Cancel");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
clickCounter++;
}});
...
}
}
containers
intermediate containers
Root pane
Layered pane
Content pane
Glass pane
Root pane
‘Invisibly’ attached to top-level container
Created by Swing when JFrame is created
Manages everything between top-level container and
components
Places menu bar and content pane in an instance of
JLayeredPane
layered pane
provides a third dimension for
positioning components (depth, or
Z order).
allows overlapping components
Adding a component to a layered
pane, depth is specified as an
integer.
Menu sits there
http://java.sun.com/docs/books/tutorial/uiswing/components/layeredpane.html
content pane
Usually a JPanel
Contains everything except
menu bar for most Swing
applications
JPanel panel = new JPanel();
panel.add(new JLabel("label"));
panel.add(...);
frame.setContentPane(panel);
glass pane
Not structured into components
event catching
painting
Used for ‘weird’ interface behavior,
rarely used.
http://www.java2s.com/Code/Java/Swing-JFC/DemonstrateuseofGlassPane.htm
JTable
JTable
How to use tables:
http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
Swing tables class diagram
JTable
+setModel
TableModel
AbstractTableModel
+getRowCount
+getColumnCount
+getValueAt
abstract methods
to implement
DefaultTableModel
+getDataVector
+setDataVector
uses Vector of
Vectors to store data
mini - tutorial
mini - tutorial 1
Too many
buttons
a lot of
redundancy
here!
no need for combo
boxes here
20 flags?!
What are they
good for?
Not a good
method to set
a clock
mini - tutorial 2
What is CR? Press M
to cancel?
What is cancel
button for?
I don't know
anymore what
I want!
Good idea but
bad realization.
A big nuisance!
Should be aligned
with left side and
in a table
Why not just
"yes" and "no"?
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Collections
10
Ch 12,(13),14
quote
Good judgment comes from experience,
and experience comes from bad judgment.
Frederick P. Brooks
contents
assignment 2
assignment 3 demo
collections
Lists
Sets
assignment 2
NGramSet
Only protected to be
testable. Should be private.
For a non-private method
String would have been the
better return type.
protected static StringBuilder convert(String text) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
char ch = Character.toLowerCase(text.charAt(i));
if ((ch < 'a' || ch > 'z') && (ch < '0' || ch > '9'))
ch = '_';
builder.append(ch);
Usage of regular expression is
}
possible here. Shorter code but
less efficient.
return builder;
}
NGramSet
protected NGramSet(String text, int n1, int n2) {
if (n1 > n2)
throw new IllegalArgumentException(
"n1 larger than n2!");
StringBuilder builder = convert(text);
for (int n = n1; n <= n2; n++)
for (int i = 0; i+n <= builder.length(); i++)
ngramSet.add(builder.substring(i, i + n).intern());
}
Works for StringBuilder. No
need to convert to String!
protected NGramSet(String text, int n) {
this(text, n, n);
}
Record
public class Record {
private String text;
private NGramSet ngramSet;
public Record(String text) {
this.text = text;
this.ngramSet = new NGramSet(text);
}
...
}
too easy...
AbstractRecordReader
public abstract class AbstractRecordReader implements Iterable<Record>
{
public Record find(String key) {
double bestSigma = -1.0;
Record bestRecord = null;
NGramSet keySet = new NGramSet(key);
we discussed this
already...
for (Record record : this) {
double sigma = record.ngramSet().similarity(keySet);
if (sigma > bestSigma) {
bestSigma = sigma;
bestRecord = record;
}
}
return bestRecord;
}
}
RecordReader
public RecordReader(Reader inputReader, String splitPattern)
throws IOException {
Pattern pattern = Pattern.compile(splitPattern);
BufferedReader reader = new BufferedReader(inputReader);
StringBuilder builder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null)
builder.append(line).append("\n");
for (String text : pattern.split(builder))
records.add(new Record(text.trim()));
reader.close();
}
readLine kills \n.
We have to add it.
again, no need to
convert to string.
RecordReader
public RecordReader(File inputFile, String splitPattern)
throws IOException {
this(new FileReader(inputFile), splitPattern);
}
trivial, but has to happen in this(...)
public RecordReader(String inputString, String splitPattern)
throws IOException {
this(new StringReader(inputString), splitPattern);
}
assignment 3 - GUI
Window title
Search field
Search
button
selected
match
similarity
scores in
percent
Table with
best matches
Divider of
split pane
Record text of
match selected
in table
Record field
collections
mini-recap
import java.util.Collection;
// Interface
import java.util.ArrayList;
// Implementation
import java.util.HashSet;
// Implementation
...
Collection coll1 = new ArrayList();
Collection coll2 = new HashSet();
...
col1.add("Test");
...
if(col1.isEmpty())
return false;
collections
A collection — sometimes called a container — is an
object that groups multiple elements into a single unit.
The collections framework is a unified architecture for
representing and manipulating collections. It contains:
Interfaces
Implementations
Algorithms
collections are generic: interface Collection<E>
AbstractCollection implements some functionality
collection may throw UnsupportedOperationException
(which is ugly)
http://java.sun.com/docs/books/tutorial/collections/index.html
grand overview
advantages
Reduces programming effort.
Increases program speed and quality.
Allows interoperability among unrelated APIs.
Reduces effort to learn and to use new APIs.
Reduces effort to design new APIs.
Fosters software reuse.
powerful stuff!
get familiar with it!
http://java.sun.com/docs/books/tutorial/collections/index.html
base interfaces
Collection:
Set:
List:
Queue:
Map:
SortedSet:
no duplicates
ordered collection
typically FIFO order
maps keys to values
maintains order
http://java.sun.com/docs/books/tutorial/collections/interfaces/index.html
base interfaces
http://en.wikibooks.org/wiki/Java:Collections
collection interface
http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.html
collection
support for-each loop:
for(Object o : collection)
System.out.println(o)
have iterators:
can be converted to arrays:
String[] a = c.toArray(new String[0]);
http://java.sun.com/docs/books/tutorial/collections/interfaces/collection.html
sets - class diagram
http://en.wikibooks.org/wiki/Java:Collections
set
inherits from collections but adds nothing
however, no duplicates
three implementations
HashSet: fast, not ordered
TreeSet: slower, but ordered
LinkedHashSet: medium, ordered, more memory
http://java.sun.com/docs/books/tutorial/collections/interfaces/set.html
set - example
public static <T> Collection<T> findDups(Collection<T> c) {
Collection<T> dups = new LinkedList<T>();
Set<T> set = new HashSet<T>();
for(T e : c)
if(!set.add(e))
dups.add(e);
return dups;
}
Set<T> s = new HashSet<T>(); is good practice!
set.add() returns false if element is already in set.
http://java.sun.com/docs/books/tutorial/collections/interfaces/set.html
set - operations
there are no set methods such as union,
intersection, difference but ...
"set operations" above are non-destructive
note that these methods are NOT set specific
http://java.sun.com/docs/books/tutorial/collections/interfaces/set.html
list - class diagram
http://en.wikibooks.org/wiki/Java:Collections
list - interface
http://java.sun.com/docs/books/tutorial/collections/interfaces/list.html
list
lists are ordered collections
inherited from Collection but with additional
methods:
positional access
search
richer Iterator
range-operations
two implementations:
ArrayList: fast positional access
LinkedList: better for insertions, deletions
http://java.sun.com/docs/books/tutorial/collections/interfaces/list.html
list - example
swap two elements of a list
random shuffling of list elements
=> note there is a Collections.shuffle() already!
http://java.sun.com/docs/books/tutorial/collections/interfaces/list.html
list - iterator
List implements ListIterator
http://java.sun.com/docs/books/tutorial/collections/interfaces/list.html
list - range view
replaces for(fromIndex, toIndex) loops
remove a range of elements from a list
find an element in a range
http://java.sun.com/docs/books/tutorial/collections/interfaces/list.html
list - Algorithms
sort
shuffle
reverse
rotate
swap
replaceAll
fill
copy
binarySearch
indexOfSubList
lastIndexOfSubList
All to find in
java.utils.Collection
s
http://java.sun.com/docs/books/tutorial/collections/interfaces/list.html
mini tutorial
StringBuilder builder = new StringBuilder();
while ((line = bufferedReader.readLine()) != null)
builder.append(line.toString()+"\n");
Can we do
better?
What do you think
about this?
static protected StringBuilder convert(String text){
return new StringBuilder(text.toLowerCase().replaceAll("\\W", "_"));
}
static public <E> void replace(List<E>, E val, E newVal) {
for (ListIterator<E> it = list.listIterator(); it.hasNext(); )
if (val == null ? it.next == null : val.equals(it.next()))
it.set(newVal);
Why and how
}
does it work?
mini tutorial solution
StringBuilder builder = new StringBuilder();
while((line = bufferedReader.readLine()) != null)
builder.append(line).append("\n");
no creation of temporary
string anymore
static protected StringBuilder convert(String text){
return new StringBuilder(text.toLowerCase().replaceAll("\\W", "_"));
}
nice! Would be perfect for String as return type
static public <E> void replace(List<E>, E val, E newVal) {
for (ListIterator<E> it = list.listIterator(); it.hasNext(); )
if (val == null ? it.next == null : val.equals(it.next()))
it.set(newVal);
deals with null values to replace
}
in an elegant way
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Collections
10
Ch 12,14
questions & quotes
When someone says, "I want a programming
language in which I need only say what I want done,"
give him a lollipop.
Alan Perlis
contents
collections
queues
maps
about consequences
a short story about wrong package
names and other software bugs ...
simple software errors
Mars Polar Lander lost
(misinterpretation of vibration due to leg-deployment as touch down)
$120 Million lost
Mars Climate Orbiter crashed when entering mars atmosphere
(Mix of metric and English units in navigation software)
$330 Million lost
Ariane 5 self-destructed (safety measure) shortly after lift-off
(bad floating point to integer conversion)
$500 Million lost
Patriot missile battery fails to intercept Iraqi Scud missile
(rounding error of internal clock)
28 killed, 98 wounded
1980 NORAD reports US under missile attack
(software ignored possible circuit failure)
1983 Soviet satellite reports incoming missiles
(software misinterpreted sun beam reflections on clouds)
to read: http://en.wikipedia.org/wiki/Stanislav_Petrov
bugs & consequences
it is not important how big the bug is!
it is the consequences that count!
collections
queues and maps
queue - class diagram
- there are more queue classes ...
ArrayBlockingQueue, ConcurrentLinkedQueue, DelayQueue, LinkedBlockingQueue,
LinkedList, PriorityBlockingQueue, PriorityQueue, SynchronousQueue
http://en.wikibooks.org/wiki/Java_Programming/Collection_Classes#Queue
queue - interface
typically FIFO
exception: priority queues
can be bound (upper limit for number of elements)
methods in two flavors (exception, special value)
LinkedList implements Queue<E> interface
http://java.sun.com/docs/books/tutorial/collections/interfaces/queue.html
queue - example
priority queue to sort list elements
Priority according to Comparable
Internally implemented as a binary tree
note there is a Collections.sort() method already
http://java.sun.com/docs/books/tutorial/collections/interfaces/queue.html
map - class diagram
http://en.wikibooks.org/wiki/Java:Collections
map - interface
http://java.sun.com/docs/books/tutorial/collections/interfaces/map.html
map
maps keys to values
no duplicate keys
keys need to be immutable
keys: hashCode() implementation
supports iteration over keys, values and pairs
the three main implementations:
HashMap: fast, keys not ordered
TreeMap: slower, keys ordered
LinkedHashMap: medium, keys ordered, more
memory
http://java.sun.com/docs/books/tutorial/collections/interfaces/map.html
map - example
public static <T> void histogram(Collection<T> c) {
Map<T, Integer> map = new HashMap<T, Integer>();
for(T e : c) {
Integer freq = map.get(e);
map.put(e, freq == null ? 1 : freq + 1);
}
System.out.println(map);
}
Map<K,V> s = new HashMap<K,V>(); is good practice!
http://java.sun.com/docs/books/tutorial/collections/interfaces/map.html
map - views
keySet — the Set of keys.
values — The Collection of values.
entrySet — the Set of key-value pairs.
Pairs are return as Map.Entry objects.
iterating over the keys of a map:
iterating over the key-value pairs of a map:
http://java.sun.com/docs/books/tutorial/collections/interfaces/map.html
more mapping
keys common to two maps:
remove keys in map that exist in another map
remove entries in map that exist in another map
http://java.sun.com/docs/books/tutorial/collections/interfaces/map.html
when to use what
List
ArrayList: constant access time, slow insertion and deletion
LinkedList: linear access time, fast insertion and deletion
LinkedList: FIFO (no sorting), fast
PriorityQueue: sorted, slower
HashMap/Set: fast, keys not ordered
TreeMap/Set: slower, keys ordered, can be sorted
LinkedHashMap/Set: medium, keys ordered
outdated
see java.util.concurrent
see java.utils.Collections
Queue
Map/Set
Hashtable, Vector
complexity O()
Collection with 65536 elements
Quadratic
O((N-1)*N/4)
1,073,725,440
Insertion sort
=> efficient algorithm is much more important
than efficient implementation!
http://www.digilife.be/quickreferences/PT/Java%20Collections%20Framework.pdf
synchronized wrappers
thread-safe collections
https://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
unmodifiable wrappers
immutable collections
https://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html
convenience implementations
List view of an array:
to use an array as a list/collection
multiple-copy list:
to initialize a collection with a value
immutable singleton set:
to remove all elements of a specific value
https://java.sun.com/docs/books/tutorial/collections/implementations/convenience.html
mini - tutorial
public interface Text {
public String getLine(int number);
}
public class SpellChecker {
public boolean isCorrect(Text text) {...}
}
public class ExtTextField implements Text {
private JTextField textField;
public ExtTextField(JTextField textField) {
this.textField = textField;
}
public String getLine(int number) {
return textField.getText();
}
}
What design
pattern has
been
applied?
mutable or
immutable
and is
there a
problem?
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Generics
11
Ch 20
quote
I know that you believe that you understood
what you think I said, but I am not sure you
realize that what you heard is not what I
meant.
Robert McCloskey
contents
JAR files
Generics
JAR files
JAR file
JAR = Java ARchive
compressed resources (classes, source, images,
sound, documentation, ...)
based on ZIP => unpack with WinZip, ...
"executable" if JRE is installed properly
can be signed => security privileges
can be sealed => version consistency
can be obfuscated => hampers reverse engineering
portable
http://java.sun.com/docs/books/tutorial/dep
loyment/jar/basicsindex.html
basics
create a JAR file:
jar cf jar-file input-file(s)
Eclipse: File->Export...
run a JAR file:
java -jar app.jar
(needs Main-class in manifest)
or simply double-click
view its contents
jar tf jar-file
create jar file - example
jar cvf TicTacToe.jar TicTacToe.class audio images
automatically adds manifest file
http://java.sun.com/docs/books/tutorial/deployment/jar/build.html
application entry point
application entry point
tells Java VM which main method of which class
to invoke.
Signature of entry point:
public static void main(String[] args)
specified in manifest file
Main-Class: mypackage.MyClass
e.g. Main-Class: calculator.Calculator
manifest file
created by default and required
stored at META-INF/MANIFEST.MF
describes how JAR is used
specifies application entry point
manifest must end with a new line!
manifest must be encoded in UTF8
UTF8: unicode but backwards compatible to ASCII
UTF-8 intermezzo
8-Bit UCS/Unicode Transformation Format
variable length character encoding for Unicode
backwards compatible with ASCII (128 chars)
may start with Byte Order Mark: BOM: EFBBBF to
mark UTF-8 ()
=> manifest must NOT have a BOM!
JAR classpath
referencing of classes in other JAR files outside a JAR
files
Class-Path: jar1-name jar2-name directory-name/jar3name
path on local drive (not within JAR file!)
doesn't allow you to put all jars of an application into one
single JAR
=> but there are tools for that
package versioning
package version in manifest file
http://java.sun.com/docs/books/tutorial/deployment/jar/packageman.html
sealing
sealing: all classes of a package must be archived in the same
JAR file
ensures version consistency
you cannot add new classes to a package from the outside
entry in manifest file
package name must end with "/"
http://java.sun.com/docs/books/tutorial/deployment/jar/sealman.html
signing
electronic signature
sign: jarsigner jar-file alias
verify: jarsigner -verify jar-file
user can grant special security privileges
Applets: accessing file system
public and private keys
private key signs
public key verifies
procedure:
Signer signs JAR file using private key
corresponding public key is placed in jar file
user verifies
deployment
Tools to create a single JAR
One-JAR
http://one-jar.sourceforge.net
Fat Jar Eclipse Plugin
http://fjep.sourceforge.net
Tools to wrap a JAR file in a window executable
JSmooth
http://jsmooth.sourceforge.net/
Launch4j
http://launch4j.sourceforge.net
Lift-Off
http://liftoff.sourceforge.net
JSmooth
open source, GPL
creates standard windows .exe binary
allows icon for executable
allows command line arguments
searches automatically for best JRE
if no JRE installed, installs automatically or points user to website
you can bundle your application with an JRE
http://jsmooth.sourceforge.net
Generics
example - class generics
public class Stack<T> {
private List<T> elements = new ArrayList<T>();
public void push(T element) {
elements.add(element);
}
public T pop() {
int top = elements.size()-1;
T result = elements.get(top);
elements.remove(top);
return result;
}
}
Stack<Double> stack = new Stack<Double>();
stack.push(3.14);
double pi = stack.pop();
example - method generics
public class Tools {
public static <T> void fill(List<T> list, T value, int n) {
for(int i=0; i<n; i++)
list.add(value);
}
public static <T> T middle(List<T> list) {
return list.get(list.size()/2);
}
}
List<String> list = new ArrayList<String>();
Tools.fill(list, "something", 10);
String middle = Tools.middle(list);
Number - intermezzo
Number: super class of Integer, Double, ...
example - bound type
public class Stats {
public static <T extends Number> void init(List<T> l, T e, int n) {
for(int i=0; i<n; i++)
l.add(e);
}
public static <T extends Number> double mean(List<T> l) {
double sum = 0.0;
for(T e : l)
sum += e.doubleValue();
return sum;
}
}
List<Double> list = new ArrayList<Double>();
Stats.init(list, 1.0, 10);
double mean = Stats.mean(list);
generics
Generics is not about implementing functionality.
Generics is about designing robust software!
Generics increase type safety through static typing.
Generics reduce casting and allow generic data
structures, e.g. Stack<Double>
Generics are implemented by type erasure.
Generic type information is only available at compile
time.
Advantage: works with legacy code (uses raw type).
Disadvantage: Some things don't work as expected:
T[] a = new T[100]
Generics are easy to use but difficult to implement
(most of the time)!
why static typing - 1
what does this code do?
def add(a, b):
# some miracle
A bit of
Python
int add(int a, int b) {
// less of a miracle
}
Object add(Object a, Object b) {
// another miracle
}
emulating
dynamic
typing
why static typing - 2
def add(a, b):
return a+b
Fails at runtime
int add(int a, int b) {
return a+b;
}
Fails at compile time
Object add(Object a, Object b) {
return a.add(b);
Fails at runtime
}
before and now
public void print_info(Collection c) {
for(Object s : c)
System.out.println(((Student s).name());
System.out.println(((Student s).address());
System.out.println(((Student s).phone());
}
public void print_info(Collection<Student> c) {
for(Student s : c)
System.out.println(s.name());
System.out.println(s.address());
System.out.println(s.phone());
}
with
1.4
with
1.5
old and new
public interface IStack {
public int size();
public void push(Object item);
public Object top();
public void pop();
}
public interface IStack<E> {
public int size();
public void push(E item);
public E top();
public void pop();
}
without
Generics
with
Generics
the rules
The type parameter is included in angular brackets after
the class name for class generics or in front of the
method name for method generics.
Any non-keyword identifier can be used for the type
parameter, but by convention, typically an uppercase one
letter name is used, e.g. T or E.
The type parameter can be used like other types used in
the definition of a class or method.
The type plugged in for a type parameter must always
be a reference type:
It cannot be a primitive type such as int, double,
or char. But there is auto-boxing!
Reference types include arrays.
some limitations
There are places where an ordinary class name would be
allowed, but a type parameter is not allowed.
In particular, the type parameter cannot be used in
expressions using new to create a new object.
Nope!
T obj = new T();
You can't
T[] a = new T[10];
do that!
The type parameter can also not be used as a constructor
name or like a constructor:
Arrays such as the following are illegal:
Stack<String>[] a = new Stack<String>[10];
There are more (subtle) problems caused by the erasure
mechanism
mini -tutorial
public abstract class Person {
public String name();
}
public class Student extends Person {
...
public class Staff extends Person {
}
...
}
public class Utils {
public static void printNames(List persons) {
for (Object person : persons)
if (person instanceof Person)
System.out.println( ((Person)person).name() );
}
}
List<Student> persons = new ArrayList<Student>();
Utils.printNames(persons);
Is it any
good?
Does it
work?
mini tutorial - first idea
public class Utils {
public static void printNames(List<Person> persons) {
for (Person person : persons)
System.out.println( person.name() );
}
}
List<Person> persons = new ArrayList<Student>();
Utils.printNames(persons);
Nice so
far!
but can't
do this :-(
Student is subtype of Person BUT
List<Student> is NOT subtype of List<Person>!
mini tutorial - solution
public class Utils {
public static <T extends Person> void printNames(List<T> persons) {
for (Person person : persons)
System.out.println( person.name() );
}
}
List<Student> students = new ArrayList<Student>();
Utils.printNames(students);
List<Staff> staff = new ArrayList<Staff>();
Utils.printNames(staff);
That works
now!
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Serialization
12
Ch 21,22
quote
If you lie to the compiler, it will get its revenge.
Henry Spencer
contents
serialization
serialization
Object
serialization
state
persistent storage
data
deserialization
persistence: preserve the state of an object beyond the
running time of the program:
saving an edited text document as a file
storing application settings within the registry
writing object states to an SQL database
...
serialization: mechanism to achieve persistence
take all member variables (= state) of an object and save
them somewhere, somehow
example - serialize
public class Document implements Serializable {
private String author;
Marks an object as
private Text text;
serializable
...
}
Needs to implement
Serializable as well
Document doc = new Document();
try {
ObjectOutputStream oos = ObjectOutputStream(
new FileOutputStream("Document.ser"));
oos.writeObject(doc);
Serialization,
oos.close();
no need to
} catch(IOException ioe) {
serialize "text"
separately
// do something
}
example - deserialize
Document doc = null;
try {
ObjectInputStream ois = ObjectInputStream(
new FileInputStream("Document.ser"));
doc = (Document)ois.readObject();
Class cast required
ois.close();
} catch(IOException ioe) {
// do something or not
} catch(ClassNotFoundException cnfe) {
cast can fail!
// you've got a problem
}
serializable
import java.io
(Serializable, ObjectOutputStream, ObjectInputStream)
Objects are not per default Serializable
Serializable is marker interface (no methods)
serializes in binary format => byte stream
(can be encrypted)
serializes referenced objects automatically if they implement
Serializable as well (they have to if they are not transient!)
a NotSerializableException is thrown when trying to serialize
a class object that is not serializable
allows to transport objects across machines, e.g.
remote method invocation (RMI)
it doesn't matter if member variable are private or protected they are serialized => breaks encapsulation
transient and static variables are NOT serialized
some classes cannot be serialized, e.g. Threads
Swing objects can be serialized but they are platform specific
(not recommended)
double trouble
objects and their referenced objects
build graph
Java serialization takes that into
account and does not serialize objects
twice, but ...
ObjectOutputStream oos = new ObjectOutputStream(...);
Document doc = new Document();
doc.setText("to be or");
oos.writeObject(doc);
doc.setText("not to be");
oss.writeObject(doc);
// serializes "to be or"
// update state
// not serialized!
call oos.reset()
transient
marks member variables as NOT being serialized
transient variables are set to their default values during
deserialization
=> you usually need to do something extra
public class Document implements Serializable {
private transient int docID;
you usually don't
private transient File tempBackup;
want to store the
private String author;
private Text text;
and the handle of your
...
temporary automatic
}
backup file is prob.
transient too.
temporary ID of a
loaded document.
custom serialization
override writeObject, readObject
need to be private
call default serialization first
private void writeObject(ObjectOutputStream out)
throws IOException {
out.defaultWriteObject();
... // do your own stuff
}
private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
... // do your own stuff
}
versioning
problem: class object gets serialized and class definition
changes due to software update.
question: can serialized class be deserialized/loaded or
not
solution: serialVersionUID
version number of a class => store during serialization
a class can be deserialized when the serialVersionUID of
the class definition and the serialized class are identical
if serialVersionUIDs do not match an
InvalidClassException is thrown
if no serialVersionUID is provided, it is generated
automatically (hidden)
serialVersionUID
static final long serialVersionUID = 7526472295622776147L;
generated serialVersionUID is hash code derived from
class properties such as name, member variables, ... and
highly sensitive to class changes
but you can make up your own. Nothing wrong with:
serialVersionUID = 1L
but you have to know what is a compatible class
modification
evolving classes:
certain changes in a class definition are compatible, e.g.
adding fields, with the serialized object other are not!
During deserialization additional fields will be initialized
with default values.
compatible changes
•
•
•
•
•
•
•
•
Adding fields
Adding classes
Removing classes
Adding writeObject/readObject methods
Removing writeObject/readObject methods
Adding java.io.Serializable
Changing the access to a field
Changing a field from static to non-static or
transient to non-transient
http://java.sun.com/javase/6/docs/platform/serialization/spec/version.html#6678
incompatible changes
• Deleting fields
• Moving classes up or down the hierarchy
• Changing a non-static field to static or a non-transient field
to transient
• Changing the declared type of a primitive field
• Changing the writeObject or readObject method so that it
no longer writes or reads the default field data
• Changing a class from Serializable to Externalizable or vice
versa
• Changing a class from a non-enum type to an enum type or
vice versa
• Removing either Serializable or Externalizable
• Adding the writeReplace or readResolve method to a class
can be incompatible
http://java.sun.com/javase/6/docs/platform/serialization/spec/version.html#6678
creating a serialVersionUID
eclipse: quickfix
Java: serialver -show
if you don't create your own serialVersionUID, one is created automatically
(hidden, hash code), which means that almost any change of the class
definition will be incompatible with the serialized object.
summary
implement Serializable
create serialVersionUID
(using serialver, eclipse, whatever, ...)
when class definition changes, decide if changes are
compatible with previous definition
when compatible keep serialVersionUID
(test that extensively!)
when incompatible create new serialVersionUID
(and provide format/version converter)
any object referenced or any superclass has to implement
Serializable as well
inner classes should not implement Serializable
denote serialized fields with @serial
other ways
Standard serialization is easy but not very efficient
(speed, size)
output is not human readable
=> difficult to debug
=> format/version conversion tricky
alternatives:
implement your own serialization via Externalizable
use other serialization frameworks
Hibernate: Maps classes to SQL database tables
JSX: Serializes objects to XML
...
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
threads
12
-
quote
Real computer scientists despise the idea of
actual hardware. Hardware has limitations,
software doesn't.
Anon
contents
threads
the Joel test
process vs thread
processes:
own execution environment - specifically own
memory
heavy weight
threads:
live within a process
share execution environment - specifically memory
light weight
Thread class
example
own class must extend Thread
implements run() method
start() starts the thread
public class HelloWorldThread extends Thread {
public void run() {
for(int i=0; i<100; i++)
System.out.println("Conquer the world!");
}
public static void main(String args[]) {
(new HelloWorldThread()).start();
}
}
important Thread methods
setName(): guess what
setPriority(): priority: 1...10
start(): starts the thread
sleep(): sends a thread to sleep, can be interrupted
join(): wait for this thread to terminate
getState(): NEW, RUNNABLE, BLOCKED, WAITING,
TIMED_WAITING, TERMINATED
isAlive(): test if thread is alive
...
deprecated methods:
Guess why! It turned
out these methods
stop(), suspend(), resume(), destroy()
Thread are
tricky!
are not really threadsafe!
two ways
public class MyThread extends Thread {
public void run() { ... }
public static void main(String args[]) {
(new MyThread()).start();
}
}
public class MyRunnable implements Runnable {
public void run() { ... }
public static void main(String args[]) {
(new Thread(new MyRunnable())).start();
}
}
sleep & interrupt
Thread.sleep(msec): suspends thread execution for the
specified time
allows other threads to work
can be interrupted => interrupted flag
interrupts are used to terminate/control thread
Thread.interrupted(): tests if thread has been interrupted
and clears flag.
Static method usually used to terminate this thread.
isInterrupted(): tests if thread has been interrupted and
does NOT clear the flag.
Non-static method usually used to test status of another
thread.
sleep & interrupt - example
public class MyThread extends Thread {
public void run() {
while(!done) {
... // do something really smart here
try { Thread.sleep(100); }
catch (InterruptedException e) { return; }
}
}
public static void main(String args[]) {
Thread thread = new MyThread();
thread.start();
... // do something in main thread
thread.interupt();
this is the way to stop a
}
thread. Not thread.stop()!
}
don't wanna sleep
you don't want to waste time in sleep()
need to call Thread.interrupted() periodically
public class NumberCruncher extends Thread {
public void run() {
while(isCrunching()) {
some heavy
... // crunch, crunch, ...
processing in
if (Thread.interrupted())
this loop
return;
}
clears
}
interrupt
}
status flag
join the party
join(): current thread waits for another thread to finish
public class ConquerWorld {
private class BuildEvilRobots extends Thread {
public void run() {
... // build the really evil type
}
}
public static void main(String args[]) {
// start conquering with big announcement
Thread thread = new BuildEvilRobots();
thread.start();
thread.join()
// proceed with conquering
}
}
synchronization - stack - 1
public class Stack10 {
private String[] stack = new String[10];
private int n = 0;
public int size() {
return n;
}
public void push(String value) {
stack[n++] = value;
}
public String pop() {
return stack[--n];
}
THREAD1:
}
if(stack.size() < 10)
stack.push("test");
not threadsafe
push() and
pop() are not
atomic
operations!
THREAD2:
if(stack.size() > 0)
stack.pop();
you have to be LUCKY that this works!
synchronization - stack - 2
public class Stack10 {
private String[] stack = new String[10];
private int n = 0;
thread-safe
public synchronized int size() {
return n;
}
public synchronized void push(String value) {
stack[n++] = value;
}
public synchronized String pop() {
methods are now
return stack[--n];
synchronized and
}
push() and pop()
}
are now atomic
operations
synchronization
when one thread is executing a synchronized method all
other threads that want to use synchronized methods of
the same object are blocked.
can't synchronize constructors
too much synchronization => dead locks
too little synchronization => consistency errors
you can synchronize statements:
public void push(String value) {
assert(stack != null);
e.g. no need to sync. assert()
synchronized(stack) {
stack[n] = value;
finer control over
n = n+1;
synchronization but
}
tricky! Careful!
}
immutable objects
are thread-safe
no synchronization is required
conditions:
no setters
all fields final and private
declare class as final
(no overriding)
don't reference to mutable objects
(create a copy if necessary)
Swing application
2+more threads
main thread
=> main method => window
Event Dispatch Thread
=> GUI
worker threads
=> long running tasks
most Swing components are NOT thread safe
=> reason: it is incredibly difficult to do
=> you need to synchronize, which is tricky!
=> but there is help: SwingWorker ...
SwingWorker
Swing application run in the Event Dispatch Thread and
long running tasks block GUI
Solution: run computationally expensive tasks in
separate thread => worker thread
SwingWorker is abstract, generic helper class that
simplifies the creation and management of worker
threads
SwingWorker provides all functionality typically needed for
worker threads: progress, status, interim results,
cancellation, ... => powerful stuff
Extending class must implement doInBackground()
method, which encapsulates the long running task
SwingWorker class
result type
intermediate results
abstract class SwingWorker<T,V> {
}
abstract T doInBackground();
T get();
void execute();
void done();
boolean isCancelled();
does the main processing
void publish(V...chunks);
void process(List<V> chunks);
...
sends data to process(...)
getter for final result
starts the worker
called when finished
indicates cancel from outside
receives published data
example - bad
No
SwingWorker
Document doc;
...
JButton button = new JButton("Load Document");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doc = loadHugeDoc();
User interface
}
blocked while
});
loading document
example - better
Document doc;
...
JButton button = new JButton("Load Document");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
(new SwingWorker<Document, Void>() {
public Document doInBackground() {
return loadHugeDoc();
runs as separate
worker thread
}
public void done() {
doc = get();
get() runs in Event
}
Dispatch Thread
}).execute();
}
loading the document as one
chunk means no progress bar
});
and you can't cancel!
publish & process
class TableSwingWorker extends
SwingWorker<DefaultTableModel, Object[]> {
private final DefaultTableModel tableModel;
public TableSwingWorker(DefaultTableModel tableModel) {
this.tableModel = tableModel;
}
protected DefaultTableModel doInBackground() {
while(Object[] row = loadRow() && !isCancelled())
publish((Object[]) row);
load table row by row
return tableModel;
and update shown table
}
protected void process(List<Object[]> rows) {
process() runs in Event
for (Object[] row : rows) {
Dispatch Thread
tableModel.addRow(row);
}
}
}
http://java.sun.com/javase/7/docs/api/javax/swing/SwingWorker.html
propertyChange - progress
class TableSwingWorker extends SwingWorker<DefaultTableModel, Object[]> {
...
protected DefaultTableModel doInBackground() {
for(int i=0; i<rowNumber && !isCancelled(); i++) {
publish((Object[]) loadRow(i));
setProgress(100*i/rowNumber);
}
return tableModel;
show progress bar
}
while loading table
}
final JProgressBar progressBar = new JProgressBar(0, 100);
TableSwingWorker tableWorker = new TableSwingWorker(tableModel);
tableWorker.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
progressBar.setValue((Integer)evt.getNewValue());
}
}
});
tableWorker.execute();
http://java.sun.com/javase/7/docs/api/javax/swing/SwingWorker.html
propertyChange - status
class SwingWorkerCompletionWaiter extends PropertyChangeListener {
private JDialog dialog;
public SwingWorkerCompletionWaiter(JDialog dialog) {
this.dialog = dialog;
}
public void propertyChange(PropertyChangeEvent event) {
if ("state".equals(event.getPropertyName())
&& SwingWorker.StateValue.DONE == event.getNewValue()) {
dialog.setVisible(false);
dialog.dispose();
}
}
}
JDialog dialog = new JDialog(owner, true);
displays dialog until
swingWorker.addPropertyChangeListener(
swingWorker is done
new SwingWorkerCompletionWaiter(dialog));
swingWorker.execute();
dialog.setVisible(true);
http://java.sun.com/javase/7/docs/api/javax/swing/SwingWorker.html
problems
deadlock: two or more threads are waiting for each other
livelock: two or more threads are too busy to communicating
to do their actual work
starvation: a thread can get access to a shared resource
because other threads accessing the resource too frequently
thread interference: two threads performing interleaving
operations on a shared resource
memory inconsistency: two threads have inconsistent views on
what should be the same data
Problems appear "randomly". Debugging essentially not
possible. Unit tests do not work. Have to be fixed through
reasoning only!
memory consistency errors
class Counter {
private int c = 0;
public void increment() {
c++;
not an atomic operation,
is c = c +1
}
public void show() {
System.out.println(c);
}
}
1. Thread A: increment().
2. Thread B: show()
may print 0 or 1
does not nec. see the change
caused by Thread A
thread interference
class Counter {
private int c = 0;
public void increment() {
c++;
not an atomic operation,
}
is c = c +1
public void decrement() {
c--;
not atomic
}
public int value() {
return c;
}
}
1. Thread A: Retrieve c.
2. Thread B: Retrieve c.
3. Thread A: Increment retrieved value;
result is 1.
4. Thread B: Decrement retrieved value;
result is -1.
5. Thread A: Store result in c; c is now 1.
6. Thread B: Store result in c; c is now -1.
tips
avoid threads whenever possible
when using threads multiply your time estimate by a factor of
5 to 10
synchronize sparsely but sufficiently -> ha ha ha!
do as little work as possible within a synchronized region
take advantage of higher level support (e.g. SwingWorker)
whenever possible
don't use thread priorities to solve synchronization/liveness
problems
test extensively on different machines under different loads
and operating systems
document thread safety
there is no trial-and-error approach with thread. You really
need to understand what's going on!
these tips/slides barely scratching the surface. Read a lot more
before implementing threads
Joel test
by Joel Spolsky:
1. Do you use source control?
2. Can you make a build in one step?
3. Do you make daily builds?
4. Do you have a bug database?
5. Do you fix bugs before writing new code?
6. Do you have an up-to-date schedule?
7. Do you have a spec?
8. Do programmers have quiet working conditions?
9. Do you use the best tools money can buy?
10. Do you have testers?
11. Do new candidates write code during their interview?
12. Do you do hallway usability testing?
http://www.joelonsoftware.com/articles/fog0000000043.html
mini tutorial
public class StoppableThread extends Thread {
private boolean stop = false;
public void run() {
while(!stop) {
// work really hard
}
}
public void requestStop() {
stop = true;
}
}
Effective Java, J. Bloch
Does
it
work?
If you are
lucky it
works most
of the
time...
mini tutorial - solution
public class StoppableThread extends Thread {
private boolean stop = false;
public void run() {
while(!getStop()) {
// work really hard
}
}
private synchronized getStop() {
return stop;
}
public synchronized void requestStop() {
stop = true;
}
}
Effective Java, J. Bloch
no problems with memory
inconsistency for boolean
stop variable but ...
... no guarantee that update
of stop variable is observed as
intended without synchronized
access!
Programming in the Large
Advanced Software Engineering
course:
topic:
week:
reading:
CSSE2002/7023
Information theory
13
-
quote
A language that doesn't affect the way you think
about programming, is not worth knowing
Alan Perlis
contents
recap: list and iterators
information theory
lists & iterators
linked list
single linked list
linear access time
constant insertion/removal time
List
Node
first
next
content
next
content
next
content
null
Iterator
java.util
iterates over the elements of a data structure
public interface Iterator<E>
hasNext()
next
content
null
next()
next
next
content
remove()
Iterable
java.lang
allows an object to be the target of the "foreach"
statement.
public interface Iterable<T>
iterator/iterable example
public class StackIterator implements Iterator<String>, Iterable<String> {
private String[] stack = new String[100];
private int
index = 0, n = 0;
public boolean hasNext() {
return index < n;
}
n = #stack elements
implementation of
push, pop, ... skipped
public String next() {
if(index >= n) throw NoSuchElementException();
return stack[index++];
}
Iterator<String>
public void remove() {
throw new UnsupportedOperationException();
}
public Iterator<String> iterator() {
return this;
}
}
Iterable<String>
information theory
bits and guessing
What's a BIT?
=> smallest unit of information:
it's binary:
e.g. true/false, on/off, yes/no, tails/heads
Guess a number between 1 and 10.
(e.g. is the number larger than 4? => yes/no)
What's the optimal strategy and
how much information(= guesses/bits)
do you need in the worst case?
=> binary search, log2(10) = 3.3 => 4 guesses
http://java.sun.com/docs/books/tutorial/java/concepts/inheritance.html
binary search tree
1
2
3
4
5
6
7
8
9
10
n numbers
<6
<4
<2
1
<5
<3
2
<9
3
4
<7
5
6
<10
<8
7
9
log2(n)
10
8
=> log2(10) = 3.3 decisions on average
=> optimal strategy if all numbers are equally probable
uncertainty
n equally probable events, p = 1/n
uncertainty u = log2(n) = -log2(1/n)
• how many guesses until you are certain
• if only one possible outcome: p=1
=> u = log2(1) = 0
=> no uncertainty = boring
• 10000 options
=> u = log2(10000) = 13.3
average uncertainty avg(u)
avg(u) = - 1/n *
log2(1/n) =
-log2(1/n)
information entropy
n possible events xi with different prob. p(xi)
uncertainty u(xi) = -log2(p(xi))
average uncertainty avg(u) =
Shannon's Information Entropy H
p(x ) u(xi)
= - p(x ) log2(p(xi))
H(X) =
i
i
more entropy
measure of boringness/redundancy of a system
smallest number of bits per symbol required to
describe a symbol stream (=>channel capacity)
upper bound for lossless compression algorithms
Shannon entropy for English = 0.6-1.3 (bpc) bits
per character (bpc)
There are other entropies (Gibbs, Boltzman, ...)
entropy of literary styles
Bible - King James
Jane Austen - Sense and Sensibility, Northanger Abbey, Persuasion,
Mansfield Park
James Joyce - Ulysses, Portrait of the Artist as a Young Man
=> you can also do "language recognition"
(zip different languages and compare file sizes)
http://www.stat.purdue.edu/people/homepages/yiannis/PAPERS/english.ps.gz
generating text
First order letter model:
ocroh hli rgwr nmielwis eu ll nbnesebya th eei alhenhttpa oobttva nah
Second order letter model:
on ie antsoutinys are t inctore st be s deamy achin d ilonasive tucoowe
Third order letter model:
in no ist lat whey cratict froure birs grocid pondenome of demonstures
First order word model:
representing and speedily is an good apt or come can different natural
Second order word model:
the head and in frontal attack on an english writer that the character
huffman tree
"this is an example of a huffman tree"
http://en.wikipedia.org/wiki/Huffman_coding
huffman encoding
David A. Huffman, 1952, MIT
entropy encoding algorithm
lossless compression
variable code length
prefix code (no code is prefix of another code)
theoretically best possible encoding for symbol stream
(provided probabilities are exact and stable)
for equiprobable symbols huffman code becomes
block code (e.g. ASCII code)
creation of Huffman tree is O(n*log(n))
http://www.siggraph.org/education/materials/HyperGraph/video/mpeg/mpegfaq/huffman_tutorial.html
mini-tutorial
Given:
- 120 Students
- a web server (limited capacity)
- a submission deadline a 5pm
Question: At what time do you submit?
1. at 5:00pm because nobody ever will submit at 5pm
2. at 5:30pm because everyone will have submitted by then
3. at 4:59pm because that is just before the deadline
4. at least 2h before the deadline because that is cool
5. doesn't matter because you don't believe in deadlines
Hint!
link to wisdom
How To Become A Hacker
http://catb.org/~esr/faqs/hacker-howto.html