Monday, September 7, 2015

Huawei TalkBand B2 review

Ok, so I've bought a new gadget. It was long overdue because I, being a MediaPad X1 user, sometimes feel uncomfortable pulling that monster of a phone just to check the time on answer a call. Of course, Bluetooth headsets are cheap and abundant but I don't really like the idea of keeping one in my ear all the time. And having it not in the ear usually makes it pretty much unusable. Various wearable gdgets that can show time and some notifications aren't new either, and there are a lot of cheap options, but, again, there are even cheaper watches and I don't care much about fitness tracking (I don't mind it though) and notifications (reading long texts is seldom convenient on a small screen anyway). So when I heard about the new TalkBand that combines watch and wireless headset I was all interested, read reviews, became even more interested, and waited a few weeks only because of the price and availability.

The price, for most people around the world it might seem a little expensive provided it's not loaded with extra features but, thanks to the continuing currency collapse and discounts in my favorite local electronics retail chain, I had to pay less than $100 in cash. Well, not counting the store credit I used, the actual discounted price was more like $130 but it's still $10 cheaper than on aliexpress (or $50 cheaper than on amazon), much faster, and with full warranty and everything. Anyway, in comparison with some cheap but good fitness tracker (about $20) and good headset (about $10) it's very expensive. But...

The main feature is convenience of on-demand headset (with nice additional features in the same device). When you take it out of the band and put into your ear, sound output in the phone automatically redirects. It also accepts the call if there's a call when you do so. That's the solution if you, for any reason, don't want to wear a headset all the time but still want to use one occasionally. It's sitting in the ear comfortably, pulling it out of the band is easy once you get the technique right (first press the release buttons and only then pull, not simultaneously), sound is good enough, there are extra rubber eartips in different sizes.

But the review wouldn't be complete without writing about other features. There are notifications for calls and missed calls, an all the apps you whitelist (vibration, icon, and a short title for each one, missed calls you can return). Fitness tracking is ok, tracks steps automatically, although needs to be switched manually before it can track running. Sleep patterns tracking I haven't tried yet, will see if it's comfortable enough to sleep in. Camera remote control is working with my X1 (although it tries to start google search app occasionally) but doesn't seem to be working with Galaxy S6 (maybe it will with some non-default camera app, other features work with S6 well, by the way). Device search is working. Automatic phone unlock works on newer Huawei devices, including X1 with the latest Chinese ROM, not sure if I want it though the way it works though. Automatic awakening of the gadget (when you wave your hand) works nice after software updates and there is a do not disturb period so that it doesn't try to blind you at night and wake-up button is convenient enough. That's probably all, — as I said, it doesn't have too much extra features. Maybe third-party apps allow for more, don't know for sure.

Any accessories (like new wristbands, more rubber eartips, anything) seem hard to come by at least yet.

Bottom line is DO buy if you want super-cool on-demand headset and maybe some smart watch/fitness tracker features, DON'T buy if you need advanced fitness tracker, very smart watch packed with features, or wear a headset all the time anyway (or don't use a headset at all). It's super smart as headsets go but definitely isn't the smartest watch around. Worth its price for me.

Update (Jan., 2016): Custom notifications, do not disturb, smart unlock, gestures — those all were introduced/fixed with software updates over time. It sucks that you can't find accessories easily. Like screen protectors, extra eartips, and straps. A standard-sized eartip I had got slightly flattened over last months of continuous usage, maybe because of the heat, and I had the extra ones left in another country. Screen became slightly scratched without a protector (totally my fault, the wall had nothing to do with it). The strap can be replaced with one made for watches, I believe it has a standard size, but I haven't tried that yet, couldn't find anything more comfortable and good-looking although it can occasionally get unclicked in a bad moment.

Update (May, 2016): It works just fine with my new Galaxy S7, no Huawei's extra features but basics (talking/syncing/notifying) are just as fine. Eartips continue to wear down, it probably has nothing to do with weather as I replaced one on returning home and it has yet to warm up out here. Judging by the fact that my wife's one is in much better shape, that none of us talk using them too much, and that she wears hers much less often while I usually sleep in mine to track my sleep, I'd say it most probably flattens from the constant wearing, body heat or something like. I have a few spare ones but they are not likely to last for more than a couple years at this rate.

Wednesday, August 26, 2015

Mobile accessories review

