Nicolò Andronio

Nicolò Andronio

Full-stack developer, computer scientist, engineer
Evil Genius in the spare time

13 kinds of developer you will meet in your career

Developers have strong views and beliefs in their code. Everyone thinks differenly and thus writes codes in a different way. Sometimes it’s fun to step back and enjoy the diversity among all the styles that, even within the same language, proliferate against all linting rules. I belong to several of these categories. Which ones do you think mirrors yours the most?

The functionally inclined

When I grow up I want to be an Haskell developer!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public List<Trigger> getTriggersForFunction(String functionName) throws IOException {
return Optional.ofNullable(execute("get", "list"))
.map(Output::getStdOutLines)
.orElse(Collections.emptyList())
.skip(1)
.map(ROW_PARSER::matcher)
.filter(Matcher::matches)
.map(m -> Trigger.builder()
.name(m.group("triggerName"))
.functionName(m.group("functionName"))
.build())
.filter(t -> t.getFunctionName().equals(functionName))
.collect(Collectors.toList());
}

The stateful tester

He doesn’t like parallel tests

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class AccountTest {
private User poorGuy = new User(1, "Tommy", "Broke");
private User richGuy = new User(2, "John", "Rich");
private User veryBrokeGuy = new User(3, "Dundy", "Debtsworn");

private Account emptyAccount = new Account(11, poorGuy, Currency.euros(0));
private Account fullAccount = new Account(17, richGuy, Currency.dollars(10_000_000));
private Account negativeAccount = new Account(19, veryBrokeGuy, Currency.yen(-5000));

private static final Bank BANK = new Bank(42);
private static final String BANK_ID = 42;

@Before
public void setUp() {
given(BANK.getUser(1)).willReturn(poorGuy);
given(BANK.getUser(2)).willReturn(richGuy);
given(BANK.getUser(3)).willReturn(veryBrokeGuy);

given(BANK.getAccount(11)).willReturn(emptyAccount);
given(BANK.getAccount(17)).willReturn(fullAccount);
given(BANK.getAccount(19)).willReturn(negativeAccount);
}

@Test(expected = YouAreBrokeException.class)
public void testWithdrawlFromEmptyAccount() {

BANK.setOpen(true);
BANK.withdraw(1, Currency.dollars(50));
}

@Test(expected = WaitUntilMondayException.class)
public void testCurrencyExchangeWhenBankIsClosed() {

BANK.setOpen(false);
BANK.exchange(2, Currency.pounds(67), Corrency.DOLLARS);
}
}

The code compressor

Blank lines? What are those?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class DataViewComponent extends React.Component<Props> {
openDeleteDialog=()=>this.props.actions.openDialog({type:'delete',name:this.props.tableName,id:this.props.tableId});
openExportDialog=()=>this.props.actions.openDialog({type:'export',name:this.props.tableName,id:this.props.tableId});
render() {
const {tableId,tableName,metadataError,location,...routeProps}=this.props;
if(metadataError&&metadataError.response&&metadataError.response.status===404){
return(<NotFoundPage location={location}/>);
}else if(metadataError){
return(<Page><ErrorMessage error={metadataError} center/></Page>);
}else if(!hasMetadata){
return (<Page pad center verticalCenter><Spinner/><br/>Loading table</Page>);
}
return (<Page toolbar={<DataToolbarContainer {...routeProps} tableId={null||tableId} doDelete={this.openDeleteDialog} doExport={this.openExportDialog}/>}
footer={<DataFooterContainer {...routeProps} tableId={tableId}/>}
drawer={getSection('drawer',{ ...routeProps,tableId:null||tableId})}
pad={views[routeProps.viewId].pad}
warning={tableId&&<React.Fragment>You are viewing a sub-table of <Link to={`/data/${tableId}`} style={{paddingLeft:4}}><Icon icon={icons.data}/> {tableName}</Link></React.Fragment>}>
{getSection('content',{...routeProps,tableId:null||tableId})}
</Page>);
}
}

The wrapper

Why have one short method when you can have four shorter methods?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public Status getApiStatus(String name) throws ApiException {
return getApiStatus(new Reference(true, name));
}

private Status getApiStatus(Reference reference) throws ApiException {
return buildRequest(GET, String.format("/v1/%s/", reference.urlEncode()), Status.class);
}

private <T> T buildRequest(HttpMethod method, String path, Class<T> responseType) throws ApiException {
return buildRequest(method, path, null, configuration.getAdminKey(), responseType);
}

private <T> T buildRequest(HttpMethod method, String path, Object body, Class<T> responseType) throws ApiException {
return buildRequest(method, path, body, configuration.getAdminKey(), responseType);
}

private <S, T> T buildRequest(HttpMethod method, String path, S body, String apiKey, Class<T> responseType) throws ApiException {
try {
String url = configuration.getBaseUrl() + path;
HttpHeaders headers = new HttpHeaders();
headers.set(API_KEY_HEADER, apiKey);

HttpEntity<S> entity = new HttpEntity<>(body, headers);
return restTemplate.exchange(url, method, entity, responseType).getBody();
} catch (Exception e) {
throw new ApiException(e);
}
}

The master cloner

Just mass producing code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
it('has correct loadUser action', () => {
app.clearActions();
result.props.actions.loadUser();
expect(app.getActions()[0].type).toEqual('mock loadUser');
});

it('has correct editUser action', () => {
app.clearActions();
result.props.actions.editUser();
expect(app.getActions()[0].type).toEqual('mock editUser');
});

