Breaking the Kubernetes Kill Chain: Host Path Mount
groovy & grails - lecture 5
1. Groovy: Efficiency Oriented Programming
Lecture 5
Master Proteomics & Bioinformatics - University of Geneva
Alexandre Masselot - summer 2011
2. Contents
‣ Eclipse & linux tips
‣ Debugging with Eclipse
‣ A thought on code design
‣ Object methods : a few step forwards
‣ Inheritance
3. A couple of linux (shell) tips
‣ Print all files named peaklist-*.mgf residing under a
given directory:
find /home/alex/tmp -name “peaklist-*.mgf”
4. A couple of linux (shell) tips
‣ Print all files named peaklist-*.mgf residing under a
given directory:
find /home/alex/tmp -name “peaklist-*.mgf”
‣ Get “ls -l” like details by appending -ls option
5. A couple of linux (shell) tips
‣ Print all files named peaklist-*.mgf residing under a
given directory:
find /home/alex/tmp -name “peaklist-*.mgf”
‣ Get “ls -l” like details by appending -ls option
‣ You want to download a fasta file, based on a list of accession codes
acList="P41159 Q9Y5Q6 Q70Z44"
for ac in $acList; do echo "downloading $ac" ; wget
--quiet -O $ac.fasta http://uniprot.org/uniprot/$ac.fasta;
done
6. A couple of linux (shell) tips
‣ Print all files named peaklist-*.mgf residing under a
given directory:
find /home/alex/tmp -name “peaklist-*.mgf”
‣ Get “ls -l” like details by appending -ls option
‣ You want to download a fasta file, based on a list of accession codes
acList="P41159 Q9Y5Q6 Q70Z44"
for ac in $acList; do echo "downloading $ac" ; wget
--quiet -O $ac.fasta http://uniprot.org/uniprot/$ac.fasta;
done
‣ The same, in multi-line version:
for ac in $acList
do
echo "downloading $ac"
wget --quiet -O $ac.fasta http://uniprot.org/uniprot/$ac.fasta
done
7. A couple of eclipse tips
‣ launches the last executed program (or test)
- <ctrl>-<shift>-F11
- configure through
preferences > run/debug > launching > launch operation
- possible to run a whole directory as junit test
8. A couple of eclipse tips
‣ launches the last executed program (or test)
- <ctrl>-<shift>-F11
- configure through
preferences > run/debug > launching > launch operation
- possible to run a whole directory as junit test
‣ It is possible to hide/show the current method / editor block
- little +/- sign in the margin to toggle show/hide
- shortcut <numpad> /
10. Eclipse: debugging
‣ 90% of a developer's time is spent debugging his code
‣ Old fashion way: add println statement
- enhance println of object defined by you through defining a String
toString() method
- damned tedious: define println details, comment in/out, pollutes the
code
11. Eclipse: debugging
‣ 90% of a developer's time is spent debugging his code
‣ Old fashion way: add println statement
- enhance println of object defined by you through defining a String
toString() method
- damned tedious: define println details, comment in/out, pollutes the
code
‣ Configurable logger (log4j)
- print on console, but with different level of details (debug/info/warn/error)
- cleaner in code
- no need to comment in/out
- we will see this functionality later
12. Eclipse: debugging (cont’d)
‣ Debugging consists in three major aspects:
13. Eclipse: debugging (cont’d)
‣ Debugging consists in three major aspects:
‣ Breakpoints
- a breakpoint is a “flag” positioned at a given line in the source code
- at execution time, the program will halt when reaching the break point
- possible to move on step by step (into, over or return) or to next
breakpoint
14. Eclipse: debugging (cont’d)
‣ Debugging consists in three major aspects:
‣ Breakpoints
- a breakpoint is a “flag” positioned at a given line in the source code
- at execution time, the program will halt when reaching the break point
- possible to move on step by step (into, over or return) or to next
breakpoint
‣ Displaying objects
- when the program is halted, objects available in the current scope can
be analyzed
- it is possible to dig in the object fields
15. Eclipse: debugging (cont’d)
‣ Debugging consists in three major aspects:
‣ Breakpoints
- a breakpoint is a “flag” positioned at a given line in the source code
- at execution time, the program will halt when reaching the break point
- possible to move on step by step (into, over or return) or to next
breakpoint
‣ Displaying objects
- when the program is halted, objects available in the current scope can
be analyzed
- it is possible to dig in the object fields
‣ Call stack
- The stack of method calls at the current position
16. Eclipse: debugging (cont’d)
‣ Launching in debug mode
- instead of “run as...”, call “debug as...”
- <ctrl>-F11
17. Eclipse: debugging (cont’d)
‣ Launching in debug mode
- instead of “run as...”, call “debug as...”
- <ctrl>-F11
‣ Eclipse open the debug perspective, with different windows for
- variables
- breakpoint list
- call stack
- current code
- menu for stepping or resuming execution
23. execution control
debug mode
call stack
current code line
break point
8
24. execution control
debug mode
call stack variable
current code line
break point
8
25. A thought on code design
‣ Writing a script with all in one to answer a (lab) question is only code
writing
26. A thought on code design
‣ Writing a script with all in one to answer a (lab) question is only code
writing
‣ Architecting a problem into a piece of software is also a matter of breaking
the problem
- into classes achieving independent functionalities (test, change a sub
part)
- offer the possibility to re-use functionalities
27. A thought on code design
‣ Writing a script with all in one to answer a (lab) question is only code
writing
‣ Architecting a problem into a piece of software is also a matter of breaking
the problem
- into classes achieving independent functionalities (test, change a sub
part)
- offer the possibility to re-use functionalities
‣ But do not over-architect a software at start; prefer to make it evolve
constantly (think agile)
28. A thought on code design
‣ Writing a script with all in one to answer a (lab) question is only code
writing
‣ Architecting a problem into a piece of software is also a matter of breaking
the problem
- into classes achieving independent functionalities (test, change a sub
part)
- offer the possibility to re-use functionalities
‣ But do not over-architect a software at start; prefer to make it evolve
constantly (think agile)
‣ For example, the practicals Protein class should not contain the
download/readFromFasta (what will happen when reading from xml?)
29. A thought on code design
‣ Writing a script with all in one to answer a (lab) question is only code
writing
‣ Architecting a problem into a piece of software is also a matter of breaking
the problem
- into classes achieving independent functionalities (test, change a sub
part)
- offer the possibility to re-use functionalities
‣ But do not over-architect a software at start; prefer to make it evolve
constantly (think agile)
‣ For example, the practicals Protein class should not contain the
download/readFromFasta (what will happen when reading from xml?)
‣ Your motto : “I want to understand my own code in 6 months”
31. OOP: more depth
‣ Several aspects of OOP
- creating a new class
- fields
- static fields
- constructors
- methods
- unit testing
- overriding operators
- method or closures?
- inheritance
32. OOP: Making a new class
‣ By convention, class name starts with an upper case (when variable usually
start with lower case)
33. OOP: Making a new class
‣ By convention, class name starts with an upper case (when variable usually
start with lower case)
‣ Within a source directory, create a package (a subdirectory structure,
where ‘.’ is a directory path separator), for example
unige.mpb.lec5.example
34. OOP: Making a new class
‣ By convention, class name starts with an upper case (when variable usually
start with lower case)
‣ Within a source directory, create a package (a subdirectory structure,
where ‘.’ is a directory path separator), for example
unige.mpb.lec5.example
‣ In eclipse File -> new -> package (<ctrl>-N package)
35. OOP: Making a new class
‣ By convention, class name starts with an upper case (when variable usually
start with lower case)
‣ Within a source directory, create a package (a subdirectory structure,
where ‘.’ is a directory path separator), for example
unige.mpb.lec5.example
‣ In eclipse File -> new -> package (<ctrl>-N package)
‣ Within this package, create a class : File -> new -> groovy class and set
name Person.
36. OOP: Making a new class
‣ By convention, class name starts with an upper case (when variable usually
start with lower case)
‣ Within a source directory, create a package (a subdirectory structure,
where ‘.’ is a directory path separator), for example
unige.mpb.lec5.example
‣ In eclipse File -> new -> package (<ctrl>-N package)
‣ Within this package, create a class : File -> new -> groovy class and set
name Person.
‣ A Person.groovy file is create with
package unige.mpb.lec5.examples
class Person{
...
}
38. OOP: making a new class (cont’d)
class Person{
String name // field of type String
Date birth // field of type Date
int age(){ // a method returning an int
return (new Date()).year - birth.year
}
}
39. one field : one property link to one instance
13
40. Class: fields
‣ Fields are properties of a class, they can be dynamically or statically typed
(of any existing type (Integer, List, Map, etc...)
41. Class: fields
‣ Fields are properties of a class, they can be dynamically or statically typed
(of any existing type (Integer, List, Map, etc...)
‣ Field are by default associated to an instance of the class (an object
generated by new Person())
42. Class: fields
‣ Fields are properties of a class, they can be dynamically or statically typed
(of any existing type (Integer, List, Map, etc...)
‣ Field are by default associated to an instance of the class (an object
generated by new Person())
‣ They can be changed directly from outside the class (GBean)
guy.name = ‘Jimmy‘
guy.setName(‘Jimmy’)
43. Class: fields
‣ Fields are properties of a class, they can be dynamically or statically typed
(of any existing type (Integer, List, Map, etc...)
‣ Field are by default associated to an instance of the class (an object
generated by new Person())
‣ They can be changed directly from outside the class (GBean)
guy.name = ‘Jimmy‘
guy.setName(‘Jimmy’)
‣ Or read
println guy.name
println guy.getName()
44. Class: fields
‣ Fields are properties of a class, they can be dynamically or statically typed
(of any existing type (Integer, List, Map, etc...)
‣ Field are by default associated to an instance of the class (an object
generated by new Person())
‣ They can be changed directly from outside the class (GBean)
guy.name = ‘Jimmy‘
guy.setName(‘Jimmy’)
‣ Or read
println guy.name
println guy.getName()
‣ Inside a method, the instance properties are directly used by their name
int age(){return (new Date()).year - birth.year}
47. Class: static fields
‣ Fields can also be static i.e. a global value, shared by all instances of the
class (by convention upper case).
48. Class: static fields
‣ Fields can also be static i.e. a global value, shared by all instances of the
class (by convention upper case).
‣ If we come back to our previous Person example, we want
static int AGE_LIMIT = 18
boolean canDrive(){return age() >= AGE_LIMIT}
49. Class: static fields
‣ Fields can also be static i.e. a global value, shared by all instances of the
class (by convention upper case).
‣ If we come back to our previous Person example, we want
static int AGE_LIMIT = 18
boolean canDrive(){return age() >= AGE_LIMIT}
‣ We can change this value at once for all Person instances
Person.AGE_LIMIT = 16
50. Constructor
‣ Thanks to the scripting spirit, there is no need to declare constructor (the
function to instantiate an object)
51. Constructor
‣ Thanks to the scripting spirit, there is no need to declare constructor (the
function to instantiate an object)
‣ Field can be filled with a map structure
Person girl=new Person(name:‘Marylyn’)
52. Constructor
‣ Thanks to the scripting spirit, there is no need to declare constructor (the
function to instantiate an object)
‣ Field can be filled with a map structure
Person girl=new Person(name:‘Marylyn’)
‣ It is not compulsory to set all the field
53. Constructor
‣ Thanks to the scripting spirit, there is no need to declare constructor (the
function to instantiate an object)
‣ Field can be filled with a map structure
Person girl=new Person(name:‘Marylyn’)
‣ It is not compulsory to set all the field
‣ To set default value to a field, you can define it in the property declaration
String name=‘John Doe’
55. Methods
‣ Methods are functions, with are called within the context of an object
instance
56. Methods
‣ Methods are functions, with are called within the context of an object
instance
‣ All properties of the instance are accessed directly
57. Methods
‣ Methods are functions, with are called within the context of an object
instance
‣ All properties of the instance are accessed directly
‣ It is possible to modify the instance, directly addressing the instance fields
58. Methods
‣ Methods are functions, with are called within the context of an object
instance
‣ All properties of the instance are accessed directly
‣ It is possible to modify the instance, directly addressing the instance fields
‣ It is possible to pass argument to the function
59. Methods
‣ Methods are functions, with are called within the context of an object
instance
‣ All properties of the instance are accessed directly
‣ It is possible to modify the instance, directly addressing the instance fields
‣ It is possible to pass argument to the function
‣ It is possible to return a value (of whatever type)
60. OOP : methods
‣ A method is a function called in the context of an object instance
61. OOP : methods
‣ A method is a function called in the context of an object instance
‣ All fields of the object can be addressed directly from within a method
62. OOP : methods
‣ A method is a function called in the context of an object instance
‣ All fields of the object can be addressed directly from within a method
‣ Methods are functions: lecture 2 about function apply:
- dynamic/static types for arguments
- arguments can be named
- arguments can have default values
- if multiple functions are defined with the same name but different list/
type of arguments, the call context will choose the correct one
63. Methods: setter and getter
‣ Protein field can be accessed in two equivalent manner
prot.sequence
prot.getSequence()
64. Methods: setter and getter
‣ Protein field can be accessed in two equivalent manner
prot.sequence
prot.getSequence()
‣ Or set via two manners
prot.sequence=‘ACDEFG’
prot.setSequence(‘ACDEFG’)
65. Methods: setter and getter
‣ Protein field can be accessed in two equivalent manner
prot.sequence
prot.getSequence()
‣ Or set via two manners
prot.sequence=‘ACDEFG’
prot.setSequence(‘ACDEFG’)
‣ In fact reading or setting the field via the field calls the getter/setter
implicitly (methods are generated automatically by the groovy compiler)
66. Methods: setter and getter
‣ Protein field can be accessed in two equivalent manner
prot.sequence
prot.getSequence()
‣ Or set via two manners
prot.sequence=‘ACDEFG’
prot.setSequence(‘ACDEFG’)
‣ In fact reading or setting the field via the field calls the getter/setter
implicitly (methods are generated automatically by the groovy compiler)
‣ By default, a setSequence method is defined
void setSequence(sequence){ //void means no value returned
this.sequence=sequence
//this is the current object
// we could have name the argument with ‘seq’
}
67. Methods: setter and getter (cont’d)
‣ Imagine we want to get the protein mass, computed from the sequence
def mp = prot.mass
68. Methods: setter and getter (cont’d)
‣ Imagine we want to get the protein mass, computed from the sequence
def mp = prot.mass
‣ Their is no explicit mass field, but a static MassCalculator is attached
to class Protein
static MassCalculator MASS_CALCULATOR
69. Methods: setter and getter (cont’d)
‣ Imagine we want to get the protein mass, computed from the sequence
def mp = prot.mass
‣ Their is no explicit mass field, but a static MassCalculator is attached
to class Protein
static MassCalculator MASS_CALCULATOR
‣ We can define a getMass method
double getMass(){
return MASS_CALCULATOR.sequenceMass(this)
}
70. Methods: setter and getter (cont’d)
‣ Imagine we want to get the protein mass, computed from the sequence
def mp = prot.mass
‣ Their is no explicit mass field, but a static MassCalculator is attached
to class Protein
static MassCalculator MASS_CALCULATOR
‣ We can define a getMass method
double getMass(){
return MASS_CALCULATOR.sequenceMass(this)
}
‣ Problem with the current solution: we recompute mass at each time we
call it (think of sorting a long list of protein on their mass)
71. Methods: setter and getter (cont’d)
‣ We could therefore have a mass field to Protein and set it with the
correct value the first time we ask for it
double mass = 0
...
double getMass(){
if(!mass)
mass = MASS_CALCULATOR.sequenceMass(this)
return mass
}
72. Methods: setter and getter (cont’d)
‣ We could therefore have a mass field to Protein and set it with the
correct value the first time we ask for it
double mass = 0
...
double getMass(){
if(!mass)
mass = MASS_CALCULATOR.sequenceMass(this)
return mass
}
‣ We consider the mass field as a cached value
73. Methods: setter and getter (cont’d)
‣ We could therefore have a mass field to Protein and set it with the
correct value the first time we ask for it
double mass = 0
...
double getMass(){
if(!mass)
mass = MASS_CALCULATOR.sequenceMass(this)
return mass
}
‣ We consider the mass field as a cached value
‣ Problem: what happen if we change the protein sequence?
74. Methods: setter and getter (cont’d)
‣ Solution : reset mass when we set the sequence
def setSequence(sequence){
this.sequence=sequence
mass=0
}
75. Methods: setter and getter (cont’d)
‣ Solution : reset mass when we set the sequence
def setSequence(sequence){
this.sequence=sequence
mass=0
}
‣ If we need (e.g. at testing time) to access directly to the field, without
going through the getMass() method, we still can
my_prot.@mass
76. Unit testing
‣ Each method of a class must be tested, to ensure it fulfills the intended
goals
77. Unit testing
‣ Each method of a class must be tested, to ensure it fulfills the intended
goals
‣ One class file = one test file
- in another directory (src/test)
- same package name
- MyClass.groovy => MyClassTest.groovy
78. Unit testing
‣ Each method of a class must be tested, to ensure it fulfills the intended
goals
‣ One class file = one test file
- in another directory (src/test)
- same package name
- MyClass.groovy => MyClassTest.groovy
‣ Eclipse/groovy offers a integrated environment for that purpose
79. Unit testing (cont’d)
‣ In another source folder (typically src/tests/groovy), test will be
generated:
- select a class
- File -> new -> Groovy Test Case
- select the other src/test/groovy source folder
- select junit 3 (better for later use of grails for the moment)
- next -> select methods to be tested
80. Unit testing (cont’d)
‣ In another source folder (typically src/tests/groovy), test will be
generated:
- select a class
- File -> new -> Groovy Test Case
- select the other src/test/groovy source folder
- select junit 3 (better for later use of grails for the moment)
- next -> select methods to be tested
‣ In junit 3, any method with name starting with test* will be used as test
81. Unit testing (cont’d)
‣ In another source folder (typically src/tests/groovy), test will be
generated:
- select a class
- File -> new -> Groovy Test Case
- select the other src/test/groovy source folder
- select junit 3 (better for later use of grails for the moment)
- next -> select methods to be tested
‣ In junit 3, any method with name starting with test* will be used as test
‣ right button -> run as -> junit test (<ctrl>-<alt>-X-T)
82. Unit testing (cont’d)
‣ In another source folder (typically src/tests/groovy), test will be
generated:
- select a class
- File -> new -> Groovy Test Case
- select the other src/test/groovy source folder
- select junit 3 (better for later use of grails for the moment)
- next -> select methods to be tested
‣ In junit 3, any method with name starting with test* will be used as test
‣ right button -> run as -> junit test (<ctrl>-<alt>-X-T)
‣ Customize show view (<ctrl>-<alt>-Q-U + down arrow and tab)
83. Methods: overriding operators
‣ In lecture 1 (or “Groovy in Action”, chap. 3.3) we saw several operator (+,
*, /) and how those operators are tight to a method name
84. Methods: overriding operators
‣ In lecture 1 (or “Groovy in Action”, chap. 3.3) we saw several operator (+,
*, /) and how those operators are tight to a method name
‣ For example, we like to write the cleavage of a Protein by an Enzyme
List peptides=my_prot/trypsin
//in Protein.groovy
def div(enz){
return enz.cleav(this) //this is the current object
}
85. Methods: overriding operators
‣ In lecture 1 (or “Groovy in Action”, chap. 3.3) we saw several operator (+,
*, /) and how those operators are tight to a method name
‣ For example, we like to write the cleavage of a Protein by an Enzyme
List peptides=my_prot/trypsin
//in Protein.groovy
def div(enz){
return enz.cleav(this) //this is the current object
}
‣ Do not abuse of overriding operator (think that you want to understand
your code in 6 months)
86. Override spaceship: making objects comparable
‣ A very common need is to make relevant the operators <, <=, ==, > and >=
87. Override spaceship: making objects comparable
‣ A very common need is to make relevant the operators <, <=, ==, > and >=
‣ It is equivalent to override the spaceship operator <=>
88. Override spaceship: making objects comparable
‣ A very common need is to make relevant the operators <, <=, ==, > and >=
‣ It is equivalent to override the spaceship operator <=>
‣ First step: make your class implements the Comparable interface
class MyClass implements Comparable{
...
}
89. Override spaceship: making objects comparable
‣ A very common need is to make relevant the operators <, <=, ==, > and >=
‣ It is equivalent to override the spaceship operator <=>
‣ First step: make your class implements the Comparable interface
class MyClass implements Comparable{
...
}
‣ Second step: code the logic of the spaceship (< return negative, == returns
0, and > returns positive integer)
def int compareTo(other){
...
}
90. Override spaceship: making objects comparable
‣ A very common need is to make relevant the operators <, <=, ==, > and >=
‣ It is equivalent to override the spaceship operator <=>
‣ First step: make your class implements the Comparable interface
class MyClass implements Comparable{
...
}
‣ Second step: code the logic of the spaceship (< return negative, == returns
0, and > returns positive integer)
def int compareTo(other){
...
}
‣ See practicals for an example on Protein
91. Method or closure?
‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object
in that you can pass a reference to it around just as you can a reference to any
other object”
(Groovy in Action - 5.1 A gentle introduction to closures)
92. Method or closure?
‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object
in that you can pass a reference to it around just as you can a reference to any
other object”
(Groovy in Action - 5.1 A gentle introduction to closures)
‣ From the caller point of view, method or closure at very similar
93. Method or closure?
‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object
in that you can pass a reference to it around just as you can a reference to any
other object”
(Groovy in Action - 5.1 A gentle introduction to closures)
‣ From the caller point of view, method or closure at very similar
‣ However, we can modify a closure, thus modify the behavior of an action
on an object, from outside the class
94. Method or closure?
‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object
in that you can pass a reference to it around just as you can a reference to any
other object”
(Groovy in Action - 5.1 A gentle introduction to closures)
‣ From the caller point of view, method or closure at very similar
‣ However, we can modify a closure, thus modify the behavior of an action
on an object, from outside the class
‣ From the coding point of view, you can add closure in your class
def myAction = { arg1, arg2 ->
...
}
95. Method or closure?
‣ “A closure is a piece of code wrapped up as an object[...]. It’s a normal object
in that you can pass a reference to it around just as you can a reference to any
other object”
(Groovy in Action - 5.1 A gentle introduction to closures)
‣ From the caller point of view, method or closure at very similar
‣ However, we can modify a closure, thus modify the behavior of an action
on an object, from outside the class
‣ From the coding point of view, you can add closure in your class
def myAction = { arg1, arg2 ->
...
}
‣ Then call it
myObj.myAction(12, ‘abc’)
96. Method or closure? (cont’d)
‣ In Protein.groovy, consider the static method that turn ac into a url
static def UNIPROT_AC_URL(ac){
return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL()
}
97. Method or closure? (cont’d)
‣ In Protein.groovy, consider the static method that turn ac into a url
static def UNIPROT_AC_URL(ac){
return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL()
}
‣ Problem : “I have no network (and that’s ok for testing purpose for example)
and I want to modify the behavior without modifying Protein class itself. I
have downloaded a list of fasta files in a local directory”
98. Method or closure? (cont’d)
‣ In Protein.groovy, consider the static method that turn ac into a url
static def UNIPROT_AC_URL(ac){
return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL()
}
‣ Problem : “I have no network (and that’s ok for testing purpose for example)
and I want to modify the behavior without modifying Protein class itself. I
have downloaded a list of fasta files in a local directory”
‣ A) turn the method into a closure
static def UNIPROT_AC_URL={ac ->
return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL()}
99. Method or closure? (cont’d)
‣ In Protein.groovy, consider the static method that turn ac into a url
static def UNIPROT_AC_URL(ac){
return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL()
}
‣ Problem : “I have no network (and that’s ok for testing purpose for example)
and I want to modify the behavior without modifying Protein class itself. I
have downloaded a list of fasta files in a local directory”
‣ A) turn the method into a closure
static def UNIPROT_AC_URL={ac ->
return “http://www.uniprot.org/uniprot/${ac}.fasta”.toURL()}
‣ B) modify it (in ProteinTest.groovy setup() for example)
Protein.UNIPROT_AC_URL = {ac ->
return (new File("src/practicals/data/fastas/${ac}.fasta")).toURL
}
101. OOP: inheritance
‣ In the practicals from lecture 4, an Enzyme cleaves a Protein and
produces a List<String>
102. OOP: inheritance
‣ In the practicals from lecture 4, an Enzyme cleaves a Protein and
produces a List<String>
‣ Let’s consider it should produces a List<Peptide> where Peptide
consists in
- field String sequence
- field Protein parentProtein
- field int startPosition
- method int getLength()
- method double getMass() (with the same caching as for the Protein)
103. Inheritance (cont’d)
‣ Solution A: create a file Peptide.groovy strongly copied from
Protein.groovy
104. Inheritance (cont’d)
‣ Solution A: create a file Peptide.groovy strongly copied from
Protein.groovy
‣ Problems:
- lot of code is duplicated, thus bugs and test
- not easy to read
- modifying a functionality (think of getMass() caching) should be done
105. Inheritance (cont’d)
‣ Solution A: create a file Peptide.groovy strongly copied from
Protein.groovy
‣ Problems:
- lot of code is duplicated, thus bugs and test
- not easy to read
- modifying a functionality (think of getMass() caching) should be done
Protein Peptide
accessionCode sequence
sequence parentProtein
downloadFasta(ac) startPosition
getLength() toString()
getMass() getLength()
compareTo(o) toString() getMass()
compareTo(o)
106. Inheritance (cont’d)
‣ Solution A: create a file Peptide.groovy strongly copied from
Protein.groovy
‣ Problems:
- lot of code is duplicated, thus bugs and test
- not easy to read
- modifying a functionality (think of getMass() caching) should be done
Protein common part Peptide
accessionCode sequence parentProtein
downloadFasta(ac) getLength() startPosition
toString() getMass() toString()
compareTo(o) compareTo(o)
108. Inheritance (cont’d)
‣ Instead of having two classes, we can have a third one
class AminoAcidSequence implements Comparable{
String sequence
int getLength(){...}
double getMass(){...}
int compareTo(o){...}
}
109. Inheritance (cont’d)
‣ Instead of having two classes, we can have a third one
class AminoAcidSequence implements Comparable{
String sequence
int getLength(){...}
double getMass(){...}
int compareTo(o){...}
}
‣ Then create Protein & Peptide classes that will inherit from
AminoAcidSequence + add their own field & methods
class Peptide extends AminoAcidSequence{
Protein parentProtein
int startPosition
String toString(){...}
}
111. Inheritance (cont’d)
‣ All the methods of the parent class are visible by the a derived class
instance
Peptide pept
...
double m = pept.mass
println pept.startPosition
112. Inheritance (cont’d)
‣ All the methods of the parent class are visible by the a derived class
instance
Peptide pept
...
double m = pept.mass
println pept.startPosition
‣ If a method is redefined by a derived class, it takes the precedence (e.g.
toString())
113. Inheritance (cont’d)
‣ All the methods of the parent class are visible by the a derived class
instance
Peptide pept
...
double m = pept.mass
println pept.startPosition
‣ If a method is redefined by a derived class, it takes the precedence (e.g.
toString())
‣ We can access to the ancestor class method: e.g. compareTo(o), from
the Protein point of view, takes into account the accessionCode, which
to do not exist at AminoAcidSequence Level:
def int compareTo(o){
return super.compareTo(o)?:
(accessionCode <=> o.accessionCode)
Editor's Notes
\n
horizontal learning\n
you can search case insensitve with -iname \n-exec rm {} \\;\n\n\n
you can search case insensitve with -iname \n-exec rm {} \\;\n\n\n
you can search case insensitve with -iname \n-exec rm {} \\;\n\n\n
you can search case insensitve with -iname \n-exec rm {} \\;\n\n\n
read the function shortcuts and try to memorize your most commons\nmaybe my shortcut are mac oriented\n
read the function shortcuts and try to memorize your most commons\nmaybe my shortcut are mac oriented\n
8% of the remaining is spent inbugging\n
8% of the remaining is spent inbugging\n
8% of the remaining is spent inbugging\n
it consist in all language and can be more or less evolved\nhalt means the program stop but is still alive and can proceed\nexploring an object can necessitate a complex rendering (big matrix, 3D structure...)\ndifference between\n
it consist in all language and can be more or less evolved\nhalt means the program stop but is still alive and can proceed\nexploring an object can necessitate a complex rendering (big matrix, 3D structure...)\ndifference between\n
it consist in all language and can be more or less evolved\nhalt means the program stop but is still alive and can proceed\nexploring an object can necessitate a complex rendering (big matrix, 3D structure...)\ndifference between\n
it consist in all language and can be more or less evolved\nhalt means the program stop but is still alive and can proceed\nexploring an object can necessitate a complex rendering (big matrix, 3D structure...)\ndifference between\n
\n
\n
use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
use shortcuts to move on\nF6, F7 F8\nin some condition, edit code during execution\ngo for demo!\n
writing the code is often not a one-off process\n
writing the code is often not a one-off process\n
writing the code is often not a one-off process\n
writing the code is often not a one-off process\n
writing the code is often not a one-off process\n
\n
a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
a file Protein.groovy is created\npackage & class file are only directories & files => no magic, use any text editor\n
\n
\n
setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
setter /getter with java standard\nno properties with reserved word\nif needed access to field directly through gui.@name\n
\n
\n
Example: Integer.MAX_VALUE\n
Example: Integer.MAX_VALUE\n
Example: Integer.MAX_VALUE\n
much simpler than java\n
much simpler than java\n
much simpler than java\n
much simpler than java\n
method < 10 statements\n
method < 10 statements\n
method < 10 statements\n
method < 10 statements\n
method < 10 statements\n
\n
\n
\n
but writing setter in that manner is very common\n
but writing setter in that manner is very common\n
but writing setter in that manner is very common\n
but writing setter in that manner is very common\n
several thousand of additional and mass def lookup for each protein mass...\n
several thousand of additional and mass def lookup for each protein mass...\n
several thousand of additional and mass def lookup for each protein mass...\n
several thousand of additional and mass def lookup for each protein mass...\n
if without curly bracket => execute only the next statement\n
if without curly bracket => execute only the next statement\n
if without curly bracket => execute only the next statement\n
\n
\n
Go to lecture 4 practicals for more example\n
Go to lecture 4 practicals for more example\n
Go to lecture 4 practicals for more example\n
Go to lecture 4 practicals for more example\n
Go to lecture 4 practicals for more example\n
Go to lecture 4 practicals for more example\n
Go to lecture 4 practicals for more example\n
we do not take into account here the check on enz class.\n
we do not take into account here the check on enz class.\n
we do not take into account here the check on enz class.\n
interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
interface is a way to say that object from a class implements certain features\nif .sort is called with Comparable objects, it can react accordingly\n
\n
\n
\n
\n
\n
This was into the download method, but it can be defined statically outside\napplied here to static, but idem with dynamic methods\nclosing curly bracket on the same line just for the slide...\n
This was into the download method, but it can be defined statically outside\napplied here to static, but idem with dynamic methods\nclosing curly bracket on the same line just for the slide...\n
This was into the download method, but it can be defined statically outside\napplied here to static, but idem with dynamic methods\nclosing curly bracket on the same line just for the slide...\n
This was into the download method, but it can be defined statically outside\napplied here to static, but idem with dynamic methods\nclosing curly bracket on the same line just for the slide...\n
\n
\n
we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
we must focus on writing the less code possible, to have the less possible opportunities to inbug\ntoString() are not in common\nforget species for space reasons\n
if AminoAcidSequence has no meaning to exist by itself (maybe), it could be declared Abstract\n
if AminoAcidSequence has no meaning to exist by itself (maybe), it could be declared Abstract\n
we do not talk about visibility\ntoString() exist from the Object class point of view, which is an ancestor of AminoAcid\n
we do not talk about visibility\ntoString() exist from the Object class point of view, which is an ancestor of AminoAcid\n
we do not talk about visibility\ntoString() exist from the Object class point of view, which is an ancestor of AminoAcid\n