1 public class HelloWorld { 2 public static void main(String[] args) { 3 print "Epic Fail" 4 } 5 }
1991 1996 2015 1989 1991 2015
X
OOP AOP FP OOP AOP FP
Simple is better than complex. Complex is better than complicated.
50% XML
100% Python
Complex session replication systems just for a presentation logic is totally stupid
JVM Threads PVM Processes
Concurrency
"write once, run anywhere" (WORA)
Raspberry Pi WiPy MicroPython
CalcoloScientifico
Desktop
Games
@decorators __metaclass__ generators yield lambda context managers list comprehension mixin closures descriptors auto(un)boxing streams lambda try-with-resources method references defaults interface methods @annotation/metadata unpacking getter/setterproperties
def p_decorate(func): def func_wrapper(name): return "<p>{0}</p>".format(func(name)) return func_wrapper @p_decorate def get_text(name): return "lorem ipsum, {0} dolor sit amet".format(name) print get_text("John") # Outputs <p>lorem ipsum, John dolor sit amet</p> Logging Timing Aspects(AOP) Mocking/Testing @decorators
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { public boolean enabled() default true; } public class T { @Test(enabled = false) void testB() { throw new RuntimeException("This test always passed"); } } public class M { public static void main(String[] args) throws Exception { for (Method method : T.class.getDeclaredMethods()) { if (method.isAnnotationPresent(Test.class)) { Annotation annotation = method.getAnnotation(Test.class); Test test = (Test) annotation; if (test.enabled()) { method.invoke(obj.newInstance()); }}}}} @annotation/metadata/reflection Logging Timing Aspects(AOP) Mocking/Testing
inspect/dir/dict class T: def test(): raise Exception("ciao") test.enabled = True import inspect for name, method in inspect.getmembers(T, inspect.ismethod): if getattr(method, 'enabled', False): method(T()) for val in T.__dict__.values(): if callable(val) and getattr(method, 'enabled', False): val(T())
generators def firstn(n): num = 0 while num < n: yield num num += 1 sum_of_first_n = sum(firstn(1000000)) sum_of_first_n = sum(range(1000000)) sum_of_first_n = sum(xrange(1000000)) def fib(): a,b = 0,1 while True: yield a b = a+b yield b a = a+b asynchronous low memory infinite
streams IntStream natural = IntStream.iterate(0, i -> i + 1); natural.limit(10000).sum(); LongStream fibs = Stream.iterate( new long[]{1, 1}, f -> new long[]{f[1], f[0] + f[1]}) .mapToLong(f -> f[0]);
context managers @contextmanager def opened(filename, mode="r"): f = open(filename, mode) try: yield f finally: f.close() with opened("/etc/passwd") as f: for line in f: print line.rstrip() class released: def __init__(self, lock): self.lock = lock def __enter__(self): self.lock.release() def __exit__(self, type, value, tb): self.lock.acquire() @contextmanager def tag(name): print "<%s>" % name yield print "</%s>" % name >>> with tag("h1"): ... print "foo" ... <h1> foo </h1>
try-with-resources try(FileInputStream input = new FileInputStream("file.txt")) { int data = input.read(); while(data != -1){ System.out.print((char) data); data = input.read(); } } try (Connection conn = ds.getConnection(); Statement stmt = conn.createStatement()) { stmt.execute(insertsql); try (ResultSet rs = stmt.executeQuery(selectsql)) { rs.next(); } } public interface AutoClosable { public void close() throws Exception; }
lambda f = lambda x, y : x + y f = lambda x: x**2 + 2*x - 5 mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9]) square_rt = lambda x: math.sqrt(x) def sqroot(x): return math.sqrt(x) Celsius = [39.2, 36.5, 37.3, 37.8] Fahrenheit = map(lambda x: (float(9)/5)*x + 32, Celsius) reduce(lambda x,y: x+y, [47,11,42,13]) sorted(list, key=lambda i: i.last_name)
lambda (int a, int b) -> { return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } () -> 42 () -> { return 3.1415 }; Runnable r = () -> System.out.println("hello world"); new Thread( () -> System.out.println("hello world”) ).start(); Consumer<Integer> c = (int x) -> { System.out.println(x) }; BiConsumer<Integer, String> b = (Integer x, String y) -> System.out.println(x + " : " + y); Predicate<String> p = (String s) -> { s == null }; Arrays.asList(1,2,3,4,5,6,7).stream().map((x) -> x*x).forEach(System.out::println); Static Typing needs a interface with a single method
method references // Comparator Arrays.sort(rosterAsArray, (a, b) -> Person.compareByAge(a, b) ); Arrays.sort(rosterAsArray, Person::compareByAge); /* * ClassName::staticMethodName * object::instanceMethodName * ContainingType::methodName * ClassName::new */
closures def generate_power_func(n): print "id(n): %X" % id(n) def nth_power(x): return x**n print "id(nth_power): %X" % id(nth_power) return nth_power raised_to_4 = generate_power_func(4) del generate_power_func raised_to_4.__closure__ raised_to_4.__closure__[0].cell_contents
mixin class HasMethod1(object): def method(self): return 1 class HasMethod2(object): def method(self): return 2 class UsesMethod10(object): def usesMethod(self): return self.method() + 10 class UsesMethod20(object): def usesMethod(self): return self.method() + 20 class C1_10(HasMethod1, UsesMethod10): pass class C1_20(HasMethod1, UsesMethod20): pass class C2_10(HasMethod2, UsesMethod10): pass class C2_20(HasMethod2, UsesMethod20): pass assert C1_10().usesMethod() == 11 assert C1_20().usesMethod() == 21 assert C2_10().usesMethod() == 12 assert C2_20().usesMethod() == 22 __mro__
defaults interface methods interface InterfaceA { public void saySomething(); default public void sayHi() { System.out.println("Hi"); } } interface InterfaceB { default public void sayHi() { System.out.println("Hi from InterfaceB"); } } public class MyClass implements InterfaceA, InterfaceB { @Override public void saySomething() { System.out.println("Hello World"); } @Override public void sayHi() { //System.out.println("implemetation of sayHi() in MyClass"); InterfaceA.super.sayHi(); } }
unpacking def my_function(): return 1, 2 a, b = my_function() a = my_function()[0] import datetime t= (2010, 10, 2, 11, 4, 0, 2, 41, 0) dt = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], t[6]) t = (2010, 10, 2, 11, 4, 0, 2, 41, 0) dt = datetime.datetime(*t[:7]) >>> def parrot(voltage, state='a stiff', action='voom'): ... print "-- This parrot wouldn't", action, ... print "if you put", voltage, "volts through it.", ... print "E's", state, "!" ... >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} >>> parrot(**d) -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
public void show(String message){ } public void show(String message, boolean show){ } public void show(Integer message){ } // does not compile! public boolean show(String message){ return false; } overloading methods
*args, **kwargs >>> def print_everything(*args): for count, thing in enumerate(args): ... print '{0}. {1}'.format(count, thing) ... >>> print_everything('apple', 'banana', 'cabbage') 0. apple 1. banana 2. cabbage >>> def table_things(**kwargs): ... for name, value in kwargs.items(): ... print '{0} = {1}'.format(name, value) ... >>> table_things(apple = 'fruit', cabbage = 'vegetable') cabbage = vegetable apple = fruit class Foo(object): def __init__(self, value1, value2): # do something with the values print value1, value2 class MyFoo(Foo): def __init__(self, *args, **kwargs): # do something else, don't care about the args print 'myfoo' super(MyFoo, self).__init__(*args, **kwargs)
varargs… public class HelloWorldVarargs { public static void main(String args[]) { test(215, "India", "Delhi"); test(147, "United States", "New York", "California"); } public static void test(int some, String... args) { System.out.print("n" + some); for(String arg: args) { System.out.print(", " + arg); } } } class Logger { void error(Marker marker, String message, Object... params) }
properties class Celsius(object): def __init__(self, temperature = 0): self._temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 @property def temperature(self): print("Getting value") return self._temperature @temperature.setter def temperature(self, value): if value < -273: raise ValueError("Temperature below -273 is not possible") print("Setting value") self._temperature = value celsius = Celsius(10) celsius.temperature = 300
getter/setter public class User { private String name; public String getName() { return this.name; } public void setName(String name) { this.name = name; } } set accessible=True frameworks conventions
descriptors class Foo(object): name = TypedProperty("name",str) num = TypedProperty("num",int,42) >> acct = Foo() >> acct.name = "obi" >> acct.num = 1234 >> print acct.num 1234 >> print acct.name obi # trying to assign a string to number fails >> acct.num = '1234' TypeError: Must be a <type 'int'> class TypedProperty(object): def __init__(self, name, type, default=None): self.name = "_" + name self.type = type self.default = default if default else type() def __get__(self, instance, cls): return getattr(instance, self.name, self.default) def __set__(self,instance,value): if not isinstance(value,self.type): raise TypeError("Must be a %s" % self.type) setattr(instance,self.name,value) def __delete__(self,instance): raise AttributeError("Can't delete attribute")
list comprehension >>> S = [x**2 for x in range(10)] >>> V = [2**i for i in range(13)] >>> M = [x for x in S if x % 2 == 0] >>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)] >>> primes = [x for x in range(2, 50) if x not in noprimes] >>> print primes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] >>> words = 'The quick brown fox jumps over the lazy dog'.split() >>> stuff = [[w.upper(), w.lower(), len(w)] for w in words] ['THE', 'the', 3] ['QUICK', 'quick', 5] ... l = [['40', '20', '10', '30'], ['20', '20', '20'], ['100', '100'], ['100', '100', '100']] [[float(y) for y in x] for x in l] >>> d = {n: n**2 for n in range(5)} >>> print d {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
list slicing a[start:end] # items start through end-1 a[start:] # items start through the rest of the array a[:end] # items from the beginning through end-1 a[:] # a copy of the whole array There is also the step value, which can be used with any of the above: a[start:end:step] # start through not past end, by step a[-1] # last item in the array a[-2:] # last two items in the array a[:-2] # everything except the last two items
factory: class inside a function >>> def class_with_method(func): ... class klass: pass ... setattr(klass, func.__name__, func) ... return klass ... >>> def say_foo(self): print 'foo' ... >>> Foo = class_with_method(say_foo) >>> foo = Foo() >>> foo.say_foo() >>> from new import classobj >>> Foo2 = classobj('Foo2',(Foo,),{'bar':lambda self:'bar'}) >>> Foo2().bar() 'bar' >>> Foo2().say_foo() foo # metaclass >> X = type('X',(),{'foo':lambda self:'foo'}) >>> X, X().foo() (<class '__main__.X'>, 'foo')
__metaclass__ >>> class Printable(type): ... def whoami(cls): print "I am a", cls.__name__ ... >>> Foo = Printable('Foo',(),{}) >>> Foo.whoami() I am a Foo >>> Printable.whoami() Traceback (most recent call last): TypeError: unbound method whoami() [...] >>> class Bar: ... __metaclass__ = Printable ... def foomethod(self): print 'foo' ... >>> Bar.whoami() I am a Bar >>> Bar().foomethod() foo # metaclass magic methods # def __new__(cls, name, bases, dict): # def __init__(self, name, bases, dict):
boolean b = false; Double d1 = 0d; Double d2 = null; Double d = b ? d1.doubleValue() : d2; long value = (Long) null; long propertyValue = (Long) obj.getProperty(propertyModel.getName()); auto(un)boxing NPE a gogo
Refactoring Testing
Java VS Python

Java VS Python

  • 1.
    1 public classHelloWorld { 2 public static void main(String[] args) { 3 print "Epic Fail" 4 } 5 }
  • 5.
  • 6.
  • 9.
  • 15.
    Simple is betterthan complex. Complex is better than complicated.
  • 16.
  • 17.
  • 20.
    Complex session replicationsystems just for a presentation logic is totally stupid
  • 22.
  • 23.
  • 25.
    "write once, runanywhere" (WORA)
  • 26.
  • 28.
  • 29.
  • 30.
  • 32.
    @decorators __metaclass__ generators yield lambda context managers listcomprehension mixin closures descriptors auto(un)boxing streams lambda try-with-resources method references defaults interface methods @annotation/metadata unpacking getter/setterproperties
  • 33.
    def p_decorate(func): def func_wrapper(name): return"<p>{0}</p>".format(func(name)) return func_wrapper @p_decorate def get_text(name): return "lorem ipsum, {0} dolor sit amet".format(name) print get_text("John") # Outputs <p>lorem ipsum, John dolor sit amet</p> Logging Timing Aspects(AOP) Mocking/Testing @decorators
  • 34.
    @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test{ public boolean enabled() default true; } public class T { @Test(enabled = false) void testB() { throw new RuntimeException("This test always passed"); } } public class M { public static void main(String[] args) throws Exception { for (Method method : T.class.getDeclaredMethods()) { if (method.isAnnotationPresent(Test.class)) { Annotation annotation = method.getAnnotation(Test.class); Test test = (Test) annotation; if (test.enabled()) { method.invoke(obj.newInstance()); }}}}} @annotation/metadata/reflection Logging Timing Aspects(AOP) Mocking/Testing
  • 35.
    inspect/dir/dict class T: def test(): raiseException("ciao") test.enabled = True import inspect for name, method in inspect.getmembers(T, inspect.ismethod): if getattr(method, 'enabled', False): method(T()) for val in T.__dict__.values(): if callable(val) and getattr(method, 'enabled', False): val(T())
  • 36.
    generators def firstn(n): num= 0 while num < n: yield num num += 1 sum_of_first_n = sum(firstn(1000000)) sum_of_first_n = sum(range(1000000)) sum_of_first_n = sum(xrange(1000000)) def fib(): a,b = 0,1 while True: yield a b = a+b yield b a = a+b asynchronous low memory infinite
  • 37.
    streams IntStream natural =IntStream.iterate(0, i -> i + 1); natural.limit(10000).sum(); LongStream fibs = Stream.iterate( new long[]{1, 1}, f -> new long[]{f[1], f[0] + f[1]}) .mapToLong(f -> f[0]);
  • 38.
    context managers @contextmanager def opened(filename,mode="r"): f = open(filename, mode) try: yield f finally: f.close() with opened("/etc/passwd") as f: for line in f: print line.rstrip() class released: def __init__(self, lock): self.lock = lock def __enter__(self): self.lock.release() def __exit__(self, type, value, tb): self.lock.acquire() @contextmanager def tag(name): print "<%s>" % name yield print "</%s>" % name >>> with tag("h1"): ... print "foo" ... <h1> foo </h1>
  • 39.
    try-with-resources try(FileInputStream input =new FileInputStream("file.txt")) { int data = input.read(); while(data != -1){ System.out.print((char) data); data = input.read(); } } try (Connection conn = ds.getConnection(); Statement stmt = conn.createStatement()) { stmt.execute(insertsql); try (ResultSet rs = stmt.executeQuery(selectsql)) { rs.next(); } } public interface AutoClosable { public void close() throws Exception; }
  • 40.
    lambda f = lambdax, y : x + y f = lambda x: x**2 + 2*x - 5 mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9]) square_rt = lambda x: math.sqrt(x) def sqroot(x): return math.sqrt(x) Celsius = [39.2, 36.5, 37.3, 37.8] Fahrenheit = map(lambda x: (float(9)/5)*x + 32, Celsius) reduce(lambda x,y: x+y, [47,11,42,13]) sorted(list, key=lambda i: i.last_name)
  • 41.
    lambda (int a, intb) -> { return a + b; } () -> System.out.println("Hello World"); (String s) -> { System.out.println(s); } () -> 42 () -> { return 3.1415 }; Runnable r = () -> System.out.println("hello world"); new Thread( () -> System.out.println("hello world”) ).start(); Consumer<Integer> c = (int x) -> { System.out.println(x) }; BiConsumer<Integer, String> b = (Integer x, String y) -> System.out.println(x + " : " + y); Predicate<String> p = (String s) -> { s == null }; Arrays.asList(1,2,3,4,5,6,7).stream().map((x) -> x*x).forEach(System.out::println); Static Typing needs a interface with a single method
  • 42.
    method references // Comparator Arrays.sort(rosterAsArray, (a,b) -> Person.compareByAge(a, b) ); Arrays.sort(rosterAsArray, Person::compareByAge); /* * ClassName::staticMethodName * object::instanceMethodName * ContainingType::methodName * ClassName::new */
  • 43.
    closures def generate_power_func(n): print "id(n):%X" % id(n) def nth_power(x): return x**n print "id(nth_power): %X" % id(nth_power) return nth_power raised_to_4 = generate_power_func(4) del generate_power_func raised_to_4.__closure__ raised_to_4.__closure__[0].cell_contents
  • 44.
    mixin class HasMethod1(object): defmethod(self): return 1 class HasMethod2(object): def method(self): return 2 class UsesMethod10(object): def usesMethod(self): return self.method() + 10 class UsesMethod20(object): def usesMethod(self): return self.method() + 20 class C1_10(HasMethod1, UsesMethod10): pass class C1_20(HasMethod1, UsesMethod20): pass class C2_10(HasMethod2, UsesMethod10): pass class C2_20(HasMethod2, UsesMethod20): pass assert C1_10().usesMethod() == 11 assert C1_20().usesMethod() == 21 assert C2_10().usesMethod() == 12 assert C2_20().usesMethod() == 22 __mro__
  • 45.
    defaults interface methods interfaceInterfaceA { public void saySomething(); default public void sayHi() { System.out.println("Hi"); } } interface InterfaceB { default public void sayHi() { System.out.println("Hi from InterfaceB"); } } public class MyClass implements InterfaceA, InterfaceB { @Override public void saySomething() { System.out.println("Hello World"); } @Override public void sayHi() { //System.out.println("implemetation of sayHi() in MyClass"); InterfaceA.super.sayHi(); } }
  • 46.
    unpacking def my_function(): return 1,2 a, b = my_function() a = my_function()[0] import datetime t= (2010, 10, 2, 11, 4, 0, 2, 41, 0) dt = datetime.datetime(t[0], t[1], t[2], t[3], t[4], t[5], t[6]) t = (2010, 10, 2, 11, 4, 0, 2, 41, 0) dt = datetime.datetime(*t[:7]) >>> def parrot(voltage, state='a stiff', action='voom'): ... print "-- This parrot wouldn't", action, ... print "if you put", voltage, "volts through it.", ... print "E's", state, "!" ... >>> d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"} >>> parrot(**d) -- This parrot wouldn't VOOM if you put four million volts through it. E's bleedin' demised !
  • 47.
    public void show(Stringmessage){ } public void show(String message, boolean show){ } public void show(Integer message){ } // does not compile! public boolean show(String message){ return false; } overloading methods
  • 48.
    *args, **kwargs >>>def print_everything(*args): for count, thing in enumerate(args): ... print '{0}. {1}'.format(count, thing) ... >>> print_everything('apple', 'banana', 'cabbage') 0. apple 1. banana 2. cabbage >>> def table_things(**kwargs): ... for name, value in kwargs.items(): ... print '{0} = {1}'.format(name, value) ... >>> table_things(apple = 'fruit', cabbage = 'vegetable') cabbage = vegetable apple = fruit class Foo(object): def __init__(self, value1, value2): # do something with the values print value1, value2 class MyFoo(Foo): def __init__(self, *args, **kwargs): # do something else, don't care about the args print 'myfoo' super(MyFoo, self).__init__(*args, **kwargs)
  • 49.
    varargs… public class HelloWorldVarargs{ public static void main(String args[]) { test(215, "India", "Delhi"); test(147, "United States", "New York", "California"); } public static void test(int some, String... args) { System.out.print("n" + some); for(String arg: args) { System.out.print(", " + arg); } } } class Logger { void error(Marker marker, String message, Object... params) }
  • 50.
    properties class Celsius(object): def __init__(self,temperature = 0): self._temperature = temperature def to_fahrenheit(self): return (self.temperature * 1.8) + 32 @property def temperature(self): print("Getting value") return self._temperature @temperature.setter def temperature(self, value): if value < -273: raise ValueError("Temperature below -273 is not possible") print("Setting value") self._temperature = value celsius = Celsius(10) celsius.temperature = 300
  • 51.
    getter/setter public class User{ private String name; public String getName() { return this.name; } public void setName(String name) { this.name = name; } } set accessible=True frameworks conventions
  • 52.
    descriptors class Foo(object): name =TypedProperty("name",str) num = TypedProperty("num",int,42) >> acct = Foo() >> acct.name = "obi" >> acct.num = 1234 >> print acct.num 1234 >> print acct.name obi # trying to assign a string to number fails >> acct.num = '1234' TypeError: Must be a <type 'int'> class TypedProperty(object): def __init__(self, name, type, default=None): self.name = "_" + name self.type = type self.default = default if default else type() def __get__(self, instance, cls): return getattr(instance, self.name, self.default) def __set__(self,instance,value): if not isinstance(value,self.type): raise TypeError("Must be a %s" % self.type) setattr(instance,self.name,value) def __delete__(self,instance): raise AttributeError("Can't delete attribute")
  • 53.
    list comprehension >>> S= [x**2 for x in range(10)] >>> V = [2**i for i in range(13)] >>> M = [x for x in S if x % 2 == 0] >>> noprimes = [j for i in range(2, 8) for j in range(i*2, 50, i)] >>> primes = [x for x in range(2, 50) if x not in noprimes] >>> print primes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] >>> words = 'The quick brown fox jumps over the lazy dog'.split() >>> stuff = [[w.upper(), w.lower(), len(w)] for w in words] ['THE', 'the', 3] ['QUICK', 'quick', 5] ... l = [['40', '20', '10', '30'], ['20', '20', '20'], ['100', '100'], ['100', '100', '100']] [[float(y) for y in x] for x in l] >>> d = {n: n**2 for n in range(5)} >>> print d {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
  • 54.
    list slicing a[start:end] #items start through end-1 a[start:] # items start through the rest of the array a[:end] # items from the beginning through end-1 a[:] # a copy of the whole array There is also the step value, which can be used with any of the above: a[start:end:step] # start through not past end, by step a[-1] # last item in the array a[-2:] # last two items in the array a[:-2] # everything except the last two items
  • 55.
    factory: class insidea function >>> def class_with_method(func): ... class klass: pass ... setattr(klass, func.__name__, func) ... return klass ... >>> def say_foo(self): print 'foo' ... >>> Foo = class_with_method(say_foo) >>> foo = Foo() >>> foo.say_foo() >>> from new import classobj >>> Foo2 = classobj('Foo2',(Foo,),{'bar':lambda self:'bar'}) >>> Foo2().bar() 'bar' >>> Foo2().say_foo() foo # metaclass >> X = type('X',(),{'foo':lambda self:'foo'}) >>> X, X().foo() (<class '__main__.X'>, 'foo')
  • 56.
    __metaclass__ >>> class Printable(type): ...def whoami(cls): print "I am a", cls.__name__ ... >>> Foo = Printable('Foo',(),{}) >>> Foo.whoami() I am a Foo >>> Printable.whoami() Traceback (most recent call last): TypeError: unbound method whoami() [...] >>> class Bar: ... __metaclass__ = Printable ... def foomethod(self): print 'foo' ... >>> Bar.whoami() I am a Bar >>> Bar().foomethod() foo # metaclass magic methods # def __new__(cls, name, bases, dict): # def __init__(self, name, bases, dict):
  • 57.
    boolean b =false; Double d1 = 0d; Double d2 = null; Double d = b ? d1.doubleValue() : d2; long value = (Long) null; long propertyValue = (Long) obj.getProperty(propertyModel.getName()); auto(un)boxing NPE a gogo
  • 58.