it('has correct loadBookmarks action', () => {
app.clearActions();
result.props.actions.loadBookmarks();
expect(app.getActions()[0].type).toEqual('mock loadBookmarks');
});

it('has correct editBookmarks action', () => {
app.clearActions();
result.props.actions.editBookmarks();
expect(app.getActions()[0].type).toEqual('mock editBookmarks');
});

The carriage-return guy

Never once he went beyond 70 characters per line

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class DataReference(BaseReference):
def __init__(
self,
data_id: int,
data_service: DataService,
is_preview: bool = False,
) -> None:

self.data_id = data_id
self.data_service = data_service
self.is_preview = is_preview

def get_metadata_for_column(
self,
col_data: pd.Series,
col_meta: ColumnMetadata
) -> Iterator[ColumnAnnotation]:

multiplier = self.extract_multiplier(col_data)
alpha_coefficient = len(col_data) - self.base_count

if (
multiplier > self._MULTIPLIER_THRESHOLD
and alpha_coefficient < self._ALPHA_COEFFICIENT
):
examples = [
value for value, _ in self.variant_table(col_data)
]
examples = examples[
1 : self._MAX_EXAMPLES_TO_SHOW + 1
]

message = messages.ColumnNearlyConstant(
col_meta.name,
alpha_coefficient,
row_count_without_alpha=len(col_data),
row_count_with_alpha=len(col_data) * multiplier,
examples_of_values=examples,
)

yield message

Captain obvious

He writes obvious comments. Duh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* Gets the shares of an user.
*/

function getShares (user) {
// If the user does not exist, return an empty array
if (!userRepository.exists(user)) {
return [];
}

// Find the shares
const shares = sharesRepository.findByUser(user.id);

// Return the shares
return shares;
}

The reflection enthusiast

We have to go deeper!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
private static Object instantiate(Class<?> klass) throws Exception {
Constructor<?>[] constructors = klass.getConstructors();

if (constructors.length == 0) {
constructors = klass.getDeclaredConstructors();
}

if (constructors.length == 0) {
throw new RuntimeException(String.format("%s has no constructors", klass.getSimpleName()));
}

Constructor<?> constructor = constructors[0];
Object[] args = Arrays.stream(constructor.getParameterTypes())
.map(OstrichTest::getDefaultValue)
.toArray();

return constructor.newInstance(args);
}

private static Object getDefaultValue(Class<?> type) {
if (!type.isPrimitive()) {
return null;
} else {
return Defaults.defaultValue(type);
}
}

The webdev from the late 2000s

People are still trying to get rid of jQuery to this day

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$('button[type=submit]').click(function (e) {
e.preventDefault();

$(this).parent().find('li.item').each(function () {
$.ajax({
type: 'POST',
url: url,
data: data,
beforeSend: function() {
$(this).addClass('loading');
},
success: function (data) {
if (data) {
$(this).html(data);
} else {
$(this).html('<em>Item was present but empty</em>');
}
},
error: function(xhr) { // if error occured
alert("An error occured. Please try again");
$(this).unbind('click')
.removeClass('loading')
.html('Click to inspect the error')
.click(function () {
$(this)
.append(xhr.statusText + xhr.responseText)
.unbind('click');
});
},
complete: function() {
$(this).removeClass('loading');
},
dataType: 'html'
});
});
})

The thief

He’s not even using hazelcast in there…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.CriteriaSpecification;
import javax.persistence.Entity;
import javax.persistence.Column;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.cli.AlreadySelectedException;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Lists.newArrayList;
import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.config.XmlClientConfigBuilder;
import com.hazelcast.config.Config;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

The passive aggressive

You don’t want to piss him off during code review

1
2
3
4
5
6
7
8
9
10
11
function* generatePoints (startingPoint) {
// Now for the third time, I won't refactor this again.
// I am not sure who exactly thinks that overriding Function.apply
// locally is a good idea (because CLEARLY it isn't). I can only hope
// that with time people will start to see the utter and complete
// USELESSNESS of the former code; which makes us lose time and increases
// our technical debt. I am not blaming anyone, here. Just saying that
// you SHOULD NOT touch this function ever again. Period.

...
}

The mathematician

Gotta get those formulas right

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def compute_weights(m, x0, x, dtype='float_'):
n = len(x)
if m >= n:
raise Exception('length of x must be larger than m')

x=np.asanyarray(x)
w = np.zeros((m+1,n), dtype=dtype)
w[0,0] = 1.
b = 1.
for i in range(1,n):
beta = np.prod(x[i]-x[0:i])
for k in range(0,min(i,m)+1):
w[k,i] = b*(k*w[k-1,i-1]-(x[i-1]-x0)*w[k,i-1])/beta
b=beta
for j in range(0,i):
for k in range(min(i,m),-1,-1):
w[k,j] = ((x[i]-x0)*w[k,j]-k*w[k-1,j])/(x[i]-x[j])

w[np.absolute(w)<1e-10] = 0
return w

The jester

He’s a funny guy through and through

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Terminator {
@Autowired
private EntityRepository timeMachine;

@Scheduled(timeString = "${losAngeles1984:2029}")
public void terminateTargets() {
List<Entity> potentialVictims = timeMachine.findAll();
Entity sarahConnor = null;

for (Entity entity : potentialVictims) {
if (entity.shouldBeTerminated()) {
sarahConnor = entity;
break;
}
}

if (sarahConnor != null) {
this.weaponize().fireAt(sarahConnor);
}
}
}