As some of you know, I'm a happy owner of Huawei Mediapad X1. So far it's the best 7" phablet (not counting the new Mediapad X2, obviously, which has better hardware with the same size and slightly changed buttons) but this post is not about device itself, instead I wanted to write a few words about cables, cases, screen protectors available on the market. By "market" I usually mean Aliexpress but some stuff might be available in your local stores as well. I'm not endorsing any sellers or brands, especially not original accessories, and prices are for reference only (and usually are for one piece and include shipping i.e. if you're thinking to buy a dozen of something, you might be able to find a better deal). In almost all the cases there might be cheaper options but with worse quality, seasonal deals and everything tend to change every month as new manufacturers and sellers come to market.

Unlike competitors' devices in the same form factor (I'm not pointing at Samsung right now), Mediapad X1 is small and narrow, it's not a tablet and it can be used in many ways people usually use smaller phones, but it still requires a large pocket or a bag to carry around. It would be interesting to write about cargo pants, vests, slings, funny packs, armpit bags, mini backpacks, etc., but I'm not doing it at least just yet. Suffice is to say that pants are my current favorite.

I somewhat dislike conventional Bluetooth headsets, haven't tried any wearables so far, and haven't decided yet whether or not I want to buy Talkband B2 (about $180, but just $150 in my local stores as of this week) so this part I will also skip. Cheap $1 earbuds is what I use (yeah, I also dislike in-ears).

First of all, regardless of what kind of case or cover you decide to use, screen protector is a must (no Gorilla Glass here). There are two kinds of protectors: protective film and tempered glass. Price is about $1 for the film and $4 for the glass. Given that tempered glass protects better and both are cheap, choice is obvious. It makes sense to buy a few extras in case you can't apply it first time or in case it breaks. In my local stores I managed to find a film for $2 (I needed it because the old one got scratches and I waited for the delivery). Universal films is also a thing, they will do if you need something urgently and nothing else is available, not recommended otherwise. Applying a glass is actually somewhat easier that applying a film with one major difference (with the protectors I saw, anyway): if you have a bubble and try to make it go away applying pressure, it can metastasize in form of micro-bubbles, they usually aren't visible but are a little bit annoying so make sure there's no dust (and buy extras).

Second of all, cases and covers. There are three major kinds of them: flip-case, flip-case with window, and back cover. As a sub-type of flip-case, there is a trifold case which can be used as a stand but from my experience this device is so not tabletish that you wouldn't want to do that very often. Of course, there are different materials, colors, manufacturers, prices, but that all is secondary and subjective, so shop around, try different ones.

Flip-case with window is obviously the most high-tech thing. Small window shows time, some notifications, and allows to use camera without opening the cover. No flashlight though. Beware of very cheap listings with no feedback: some of them are so cheap that window doesn't work. Starting from $3-4.

Usual flip-case is less attractive as it requires you to flip it every time you need to see the time or something. Not convenient at all for my liking. But, on the bright side, in this category there are wallet cases in which you can carry two credit cards or id and credit card (although maybe it's not the wisest idea to carry phone, id, and money in one place). $6.

And last but not least is the back cover. My recommendation is to always compliment it with tempered glass screen protector, never put it to bag with heavy objects, and switch to flip-case (or put into an additional case) when travelling because screen is very vulnerable. But other than that it's my current favorite: in all the flip cases device just feels too flimsy and bulky while it's actually very thin and narrow, it's also the best if you use camera or flashlight often, and usually being soft and elastic such cover can sometimes actually protect your device from falling better than the hard cases. Traction is better, I like the look, and port and button protection is effective. Buttons might be a bit tight hard to press and port protection (not present in all covers) is inconvenient for some. About $3.

Travel cases might be good to compliment back cover but I haven't tried any yet (I'm thinking Cocoon Travel Case 7 or similar). In the same category there are waterproof bags, sport cases, and then slings and funny packs (never used any of them).

Flip case with attached qwerty keyboard might be a thing (about $15) but I find them not very usable on the go (and I do most of the typing on mini laptop anyway) while at home you can use just any Bluetooth or USB keyboard.

Yes, the latter would require an OTG cable. There are two kinds of them: with and without external power ($1 and 50¢ respectively), there are also small adapters (20¢). Buy several of each, and then buy and extra one to carry in backpack and another one to leave at home. Much like a microUSB cable, this is the accessory you need often, for many devices, and will probably need even more often in future. If there are some devices (thumb drives, keyboards, etc.) that you use only with phone but not with computers, you can just plug it into an OTG cable (or adapter) and never unplug. Because those cables are cheap and you will need them regardless of your preferred device until USB-C become a thing which will not be until after a few years and then some.

