59
1 public class HelloWorld { 2 public static void main(String[] args) { 3 print "Epic Fail" 4 } 5 }

Java VS Python

Embed Size (px)

Citation preview

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 PiWiPy

MicroPython

Cal

colo

Sci

entifi

co

Desktop

Games

@decorators

__metaclass__

generators yield

lambdacontext managers

list comprehension

mixinclosures

descriptors

auto(un)boxing

streams

lambdatry-with-resources

method referencesdefaults 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_decoratedef 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 inspectfor 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@contextmanagerdef 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()

@contextmanagerdef 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 - 5mult3 = 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): passclass C1_20(HasMethod1, UsesMethod20): passclass C2_10(HasMethod2, UsesMethod10): passclass C2_20(HasMethod2, UsesMethod20): pass

assert C1_10().usesMethod() == 11assert C1_20().usesMethod() == 21assert C2_10().usesMethod() == 12assert C2_20().usesMethod() == 22

__mro__

defaults interface methodsinterface 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(); }}

unpackingdef 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. apple1. banana2. cabbage

>>> def table_things(**kwargs):... for name, value in kwargs.items():... print '{0} = {1}'.format(name, value)...>>> table_things(apple = 'fruit', cabbage = 'vegetable')cabbage = vegetableapple = 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)}

propertiesclass 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.num1234>> 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-1a[start:] # items start through the rest of the arraya[:end] # items from the beginning through end-1a[:] # a copy of the whole arrayThere 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 arraya[-2:] # last two items in the arraya[:-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