Journey from static to dynamic (Java to Python)

Via this blog, I want to inspiring developers who have plan to learn. It also covers all pros and cons of Python in many aspects, from philosophy to OOP design, from library to handy shortcut.

Because Python go from one person project, it philosophy quite effective. The main target is make things fast, keep it simple, and do it good enough. Like sentences below:
Borrow ideas from elsewhere whenever it makes sense.
“Things should be as simple as possible, but no simpler.” (Einstein)
Do one thing well (The "UNIX philosophy").
Don’t fret too much about performance--plan to optimize later when needed.
Don’t fight the environment and go with the flow.
Don’t try for perfection because “good enough” is often just that.

The beauty of Python
"The Zen of Python" - Wrote by Tim Peter, main contributor of Python.
  “Beautiful is better than ugly.
   Explicit is better than implicit.
   Simple is better than complex.
   Complex is better than complicated.

   Flat is better than nested.
   Sparse is better than dense.
   Readability counts.
   Special cases aren't special enough to break the rules.

   Although practicality beats purity.
   Errors should never pass silently.
   Unless explicitly silenced.
   In the face of ambiguity, refuse the temptation to guess.
   There should be one-- and preferably only one --obvious way to do it.
   Although that way may not be obvious at first unless you're Dutch.

   Now is better than never.
   Although never is often better than *right* now.
   If the implementation is hard to explain, it's a bad idea.
   If the implementation is easy to explain, it may be a good idea.
   Namespaces are one honking great idea -- let's do more of those!”

Why python is beautiful
Easy to learn and understand
I cannot stress enough how beautiful it feels to code in Python because of its neat flawless syntax. There are no braces for you to keep on continually balancing, white spaces and tabs automatically do it for you , also are no semicolons to remember.

``` JAVA
public class HelloWorld {
   public static void main (String[] args) {
       System.out.println("Hello, world!");
   }
}
```

``` PYTHON
print("Hello, world!")
```

Lean project structure
Multiple public classes can be defined in a single file. If your application has 15 classes, the entire code base could be stored in a single file. Same thing in Java forces you to create all 15 files.

Dynamic typing
In Python, you never declare anything. An assignment statement binds a name to an object, and the object can be of any type. If a name is assigned to an object of one type, it may later be assigned to an object of a different type. Python container objects also (e.g. lists and dictionaries) can hold objects of any type. When you retrieve an object from a container, it remembers its type, so no casting is required.

OOP with multiple inheritances
Python has been an object-oriented language since it existed. Because of this, creating and using classes and objects are downright easy. Java single inheritance is a pain, you must know and use Abstract Class and Interface for a good design structure. Python is object-oriented language to core, cause pretty much everything is an object, whether it is a number, a function… or even None, True or False.

``` JAVA
interface Moveable {
   default void move(){
       System.out.println("I am moving fast, buddy !!");
   }
}
 
interface Crawlable {
   default void crawl(){
       System.out.println("I am crawling !!");
   }
}
 
public class Animal implements Moveable, Crawlable {
   public static void main(String[] args) {
       Animal self = new Animal();
       self.move();
       self.crawl();
   }
}
```

``` PYTHON
class Moveable:
   def move(self):
       print("I am moving fast, buddy !!")

class Crawlable:
   def crawl(self):
       print("I am crawling !!")

class Animal(Moveable, Crawlable):
   def do(self):
       self.move()
       self.crawl()

animal = Animal()
animal.do()
```

Easy to create objects
No more creating an ocean of constructor functions before coding the real important thing. With list argument, key-word argument, default value in Python avoid function overloading problem. List argument is used to send a non-keyworded variable length argument list to the function. Key-word argument allows you to pass keyworded variable length of arguments to a function. Python also provides support for default argument values, that is function arguments that can either be specified by the caller or left blank to automatically receive a predefined value.

``` JAVA
public class Employee {
   private String myEmployeeName;
   private int    myTaxDeductions = 1;
   private String myMaritalStatus = "single";

   public Employee(String EmployeName) {
       this(employeeName, 1);
   }

   public Employee(String EmployeName, int taxDeductions) {
      this(employeeName, taxDeductions, "single");
   }

   public Employee(String EmployeName, int taxDeductions, String maritalStatus) {
      this.employeeName    = employeeName;
      this.taxDeductions   = taxDeductions;
      this.maritalStatus   = maritalStatus;
   }
...
```

``` PYTHON
class Employee():
   def __init__(self, employee_name, tax_deductions=1, marital_status="single"):
       self.employee_name    = employee_name
       self.tax_deductions   = tax_deductions
       self.marital_status   = marital_status
...
```

Awesome set of Libraries
Python’s standard library is very extensive, library contains built-in modules (written in C) that provide access to system functionality such as file I/O that would otherwise be inaccessible to Python programmers, as well as modules written in Python that provide standardized solutions for many problems that occur in everyday programming.
You also have rich set of libraries to choose from image processing, or natural language processing, or web scraping. These libraries come with excellent documentation.

Syntactic sugar
Swapping Variables
```
x = 6
y = 5
x, y = y, x
```

Inline if Statement
```
a =  "Hello" if True else "World"
```

Numerical Comparison
```
if 3 > x > 1:
   print x
```

Iterate Through Two Lists at the Same Time
```
nfc = ["Packers", "49ers"]
afc = ["Ravens", "Patriots"]
for teama, teamb in zip(nfc, afc):
   print teama + " vs. " + teamb
```

List Comprehension
``` # print element which is even
numbers = [1,2,3,4,5,6]
even = [number for number in numbers if number%2 == 0]
```

Dictionary Comprehension
```
teams = ["Packers", "49ers", "Ravens", "Patriots"]
print {key: value for value, key in enumerate(teams)}
```

Converting a List to a String
```
teams = ["Packers", "49ers", "Ravens", "Patriots"]
print ", ".join(teams)
```

Start a http web server
```
python -m SimpleHTTPServer
```

Great productivity
So programs don’t need to compile before run, code don’t need braces, variable type much more flexible, … With all of these advantages above, most of us will be more much more productive and happier.

The hard & pain
With static programming language, everything so easy to understand, to learn without magic. But with dynamic:
  • Lack of static typing gives programmers headaches. Actually is hard to know which type will return from a complex function. Or which line will raise TypeError in run time.
  • Lack of performance for performance-critical applications or feel bad with Global Interpreter Lock? “In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython's memory management is not thread-safe so that it prevents multithreaded CPython programs from taking full advantage of multiprocessor systems in certain situations”, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once.” - From Python Wiki


Our rules to live with dynamic life
  • Features separated into, core library, data access service, business logic, API.
  • Code coverage must be greater than 95 percent, or you feature branch will stay at your local forever! Automation test tool will mark these branch as build fail.
  • Every feature branch must be reviewed with at least two round, one from team members and final from our CTO.