Language agnostic REPL driven development with Visual Studio Code



A few years ago I was using Light Table, the integration with Clojure REPL was so nice. But the other parts of the editor and other languages support weren’t that good. And at the moment the editor looks almost dead.

After that, for Clojure, I switched to Cursive, and I still use it. It has a nice feature – send to REPL, which allows users to execute selected code in REPL. But it’s Clojure/ClojureScript only and requires some hassle to configure.

Nowadays for some stuff, I use Visual Studio Code. It doesn’t have a nice integration with REPL, but it has integrated terminal. So I thought, wouldn’t it be nice to just open any REPL in a terminal and somehow send selected code to the REPL. Without any configuration, even with REPL on a remote server.

So I wrote a little extension – SendToREPL. In action with Python REPL:

How does it work? Let’s look at the initial version of the extension:

const vscode = require('vscode');
let terminal;

function activate(context) {
    terminal = vscode.window.createTerminal('SendToREPL terminal');
    terminal.show();

    const command = vscode.commands.registerTextEditorCommand('extension.sendToREPL', (textEditor) => {
        const code = textEditor.document.getText(textEditor.selection);
        terminal.sendText(code);
    });

    context.subscriptions.push(command);
}

exports.activate = activate;

function deactivate() {
    if (terminal) {
        terminal.dispose();
    }
}

exports.deactivate = deactivate;

It just creates a terminal when extension loaded and registers extension.sendToREPL command. When the command is triggered (by Ctrl+’/Cmd+’ hotkey or from Quick Open) it gets selected code and sends it to the terminal.

The current version is a bit more advanced, it sends the line with cursor if nothing selected and squash code in one line for some languages e.g. Perl.

Marketplace, github.

Michael Feathers: Working Effectively with Legacy Code



book cover Recently I wanted to read something about refactoring and about working with not so good code, so I decided to read Working Effectively with Legacy Code by Michael Feathers. And it seems to be a good book, it contains a lot of recipes and techniques for making the code more testable, for removing dependencies and for making the code better generally.

Although the book is a bit too OOPish and a bit old, I think it’s still useful.

Change iTerm2 tab and window title colors depending on ssh host



At my work, I use macOS with iTerm2 as a terminal. And iTerm2 has fancy escape codes for changing tab and window titles colors:

\033]6;1;bg;red;brightness;255\a
\033]6;1;bg;green;brightness;255\a
\033]6;1;bg;blue;brightness;255\a

So I thought that it will be nice to distinguish different ssh hosts by color. I found on Stack Overflow how to generate color from a string and wrote a python script that extracts host from command line arguments and prints fancy sequences:

#!/usr/bin/python

import sys


def get_host():
    for arg in sys.argv[1:]:
        if not arg.startswith('-'):
            return arg


def str_to_color(s):
    hash = 0
    for c in s:
        hash = ord(c) + ((hash << 5) - hash)

    for i in range(3):
        yield (hash >> (i * 8)) & 0xff


def generate_seqs(color):
    seq = '\033]6;1;bg;{};brightness;{}\a'
    names = ['red', 'green', 'blue']
    for name, v in zip(names, color):
        yield seq.format(name, v)


if __name__ == '__main__':
    host = get_host()
    if host:
        color = str_to_color(host)
        for seq in generate_seqs(color):
            sys.stdout.write(seq)

In action:

➜ ./ssh_color.py mrw.wtf
]6;1;bg;red;brightness;173]6;1;bg;green;brightness;84]6;1;bg;blue;brightness;51

Now we need to create a bash/zsh function that will call our script, run ssh and reset color on exit:

ssh_color () {
    ssh_color.py $*  # I put script in /usr/local/bin/
    trap 'echo -e "\033]6;1;bg;*;default\a"' INT EXIT
    ssh $*
}

alias ssh=ssh_color

And it just works:

screenshot

Nigel Poulton: The Kubernetes Book



book cover white Recently I decided to read something more about Kubernetes and found The Kubernetes Book by Nigel Poulton. And I’ve made a wrong choice because it’s an introductory book explaining basic concepts with very simple examples.

I don’t know, maybe it’s a good book to start working with Kubernetes.

Jim Webber, Ian Robinson, Emil Eifrem: Graph Databases



book cover white Recently I wanted to read something about graph databases and in the Humble Book Bundle, I found Graph Databases by Jim Webber, Ian Robinson and Emil Eifrem. The book is mostly focused on neo4j but has a bit of information about other databases. It has examples of graph data models and real world use cases, also the book contains an information about theoretical parts and neo4j internals. And there’s a lot about Cypher language.

Although in some chapters the book can be described by anything’s a graph if you’re brave enough.

Building a graph of flights from airport codes in tweets



A lot of people (at least me) tweet airports codes like PRG ✈ AMS before flights. So I thought it will be interesting to draw a directed graph of flights and airports. Where airports are nodes and flights are edges.

