Pratyush Mittal
Hobby coder and a stock investor.

Uberspace - Shared web hosting

I love Uberspace for hosting websites on a shared server.

While I use VPS (AWS, Linode or DigitalOcean) for larger projects, I still love shared hosting because they are batteries included. They are pre-configured with firewalls, databases, nginx, apache, memcache and SSL.

Shared servers also have much more (shared) CPU resources than a fixed CPU capacity in a VPS. My earlier websites on (1GB ram - shared cpu - $5/month) performed much better than on DigitalOcean (2GB ram - 2CPU - $10/month). Primary reason was that though the CPU on Webfaction was shared with neighbours, it was of much much larger capacity.

Thus it all boils down to how a shared hosting provider allocates the neighbours. UberSpace rocks at this.

I didn't find the resource allocation part on UberSpace website. Here are the details of that:

Disk space: 10 GB (can be expanded)
RAM: 1.5 GB
CPU: Shared as available. But restricted to 6 (

On pricing: they provide a pay what you want model :)

I love to write functions instead of classes. However, Django does not allow us to call functions inside templates.

Sometimes we want to postpone the function calls in templates because they might be expensive. Thus we might want to call them inside the template’s cache fragment or inside an if statement.

My way around them is to use a lazy_cache function to postpone and cache a function's result.

Thus the whole usage is something like this:

import datetime as dt
from utilities.functional import lazy_cached

def expensive_computation(result_date, page_number=1):
    # do some expensive stuff
    return results

def latest_results(request):
    result_date =
    page_number = request.GET.get('page')
    results = lazy_cached(

    return render(
            "results": results,
            "page_number": page_number,

In templates we can now do:

{% load cache %}

{% block content %}
{% cache 30000 results_page page_number %}
{% for result in results %}
    <div>{ { }}</div>
{% endfor %}
{% endcache %}

My recipe for lazy_cached function is:

def lazy_cached(func, *args, **kwargs):
    state = {"value": None, "realized?": False}

    def wrap():
        if state["realized?"]:
            return state["value"]
        state["value"] = func(*args, **kwargs)
        state["realized?"] = True
        return state["value"]

    return wrap

Showing sender image (logo) in transactional emails - BIMI Implementation

We usually see a sender's photo in Gmail. Those sender avatars are shown not only for our friends and known contacts, but also for transactional emails.

I often wondered how they are shown. They look good and provide a better clue about the sender.

Turns out there is a "BIMI" (Brand Indicators for Message Identification) spec for that. It requires DMARC compliance and then a DNS record pointing to the SVG image.


Problems of being a solo developer

I would describe my work like single-handedly running a restaurant in an old château. It’s cool and fun, and the ambiance is great, but occasionally the soup is served cold or not at all because I have to chase a bunch of bats out of the kitchen, or replace a collapsed beam, while the diners sit and wait. This is no fun for either me or the diners, who rightfully complain that it ruins their dinner. Having more paying users would let me hire some dedicated carpenters and and bat-chasers that would let me focus on the cooking.

Rules of card game Judgement (or President)

My family loves to play this card game. It is much like coat-piece but less dependent on luck. Plus it allows any number of people to play together.

I was not aware of the official rules around scoring. We gave 10 points to everyone with the right prediction. But linking of points to number of hands predicted is an interesting twist.

How to play

  1. Each Player gets 1 card in Level 1, 2 cards in Level 2 and so on
  2. Trump type changes on every level. In rotational order of Spade, Diamond, Club & Heart.
  3. Each Player need to predict wins in the level before first player throws card
  4. Each player throws one card, first player's card decides the type other players should throw, highest card player wins the round
  5. If player don't have same type card then Trump type could be thrown and that takes precedence, if player don't have Trump type card then any card can be thrown
  6. Each player that wins exact same rounds as predicted, wins the level
  7. Every Level winning player will get 10 + predicted win points. eg if predicted win was 2, player gets 10 + 2 = 12 points
  8. Player with the highest total points in the score card wins.
« first previous
Page 4 of 59.
next last »