Unlike some competitors (again not pointing at Samsung and Sony), Huawei still uses microSD cards as a main storage, and although you won't take the card out often, a small reader is still a good thing to carry on your key chain (50¢).

Stylus is a thing that almost nobody uses these days (maybe hand-writing could be good, not sure) but it's cheap enough if you need it (50¢).

Next time I have nothing to do I'll probably write about my experience with the phablet itself and maybe about my expectations from X2. Stay tuned.

Tuesday, August 25, 2015

Settling the bracket discussion once and for all

There are quite a few ways you can format a multi-line function call/list/dictionary in a programming language. With Python (at least with PEP8) it's just two ways: hanging indentation and vertical indentation. The latter is quite straight-forward and I mention it in the notes below. The former one is what this post is about. Well, about a minor but important question of where to place the closing bracket when using it.

Yes, style is much more than formatting the commas and brackets so let's settle this and move on to the more important questions.

When using hanging indentation, the only true way is this one(*):
some_tuple = (  # Nothing here, only opening bracket.
    item1,
    item2,
    item3, item4,  # Several items on one line is acceptable though not recommended.
    item5,  # Last comma is important. And never, never place the closing bracket here.
)  # Again, nothing here but the bracket and it's on the same level as the opening line.
Empty line after the opening comma is mandated by PEP8 even though there are a few cases where doing otherwise would've been a possible alternative, like:
class DoNotDoThis(object):

    def just_do_not(self,
        long_argument1,
        long_argument2,
        long_argument3=long_default_value,
    )
and there is a reason for that — anything after the bracket makes the opening line less visible. That's part of the reason for the two spaces before inline comment rule.

The last comma(†) and separate line for the closing bracket is important because you don't really want to see another commit in git blame just because another item was added or deleted and you had to add a comma or move the bracket. You you're using Vim, it also makes adding/deleting easier because you can operate with the whole lines (it helps with just any editor but with Vim it's more so).

I'll repeat: closing bracket should be on separate line and on the same indentation level with the beginning of the opening line (if some_tuple is indented by four spaces, closing bracket should be indented by four spaces).

It might sound like a minor issue but 1) it's the only meaningful way of doing brackets once you think about it, and 2) they should be formatted in uniform way throughout the code so why not pick this one from the three or four PEP8-compatible alternatives(‡). It's one of the things that are easily controllable with pep8 linter (or flake8 which I actually prefer, the same thing but better) — you might wanna configure some auto-check in your editor/IDE, most of them allow that easily (plus, autoindent helps tremendously).

(*) The only case when you place the closing bracket on the line with the last item is this (so-called vertical indentation):
call_some_function(argument1, argument2,
                   argument3, argument4)
Although I'm not fan of this style, it's been around since Kernighan and Ritchie... But still, don't do that, especially with long arguments. Also, while it's still acceptable to put a closing comma on a separate line when using vertical indentation, it looks kinda ugly for me.

(†) There is one case where there should be no last comma. If it's a function call/def and you're using *args or **kwargs. It's almost not worth mentioning because you don't add stuff after **kwargs and it would just result in syntax error if you placed a comma there (not sure why it was implemented that way, but that's the way things are). But still a separate line for the bracket is preferred.

(‡) The text of PEP8 is little ambiguous on this point and some variations acceptable by the letter of it are not allowed by the recent versions of the linter, but it's essentially three options for hanging indentation: a) closing bracket on the separate line on the same level of indentation as the items (doesn't work well with if/while/def blocks), b) closing bracket on the same line as the last item (makes editing harder and messes with git blame when you add/remove items), c) what I have presented above. (There is also d) bracket on any other other level of indentation, like four spaces more than for the items, but that just makes zero sense.)

Friday, July 10, 2015

Using Docker: Is it worth it?

Many companies these days are starting using Docker in their workflow, both big shots and tiny startups, even open-source projects which might sometimes be somewhat conservative when it comes to tools. I'm not trying to provide any kind of instruction here but instead to ask questions you should be asking yourself before following or not following their lead. I'm concentrating on context of web services using Django and Python, but it should be applicable to more or less anything.

I must admit that Docker is cool. Linux containers is a fascinating thing itself and Docker is a great tool for simplifying their use for whatever purpose. Reusable and simple to build and share images, an easy way to launch those images and do stuff with them is a must if you use them. But should you containerize everything? It might, on the other hand, over-complicate your process without any significant benefits. So the first question is: do you even need containers or would you better off without them, using more traditional tools? Or maybe you should use them for some things and not use for some other ones?