First of all, I created a twitter application, authorized my account within it and got all necessary credentials:

TWITTER_CONSUMER_KEY = ''
TWITTER_CONSUMER_SECRET = ''
TWITTER_ACCESS_TOKEN = ''
TWITTER_ACCESS_TOKEN_SECRET = ''
USER_ID = ''

As a special marker I chose airplane emoji:

MARKER = '✈'

Then I tried to receive all my tweets with that marker but stuck with a huge problem, twitter REST API doesn’t work with emojis in a search query. So I decided to receive a whole timeline and filter it manually. So only the last 3200 tweets will be parsed. Working with twitter API is very easy with tweepy:

import tweepy


def get_tweets():
    auth = tweepy.OAuthHandler(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET)
    auth.set_access_token(TWITTER_ACCESS_TOKEN, TWITTER_ACCESS_TOKEN_SECRET)
    api = tweepy.API(auth)
    cursor = tweepy.Cursor(api.user_timeline,
                           user_id=USER_ID,
                           exclude_replies='true',
                           include_rts='false',
                           count=200)
    return cursor.items()
>>> for tweet in get_tweets():
...     print(tweet)
... 
Status(_api=<tweepy.api.API object at 0x7f876a303ac8>, ...)

Then I filtered tweets with in its text:

flight_texts = (tweet.text for tweet in get_tweets()
                if MARKER in tweet.text)
>>> for text in flight_texts:
...     print(text)
...
ICN ✈️ IKT
IKT ✈️ ICN
DME ✈️ IKT

As some tweets may contain more than one flight, like LED ✈ DME ✈ AUH, it’s convenient to extract all three letter parts and build flights like LED ✈ DME and DME ✈ AUH:

def get_flights(text):
    parts = [part for part in text.split(' ') if len(part) == 3]
    if len(parts) < 2:
        return []

    return zip(parts[:-1], parts[1:])


flights = [flight for text in flight_texts
           for flight in get_flights(text)]
uniq_flights = list(set(flights))
>>> uniq_flights
[('ICN', 'IKT'), ('IKT', 'ICN'), ('DME', 'IKT')]

From edges in uniq_flights it’s very easy to get all nodes:

airports = [airport for flight in flights
            for airport in flight]
uniq_airports = list(set(airports))
>>> uniq_airports
['ICN', 'IKT', 'DME']

So now it’s possible to create a graph with networkx and draw it with matplotlib:

import networkx
from matplotlib import pyplot


graph = networkx.DiGraph()
graph.add_nodes_from(uniq_airports)
graph.add_edges_from(uniq_flights)
networkx.draw(graph, with_labels=True, node_size=1000)
pyplot.draw()
pyplot.show()

The graph is very ugly:

But it’s simple to improve it by using different colors depending on nodes and edges weight, and by using graphviz.

from collections import Counter
from matplotlib import cm


def get_colors(all_records, uniq_records):
    counter = Counter(all_records)
    max_val = max(counter.values())
    return [counter[record] / max_val
            for record in uniq_records]


networkx.draw(graph, 
              with_labels=True,
              node_size=1000,
              width=1.5,
              pos=networkx.nx_pydot.graphviz_layout(graph, prog='neato'),
              cmap=cm.get_cmap('Pastel1'),
              edge_cmap=cm.get_cmap('Pastel2'),
              edge_color=get_colors(flights, uniq_flights),
              node_color=get_colors(airports, uniq_airports))
pyplot.draw()
pyplot.show()

So now it’s much nicer:

Gist with sources.

Baron Schwartz, Peter Zaitsev, Vadim Tkachenko: High Performance MySQL



book cover white Apart from using Cloud SQL, I haven’t touched MySQL for a while, so I decided to freshen up things and read High Performance MySQL by Baron Schwartz, Peter Zaitsev, and Vadim Tkachenko. The book feels solid, it explains how MySQL works (and worked before) inside, what problems storage engines/parser/optimizer/etc have and how to leverage them. It’s kind of nice that a big part of the book is about MySQL scaling. And it’s also good that the book has a lot of information about troubleshooting, debugging, profiling and some MySQL related tools.

Although the book is probably a bit outdated, it covers MySQL versions up to 5.5, but nowadays the latest version is 5.7.

A year in Prague



Prague

From September 2016 to August 2017 I was living in Prague, it was almost a year. I was studying the Czech language there because I was planning to continue my education and finish university here. But I decided that studying and working full time simultaneously is too much for me, so I’m moving to the Netherlands for work. Got B2 in Czech language and got accepted to two universities in Prague though.

I was living in the country with a student visa. CR student visa is fairly easy to obtain, it just requires confirmation from a university and around €5000 on a bank account. With this kind of visa, you can entry Czech Republic multiple times and travel all over Schengen Area.

