FML

(locals().get('FML', locals().update(FML=lambda: FML(), sys=__import__('sys')) is locals().update(__=sys.setrecursionlimit(666))))()  # #FML

Setting variable in recipe based on another variable value in Makefile

I have a Makefile which needs to run Python 2 and 3 with same recipe for identical process. The only difference should only be the command names of Python versions. Since they are virtually the same, I rather not having two recipes just for sake of different command names.

Yesterday, I pushed an update that wasn’t quite okay by me, but I was working on a fix for a bug. Although it’s not really an urgent situation, still, the feeling of getting everything done and pushing out to the world as soon as possible got to me pretty good.

I am okay with using subst just not the part of expanding variable in target name. I feared that could be running into troubles someday. I am not good at writing Makefile, only learn as I go. Today, time finally allowed me sitting down and starting with an empty Makefile to study how it could be done better.

Here is the final result I am okay with:

py2=python2
py3=python3

if: if_py2 if_py3 if_unknown
if_py2 if_py3 if_unknown:
        @echo target is $@
        $(eval py_cmd = \
                $(if $(findstring py2,$@),\
                        $(py2),\
                        $(if $(findstring py3,$@),\
                                $(py3),\
                                $(error Do not know what to do \
                                        with $@)\
                        )\
                )\
        )
        @echo '$$py_cmd' is set to $(py_cmd)
        @echo

At first glance, it looks like terribly long, indeed, it is. The output would be:

$ make
target is if_py2
$py_cmd is set to python2

target is if_py3
$py_cmd is set to python3

Makefile:9: *** Do not know what to do with if_unknown.  Stop.

If could be just one-liner, but I prefer to have that error even the target names are specifically typed.

Another solution I could come up with is double expansion:

py2=python2
py3=python3

double_expand: double_expand_py2 double_expand_py3
double_expand_py2 double_expand_py3:
        @echo target is $@
        $(eval py = $(subst double_expand_,,$@))
        @echo '$$py' is set to $(py)
        $(eval py_cmd = $($(py)))
        @echo '$$py_cmd' is set to $(py_cmd)
        @echo

The variable py is expanded twice, first to get the name of the variable containing Python command, then expand it to get the command name. The output:

$ make
target is double_expand_py2
$py is set to py2
$py_cmd is set to python2

target is double_expand_py3
$py is set to py3
$py_cmd is set to python3

When I first tried to simplify during that commit, I was trying to get ifeq to work for me, but never could do that with eval. I think if that’s for shell variable, it would do, but I’d like to set to Make’s variable.

Don’t be that README: lists mistakenly in block quotes

Last month, I had a short discussion with someone about a few funky naming scenarios of README that I dislike. After the chat, an idea has been brewing in me, hence this post title. Hopefully, this would become a series of issues I’ve seen in many README.

For this very first part, it’s lists mistakenly wrapped in block quotes, which happens quite often and many people make such mistake. The following is a GIF of a README, consisting of the rendered results on PyPI and GitHub, plus the relevant reStructuredText source code.

https://lh6.googleusercontent.com/-nz4uepJaLFI/U8s_KG3OXGI/AAAAAAAAGic/x-5Y2jna-eY/s640/Python%2520Wars%2520Solo.gif

The bullet lists are wrapped inside block quotes, which are by mistakes, or simply the lack of the knowledge of reStructuredText and failures to check the rendered results on those websites.

It’s not only happening on README, even on PEPs (Python Enhancement Proposals) with final status as seen in the GIF below.

https://lh4.googleusercontent.com/-yep1DqXtTPM/U8tAhrrOwFI/AAAAAAAAGis/mouVjznBtPs/s640/PEP.gif

When you are not meant to quote lists, you don’t nest lists inside block quotes. All of the cases above are errors by the writers. They are simple to fix, here are a few thoughts:

  • Learn the markup language

    A text block that is indented relative to the preceding text, without preceding markup indicating it to be a literal block or other content, is a block quote.

    reStructuredText Markup Specification

  • Check the rendered results by markup processor locally

    For reStructuredText, you can use rst2html.py to render a HTML to preview in web browser.

  • Check the rendered results on websites

    For README.md on GitHub, get a GRIP.

Somehow, I have a feeling that these people are not only unfamiliar with block quote styles on those websites, but also the HTML, therefore unable to spot the errors.

This type of mistake probably is only possible in reStructuredText, definitely not in Markdown since it requires > to mark a quote, but Markdown has its own share of inexperienced users, stay tuned.

Reviving chk-jtv-lives, which checks live Twitch streams, status, uptime, etc

About two years, after my last mention of chk-jtv-lives.sh, it stopped working. My guess is the changes in API versions causing the cease of functioning.

Yesterday, despite I was having some personal issue, I fired up terminal and extracted its Git history so I could move it to its own repository before I started to port it into a Python 3 code and use latest Twitch API v3 /streams.

The code can be found on Gist, chk-jtv-lives.

In the original Bash script, it would use current user’s login name and look for the favorite channels under the same username on Justin.tv/Twitch.tv, but this Python script is no longer doing that. I keep it as simple as possible, since I don’t actually log in on Twitch anymore.

It’s usage is:

usage: chk-jtv-lives.py [-h] CHANNEL [CHANNEL ...]

You give it a list of channel IDs and it returns a result like:

https://gist.github.com/livibetter/614a080fd08e05d86bb6/raw/chk-jtv-lives.py.png

For a quick comparison from old screenshot of ol’ shell script:

https://gist.github.com/livibetter/614a080fd08e05d86bb6/raw/chk-jtv-lives.sh.png

You can see the currently playing game is added as well as the timestamp in local timezone, the stream uptime is still provided in short form, status is still wrapped.

I saw quite more information could be useful, such as delay and preview images. Although I don’t really think, adding a preview image link would be nice in terminal, perhaps incorporating with Image-to-ASCII conversion would work?

At this moment, I actually use it as an alias with a list of channel IDs after the script name.

chk-jtv-lives is still kept its old license, WTFPL Version 2.