Notes from “Programming Elixir”
Single Script Pattern in Groovy and Style Suggestion
Introduction
In some cases, Groovy scripts are loaded (by script engine of the hosted application server) as a single piece and have no dependency to other shared libraries. In this situation, the scripts need to be self-contained with both application code and support code. How to split these two parts of code and how to make use of Groovy’s dynamic language features is the main topic of this blog. There are also some suggestions of what is good code style about Groovy (for Java programmers).
Memo of Design Data-intensive Applications
It’s a summary and abstraction of “Design Data-intensive Applications” (DDIA), which is an excellent book covering a vast majority domain of database administration and distribute systems.
Python for Java Programmer - 2
Intermediate Level
Question | Answer |
---|---|
01.Create simple class | collections.namedtuple (see code) |
02.__str__ VS __repr__ |
str() calls the latter when the former is missing. |
03.Why exclude the last item when sclicing | One reason is lst[:n] + lst[n:] == lst |
04.Variables created inside listcomp | They exist after listcomp |
05.Application of score to grade | bisect.bisect (see code) |
06.Counterpart of Map::computeIfAbsent |
dict.setdefault |
07.Tricky way to handle missing key for a dict | __getitem__ fallback to __missing__ . So implement the latter accordingly. |
08.Check the existing of an attribute in instance method | hasattr(self, 'xxx') |
09.Closure and nested function | Local variables in outer function are free variables for inner function. When inner function returns as return value, free variables captured as closure. |
10.Local variables in the current scope | locals() built-in function to return a dict |
11.is operator VS == | is is faster in that it compares id, while == could be overrided in user type with __eq__ |
12.Mutable object used as default value of function parameter | Default value evaluated once when function is defined. So the instance of default value is shared among methods from different instances and therefore is dangerous. |
13.Things can keep unexpected references so as to prevent objects from destroying | _ and Traceback object. |
14.Quickly compare multiple variables | tuple(this) == tuple(other) |
15.Another way of hash code generation other than odd prime 31 and 17 | xor |
1 | # 01 |
reference
Fluent Python 2015.7
Python for Java Programmer - 1
Tips of Anaconda installation
For Anaconda distribution, this (mirror)[https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/] could be faster than the official.
(numpy tutorial)[https://docs.scipy.org/doc/numpy-dev/user/quickstart.html]
matrix with Jupyter1
2
3
4
5
6
7
8
9%matplotlib inline
import sympy as sympy
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sbn
from scipy import *
A = np.array(([.8,.3],[.2,.7]))
A.dot(x1)
Language Basic
Question | Answer |
---|---|
01.Access the last element of a list | aList[-1] // it can be interpreted as aList[len(aList)-1] |
02.Remove an element from a list | previousLastOne = aList.pop() or del aList[-1] The first one can get the removed one. |
03.Is it accessible for a (loop) variable after the loop (e.g. for ele in elements:) | Sadly, it is (e.g. ele). How to get rid of it? (del ele , ugly workaround) |
04.How to turn a range object to a list | list(range(1,5)) // range() returns a range object (iterable) and passed to list() to become a list |
05.How to slice a list | aList[-3:] // obviously here : needs specific syntax support |
06.Find if an element exists in a list/string | element in aList or sub_string in aString // it returns a boolean, a syntax keyword |
07.How to check empty string/list | if aList: or if aString: // empty string/list is false in for and if |
08.Loop through a dictionary | for k, v in aDict.items() |
09.Provide a description to a function/class/module | Put """...""" (docstring) below a function/class or at the beginning of a module |
10.Flexible number of function parameters | def foo(p, *pa): // put *pa after positioned parameters |
11.Flexible number of named parameters | def foo(**user_info) // Note the call side doesn’t need to create a dictionary to use user_info (see source code) |
12.Import a function with another name from a module | from a_module import function_a as function_b |
13.Arrange function parameters in multiple lines | use two TAB to make parameters look different from function body (see source code) |
14.Call methods of super class | super().__init__(...) |
15.Open a file without closing it explicitly | with open('file_name') as file_object: |
16.Loop through file object line by line | for line in file_object: |
17.Exception handling | try-except-else-finally block. Use pass in except branch to fail silently. |
18.Is there concept of Option | No. None is same as null. |
19.Check if variable is None | a is None // is not is to check the opposite |
20.Unpack sequence | a,b,*_ = ("foo","bar",1,2) // _ => [1,2] |
21.Performance of list insert, pop and in | For non-last element, it’s O(n) while n is the size of the list |
22.For loop with index | for i,value in enumerate(seq): |
23.Convert a list of rows into a list of columns | zip(*seq) //see source code |
24.Objects can be put in dictionary as key | number, string, tuple (immutable) or anything else has fixed value of hash(obj) |
25.Nested for comprehension | [v2 for v1 in s1 if ... for v2 in v1 if ...] |
26.Variable scope | There are two scopes: local and global. class, function can create nested scope, but not if/for/while. |
27.Currying | from functools import partial and partial(foo, some_variable) |
28.Generator in for comprehension | (x for x in ... if ...) or use yield in generator function |
29.Anonymous function | lambda x: x[0] |
30.Generator from itertools | groupby, combinations, product, permutations, etc. |
31.Catch multiple errors | except (TypeError, ValueError): |
1 | // 11 |
reference
Async in action
Multithreading, Parallel and Async
Multithreading
A form of concurrency that uses multiple threads of execution.
Thread
, BackgroundWorker
, low-level, best to start with high-level abstractions like thread pool.
Parallel
Divide work among multiple threads that run concurrently.
Maximize the use of multiple processors of CPU. In most cases, work against built-in parallelism on server-side.
Async
Use futures or callbacks to avoid unnecessary threads.
Composition over inheritance
For many programmers of younger generation, career started with object-oriented programming. And modern languages provide easy ways to create objects (and destroy them after the use). As a result, programs are pushed to the limit to make use of encapsulation and polymorphism and therefore sometimes tend to be unnecessarily complicated and hard to maintain. Let’s use an example to illustrate when and when not to (over)use object-oriented programming.
Memorizer
What is the problem
Continue with the last topic about domain model, there is a performance problem. See the code:
1 | public Supplier<List<Person>> femaleMembers() { |
Given the same groupName, if femaleMembers is invoked by more than one place within the same transaction, it will trigger the query each time even when the result is almost identical. So how to improve the performance?
Domain Model in Practice
What is the problem
Suppose we have domain models like this:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Person {
ID id;
PersonName name;
Gender gender;
}
class Mail {
Address address;
MailGroup group;
ID? idOfOwner;
}
class MailGroup {
String name;
Person[] admin;
}
One day, product owner asked me to do a story with the following requirement:
Given a mail group, list female owners of mail addresses in this group. The list should exclude the admin of this mail group for whatever reason.
Data Provider with Currying
What is the problem
Suppose we have a Person model like this:1
2
3
4
5
6
7
8class Person {
private ID id;
private PersonName name;
private BirthDate dateOfBirth;
private TransactionalDate lastModified;
private List<Contact> contacts;
...
}
Something additional about the way of modeling. I could create the same Person in this way:1
2
3
4
5
6
7class Person {
private long id;
private String name;
private Date dateOfBirth;
private Date lastModified;
...
}
The benefit of using ID, PersonName and BirthDate instead of long, String and Date respectively is that:
- These basic types could be very likely reused in other models. Having a separate definition gives them a place to hold their own business logic other than the generic type shipped with language library. For example, ID is a numeric long greater than zero (due to the fact of incremental primary key in database). ID could have a property ‘Empty’ to indicate the data has not been persisted yet, which is better than using expression
if (id > 0)
that leaks too much technical details. And for BirthDate, we can apply a constraint on it due to the limit of human being’s age; while for TransactionalDate, it could have a default value as the current date, which represents the timing of a business transaction. - Less possibility of using a wrong field because most fields have a different type so that compiler can easily detect such error. That’s where the misleading practice, ‘Don’t use the same type for different fields when modeling a business object’, comes from.
And in application code we need to send person data to an external service like this:1
2externalService.consumePerson(long personID, String name, Date birthDate, ...);
externalService.consumePersonAndContact(long personID, String name, List<ContactInfo> contacts, ...);
Note external service has a slightly different understanding of person data. What’s more, different services ask for different data. How to do this with clean code?