Because I was studying, I managed to live in a students campus, but in something like an apartment, but with a shared kitchen for 7500 CZK (€300). The only problem that it was far away from the city center. But the city is not too big, and as a student, I’ve got a travel card almost for free. So the location wasn’t a big problem.

Internet was included in my rent, I had something around 50 Mbit/s. Mobile internet and mobile operators in the Czech Republic are the worst. I was using Vodafone and initially, I was paying 519 CZK (€20) for 4GB, but somehow in June this option disappeared and I started to pay 399 CZK (€15) for just 1.5GB.

Food is cheap there, I was spending around 800 CZK (€30) per week for everyday chicken/meat/fish. Although in Prague there’s very small selection of fish and almost no seafood. The booze is very cheap there, 15-25 CZK (€0.5-1) for a fairly good beer in a supermarket and around 30 CZK (€1.2) in a pub.

Summing up everything, Prague is a very nice city with a lot of cultures, attractions, and events. It’s in the middle of Europe and it’s very easy to travel from there. And I kind of glad that I was living there.

AR* Geolocation Snake



instruction     gameplay

I like rollerskating, but sometimes it’s kind of boring to skate by the same routes. I was using Pokemon GO for making the route more fun, but pokestops have fixed locations and catching the pokemons after a few months is kind of boring too. So I thought that it can be interesting to randomly select places to skate. And snake game makes it even more interesting and challenging because I need to select a more complex route for avoiding snake’s tail and not losing the game.

Although sometimes the app puts candies on the other side of the road or requires me to ride on a sidewalk with intolerable quality, I solved it with an option to regenerate the candy.

TLDR: the app, source code.

What’s inside

The app is written in JavaScript with flow, React Native and redux with redux-thunk. For the map, I used react-native-maps which are nice, because it works almost out of the box. So mostly the game is very simple.

The first challenging part is candies generation. As a first attempt the app uses nearby search from Google Places API (hah, it’s already deprecated) with a specified radius, filters places with the radius greater than minimal and selects random place. As we can’t just use coordinates for filtering by distance, I used node-geopoint library.

const generateCandyFromPlacesNearby = async (
  position: Position,
): Promise<?Position> => {
  const positionPoint = new GeoPoint(position.latitude, position.longitude);

  const response = await fetch(
    "https://maps.googleapis.com/maps/api/place/nearbysearch/json?" +
      `location=${position.latitude},${position.longitude}` +
      `radius=${config.CANDY_MAX_DISTANCE}`,
  );
  const { results } = await response.json();

  const availablePositions = results.filter(({ geometry }) => {
    const point = new GeoPoint(geometry.location.lat, geometry.location.lng);

    return positionPoint.distanceTo(point, true) > constants.CANDY_MIN_DISTANCE;
  });

  return sample(availablePositions);
};

If there’s no place with appropriate distance in the specified radius, the app just chooses a random latitude and longitude offset within specified bounds.

const generateCandyFromRandom = (position: Position): Position => {
  const point = new GeoPoint(position.latitude, position.longitude);
  const [minNE, minSW] = point.boundingCoordinates(
    constants.CANDY_MIN_DISTANCE,
    undefined,
    true,
  );
  const [maxNE, maxSW] = point.boundingCoordinates(
    constants.CANDY_MAX_DISTANCE,
    undefined,
    true,
  );

  switch (random(3)) {
    case 0:
      return {
        latitude: random(minNE.latitude(), maxNE.latitude()),
        longitude: random(minNE.longitude(), maxNE.longitude()),
      };
    case 1:
      return {
        latitude: random(minSW.latitude(), maxSW.latitude()),
        longitude: random(minNE.longitude(), maxNE.longitude()),
      };
    case 2:
      return {
        latitude: random(minNE.latitude(), maxNE.latitude()),
        longitude: random(minSW.longitude(), maxSW.longitude()),
      };
    default:
      return {
        latitude: random(minSW.latitude(), maxSW.latitude()),
        longitude: random(minSW.longitude(), maxSW.longitude()),
      };
  }
};

And the last complicated part is detecting if the player touches snake’s tail. As we store tail as a list of coordinates, the game just checks if the head within aspecified radius of the tail parts.

export const isTouched = (
  a: Position,
  b: Position,
  radius: number,
): boolean => {
  const aPoint = new GeoPoint(a.latitude, a.longitude);
  const bPoint = new GeoPoint(b.latitude, b.longitude);

  return aPoint.distanceTo(bPoint, true) <= radius;
};

export const isSnakeTouchedHimself = (positions: Position[]): boolean =>
  some(positions.slice(2), position =>
    isTouched(positions[0], position, constants.SNAKE_TOUCH_RADIUS),
  );

Play Store, Github.

* like Pokemon GO without a camera.