Like building images for continuous integration and deployment while doing local development old-fashioned way. This is actually a big point. Because whenever I tried it for local development, Docker wasn't on their best foot. Compare two processes with the same Django project, you have the usual requirements.txt file describing stuff you should install (in virtualenv, usually), probably some additional requirements not needed outside you own environment (like django-debug-toolbar), you have Django's development webserver (./manage.py runserver) that will seamlessly reload every time you change anything with code, you have some RDBMS (might just be sqlite, but usually the same one you use on production) with some test data in it making your development process easier, and some system requirement you just install once before you start developing (version of your DBMS is sometimes important, everything else usually less so). Traditionally, once you have installed system stuff, you just need two or three commands to setup your virtualenv and then you just launch devserver and start hacking. With Docker you'd have to build an image and launch container, often you'd have to launch another container for DBMS too (image can often be just pulled), and when you change your code, you rebuild and relaunch. Do you need that rebuild part after the changes? Can't you just mount your code into container? You can (look up volume in docker's documentation) but it will make it even more complicated as the process in container starts creating files in you local filesystem as a different user, making a mess and security breaches there. I won't even start explaining what kind of mess would be with boot2docker. Also it would complicate the deployment as you'll have to match images with the code revisions, etc. The point is, if you need to generate some data and keep it, containers might be not the best way of doing it (imagine yourself generating, say, a migration inside container then copying it with `docker cp` out, then building some special container for generating another thing because inside you usual container you don't have data for it and outside it you don't have tools or some other data...)

Regardless of whether or not you like to rebuild containers every time you change a line of code, should you use Docker for testing (especially continuous integration) and deployment. Isn't it great to have exactly the same image in your CI service and on production server? While it does sound appealing, remember that half of the stuff you need for testing is not needed on production and half of the production stuff is too complicated to be used for testing. It doesn't mean you can't either, and personally I like how it makes concurrent builds easy: not conflicts over database, or port, or some other resource whatsoever. But then if you try to use some paid service you might get stuck with an outdated version of docker that can't do many advanced stuff and without any kind of caching for images, even for images from the official registry (true story from one of the popular services). Are you comfortable setting up Jenkins for your CI needs or does your service has an up-to-date version of Docker?

And to the last important question. Docker is usually used to avoid problems arising from different environments. Are your environments different? If you have CI server, production server, staging server, and your own computer all running the same LTS version of same distribution of Linux, do you have much differences? Are other developers using the same distribution? (Yes, we all know what distribution it is). And answer not counting non-Linux users because they won't be able to use Docker natively anyways and since they need virtualization they might just as well use the virtual machine for testing and stuff without additional layer of Docker and containers. And if you have many non-Linux users, maybe you just need some virtualization solution (there are several easy to use tools running on top of VirtualBox or something).

As I said, Docker is a great tool but you should not use a microscope for hammering nails just because it's a cool tool or because some other guys do it. Use the tools that are great for your particular tasks.

Saturday, January 24, 2015

A small catch in Python documentation (strftime).

Every developer knows datetime.strftime() method, but some don't know that its argument's format is not documented in full in the official documentation.

For example, you won't find any mention of %s directive there which means UNIX epoch time, timestamp. It works (at least with every major version of Python on Linux, FreeBSD, and MacOS), I've tested it a few times myself, it's just not documented.

I recently saw a piece of code where developers, being unaware of such a directive, used custom format string with both datetime.now() and time.time(), a function generator, and on top of it messed with model migrations (it all was about FileField.upload_to if you know what I'm talking about) when they could just use %s.

From other undocumented features you might be interested in these:

%C is a century (%Y//100), could be helpful for complimenting %y or something, I guess.

%u is a weekday number with Monday as 1 and Sunday as 7 (as opposed to %w representing Sunday as 0).

And padding/case modifiers (specifications are for reference only):

%_d (pad with blank),
%-H (no padding),
%0e (pad with zeros),
%^A (uppercase),
%#Z (effectively lowercase for %Z, not useful with anything else).

(Note: They were introduced by GNU extension but work on BSD/MacOS and other modern systems.)

I'm not writing documentation here, but for the sake of completeness, here is the list of all specifications supported by python library on major platforms but not mentioned in Python docs:

%C %D %e %F %G %g %h %k %l %n %R %r %s %T %t %u %V (and modifiers %_* %-* %0* %^* %#* %E* %O*)

Most of them are just shortcuts (like %F, %T, or %D) or simply useless (like %V, %G, %g stuff) but please refer to strftime(3) or standards for explanations.