Wednesday, May 9, 2018

Making mouse pointer movement smooth with touchpad in Kubuntu 18.04

I have noticed that my mouse pointer (rather touchpoint pointer) moves in a jumpy manner while trying Kubuntu 18.04 Bionic Beaver on my Acer laptop.
After some research I've managed to fix this. Here's how:
1. Open Konsole
2. Run this command:
sudo apt install xserver-xorg-input-synaptics
(don't forget to enter your password :)
3. Reboot

That's basically it. After this you can open System Settings, go to Input Devices / Touchpad settings and further adjust Noise Cancellation if you really want to.

Here's a little video I made about it in Kdenlive (it was an excuse to spend some time learning the basics of Kdenlive, really :).


Makes me wonder why it isn't installed out of the box :|

Thursday, December 28, 2017

Command line classpath is ignored when using -jar

I was a little shocked today by my discovery of -classpath (-cp) parameter being ignored silently by Java Virtual Machine, when -jar is provided. Look at this (my jar file prints out its working directory and classpath):
java -cp /home:./ -jar ./build/jarclassscanning.jar

Working Directory = /home/me/projects/jarclassscanning
----------------
Classpath elements:
/home/me/projects/jarclassscanning/build/jarclassscanning.jar
----------------

However, if I run the same jar without -jar parameter, here's what it prints out (I've added a couple of directories to -cp just to show that it works):
java -cp /home:./:./build/jarclassscanning.jar my.package.jarclassscanning.BaseClass

Working Directory = /home/me/projects/jarclassscanning
----------------
Classpath elements:
/home/
/home/me/projects/jarclassscanning/
/home/me/projects/jarclassscanning/build/jarclassscanning.jar
----------------

So if your jar uses classes from other jars (or just plain old .class files) and you have to specify classpath, one solution is to add classpath elements to the manifest file - https://docs.oracle.com/javase/tutorial/deployment/jar/downman.html. Keep in mind, however, that you've got to use spaces to separate them, not colons.

Also I've ran into another thing - when specifying jar files as classpath elements using Class-Path field of the manifest file using relative paths, they had to be relative to the location of my jar (the one that I give to JVM using -jar).

So, since my folder structure looked like this:
build
    myjar.jar
jdbc
    postgresql-42.1.4.jar
amqp
    amqp-client-4.2.0.jar
sl4j
    slf4j-simple-1.7.25.jar
    slf4j-api-1.7.25.jar

The Class-Path field of the manifest in myjar.jar ended up looking like this (note the ".."'s):
Class-Path: ../jdbc/postgresql-42.1.4.jar ../amqp/amqp-client-4.2.0.jar ../slf4j/slf4j-simple-1.7.25.jar ../slf4j/slf4j-api-1.7.25.jar

Tuesday, December 26, 2017

Apache Ant modifies classpath

Just a quick note - I have discovered this thing while digging into Java class loading / reflection. When running my test program from command line, like so:
java -ea -cp ./build/jarclassscanning.jar my.package.jarclassscanning.BaseClass
(yes, I specify my main class directly and just add my jar file to the classpath)

my classpath contains what I expect it to contain:
/home/me/projects/jarclassscanning/build/jarclassscanning.jar

But if I use my simplistic ant build.xml, which contains target run:
<target name="run">
  <java classname="my.package.jarclassscanning.BaseClass">
    <arg value="-ea"/>
    <classpath>
      <pathelement location="./build/jarclassscanning.jar"/>
    </classpath>
  </java>
</target>

this is what my classpath becomes (printed out from the test program itself):
/home/me/apps/apache-ant-1.9.7/lib/ant-launcher.jar

However, if I add fork="true" to the java task (just as you should if you use jar attribute, which I don't):
<target name="run">
  <java classname="my.package.jarclassscanning.BaseClass" fork="true">
    <arg value="-ea"/>
    <classpath>
      <pathelement location="./build/jarclassscanning.jar"/>
    </classpath>
  </java>
</target>

everything's back to normal:
/home/me/projects/jarclassscanning/build/jarclassscanning.jar

Saturday, February 18, 2017

A C pitfall

Consider the following code:

#include ‹stdio.h›

int main(void)
{
 printf("This line ends with backslash (\\)\n"); // Print \
 printf("This is the second line\n");
 printf("This is the third line\n");
 return 0;
}

gcc 5.4.0 I have on my Xubuntu 16.04 box compiles this code without errors or warnings.
What do you think the code prints out when run?
This:

This line ends with backslash (\)
This is the third line

The second line is silently ignored by the compiler. The reason is that the line before it ends with backslash symbol (\). Even if the backslash belongs to the comment, gcc still considers the second line to be continuation of the line before it, and exactly because of this the second line is considered to be the continuation of the comment and is ignored.

Worst of all there's no warning or error, although ideone tells me that at least gcc 6.3 refuses to compile the code:
prog.c: In function ‘main’:
prog.c:5:50: error: multi-line comment [-Werror=comment]
  printf("This line ends with backslash (\\)\n"); // Print \
                                                  ^
cc1: all warnings being treated as errors

But anyway this is something to be aware of, especially if you're not sure about the way your compiler treats this case.

Wednesday, July 13, 2016

Enums in Java

If you're familiar with C or C++, you may tend to think of enums as just integers. Which they basically are - in those languages, but not in Java.
Java enum is a special kind of class. What's the difference for you as a user?

It you just want a simple enum and don't care about real values behind enum constants, you can go ahead and just do as in old good C (almost, as C syntax is slightly different):
enum Color {RED, GREEN, YELLOW}
 . . .
Colors col = RED;
But if you try to assign an integer value to col, as you could in C, like so:
col = 2;
- the code fails to compile, which is a good thing, as you obviously want your value to be one of the predefined constants.
Well, actually you can't compile this in C++ either, but you can still force the compiler to build it by using a cast like this one:
col = (Color)2;
But that's beside the point. If you want your constants to have specific values, in C you could achieve that like this (note that this is C syntax, which is slightly different from Java):
enum Color {RED=5, YELLOW=10, GREEN=15};
If you want this in Java, you have to take into account that your enum is going to be a special kind of Java class, extending java.lang.Enum. Its syntax is also different from both C / C++ enums and normal Java classes:
enum Color
{
    RED(5), GREEN(10), YELLOW(15);
    private int col;
    private Color(int col) { this.col = col; }
    private int getValue() { return col; }
}
And this is how you use it:
Color c = Color.RED;
System.out.println(c);
which prints out
RED
But you can't just go and assign an integer value to your enum object:
Color c = 5;
System.out.println(c);
because
error: incompatible types: int cannot be converted to Color

There's much more to Java enums, check out these links for more details:

Monday, July 11, 2016

java.time

java.time is a package for handling date / time values, introduced in Java 8. Before that you had to use classes like java.util.Date or java.sql.Date, if you were dealing with SQL databases.

These are still available in Java 8, but I would rather avoid them, as they're not thread safe, don't support the notion of time zones, etc. You can use a third-party solution like Joda-Time, but if you're writing Java 8 code, I see no reason not to use buiilt-in java.time.

Here's an article from Java Magazine, introducing java.time package.

I myself am most interested in ZonedDateTime class, as it represents timestamp in a certain time zone. ZonedDateTime (like OffsetDateTime class) contains at its heart an object of Instant class, and time zone information.

Instant is "an instantaneous point on the time-line", in other words it's just a number of seconds (and nanoseconds) passed since "epoch" (1970-01-01T00:00:00Z). This value doesn't depend on time zone, it is the same no matter where in the world you are (java.time doesn't take relativity into account, which is fine with me).

What this means, basically, is that you can't "convert" ZonedDateTime to another time zone, but what you can do instead is create another ZonedDateTime object with the same Instant value, but with different time zone setting. You can't change your existing ZonedDateTime objects, since they are immutable (thread safety!).

Using ZonedDateTime.withZoneSameInstant does just that:
import java.time.ZoneId;
import java.time.ZonedDateTime;

. . .

ZonedDateTime zdtHereNow = ZonedDateTime.now();
System.out.println("ZonedTimeDate here and now = " + zdtHereNow);

ZoneId utcTzId = ZoneId.of("UTC");
ZonedDateTime zdtUtcNow = zdtHereNow.withZoneSameInstant(utcTzId);
System.out.println("ZonedTimeDate \"here and now\" in UTC = " + zdtUtcNow);

Redis + Java = Jedis

"Jedis is a blazingly small and sane Redis java client."

Jedis wiki is here - https://github.com/xetorthio/jedis/wiki

Here's a tutorial: http://www.tutorialspoint.com/redis/redis_java.htm

If you want to download Jedis jar (compiled, not the source zip they offer on their Github page), use this link - http://repo1.maven.org/maven2/redis/clients/jedis/
Go to the folder with the greatest version number (currently 2.8.1, but it'll change) and download jedis-.jar (jedis-2.8.1.jar at the moment).

Don't forget to add this jar to your CLASSPATH both for javac (when you compile your project) and for java (when you run it).

Another option, besides Jedis, is Lettuce - see here for short introductions for both Lettuce and Jedis.

Finally, here's a small example of my own:

package kotodemo.jedis_test;

import java.util.Set;
import redis.clients.jedis.Jedis;

class JedisTest1
{
 public static void main(String[] args)
 {
  // Connecting to Redis server on localhost
  Jedis jedis = new Jedis("localhost", 6100); // Note the non-standard port 6100 I'm using
  // Check whether server is running or not
  System.out.println("Server is running: " + jedis.ping());

  // Get the names of all the keys print them
  Set keys = jedis.keys("*");
  for(String keyStr : keys)
   System.out.println(keyStr);
 }
}

Update: to connect to a non-zero Redis database, use Redis URI to initialize Jedis object, like so:
import java.net.URI;
. . .
Jedis jedis = new Jedis(new URI("redis://localhost:6100/7"));
where 6100 is Redis port I used to test this particular code snippet and 7 is Redis DB I wanted to connect to.

More information on Redis URIs (URLs):

Sunday, July 10, 2016

Saturday, December 19, 2015

RAMPS + DRV8825

I have ordered this Arduino Mega 2560 + RAMPS + 5 * DRV8825 + LCD 12864 set, loaded it with Repetier firmware and found out that it works nicely, hooray!

Things to keep in mind: DRV8825 boards were configured for Vref = 1.6-1.7 V, which is way too high. This translates into output current of 3.2-3.4 A, as the formula for DRV8825 is
    I_TripMax = Vref / (5 * Rs)

Or, as Rs is 0.1 Ohm (resistors are labeled as "R100") -
    I_TripMax = Vref / 0.5

which is the same as
    I_TripMax = 2 * Vref

See these links - 
http://reprap.org/wiki/A4988_vs_DRV8825_Chinese_Stepper_Driver_Boards
https://www.pololu.com/product/2133

This current can damage your motors, so before connecting the motors to RAMPS you must adjust Vref. Thankfully it's not that hard: plug in 12 V power supply into RAMPS (Arduino is powered from RAMPS board), and measure Vref between the ground pin of DRV8825 board and top of adjustment potentiometer, as shown:



I have soldered a wire to the ground pin and wound it onto the ground probe of my multimeter because I only have two hands. With the red probe touching my screwdriver that I used to turn the potentiometer I was able to adjust Vref and check its value on the multimeter.

The first link recommends setting Vref to 0.5 V (which translates into 1 A current) and using that as the starting point to further tweak Vref. However when using puny CD / DVD stepper motors, I think 1 A is waay too high, so I started with ~0.1 V, and went up to 0.16 V. With this Vref my motor works just fine and doesn't seem to overheat. I may end up increasing Vref when I add mechanical load to the motor though.

Friday, October 9, 2015

Supervisor program groups

"Supervisor is a client/server system that allows its users to monitor and control a number of processes on UNIX-like operating systems."
Simply put, it's a program that can run other programs for you. It does its job, it is mature and straightforward - just define your programs in a plain Windows-INI-style configuration file (although Supervisor doesn't run on Windows) and you're set.

But what if you've got a whole bunch of programs to run, isn't starting/restarting/stopping them one-by-one using supervisorctl going to be a major hassle? Yes, but Supervisor offers a solution: program groups! Define your programs as usual, but add a group entry to the conf file:

[program:a-program]
command=command-to-run-a-program
; etc.

[program:another-program]
command=command-to-run-another-program
; etc.

[program:yet-another-program]
command=command-to-run-yet-another-program
; etc.

[group:my-group]
programs=a-program,another-program,yet-another-program

Now, instead of issuing commands for each program like so:
supervisorctl start a-program
supervisorctl start another-program
supervisorctl start yet-another-program
or
supervisorctl restart a-program
supervisorctl restart another-program
supervisorctl restart yet-another-program
or
supervisorctl stop a-program
supervisorctl stop another-program
supervisorctl stop yet-another-program

you can just do
supervisorctl start my-group:*
or
supervisorctl restart my-group:*
or
supervisorctl stop my-group:*

And just imagine having 10 or 20 or even more programs to control!

Monday, February 9, 2015

Contrary to what I considered possible, LDAP server

somehow notifies connected clients when being shut down.
So when you have an open connection to said server, you don't receive ldap.TIMEOUT exception as I expected. You get ldap.SERVER_DOWN.

Something to watch out for when you're working with LDAP.
Like so:
try:
    data = conn.search_s(base_dn, scope, search_filter, retrieve_attributes)
    log.debug("Searched for attribute(s) of LDAP base DN {0}, filter {1}".format(base_dn, search_filter))
    return data
except (ldap.TIMEOUT, ldap.SERVER_DOWN) as ex:  # catching just ldap.TIMEOUT is not enough!
    log.error("Exception: {0}".format(ex))

Thursday, January 1, 2015

Vortex Ring State

happens when a helicopter (even a small quadcopter!) descends too quickly and its own downwash (turbulent air beneath the rotor(s)) envelopes the rotor(s). The machine basically runs into its own downwash. This may happen for instance due to a piloting error and leads to severe loss of lift.

Simply put, you go down too quickly and find that you start falling down and can't pull up! And Going full throttle doesn't help! The most straightforward way of getting out of VRS is to move horizontally to get out of the turbulent air as quick as possible.

Wikipedia article.
Quadcopter demonstration:

Monday, December 22, 2014

Exporting to MS Excel format (XLS)

from Python is relatively easy with xlwt package. The linked page says that xlwt is a
Library to create spreadsheet files compatible with MS Excel 97/2000/XP/2003 XLS files, on any platform, with Python 2.3 to 2.7
To that I can only add that it's fast, too!
I've heard it doesn't support creation of XLS files with formulas, which might or might not be true (haven't tested that myself).

Installation is easy as usual:
$ pip install xlwt
Here's the link to PDF tutorial covering xlwt along with xlrd (read Excel files from Python) and xlutils (utulities for both xlwt and xlrd). You may also want to check out this site for some information.

To create yourself an Excel file, you basically do this:
import xlwt
from datetime import datetime


book = xlwt.Workbook()
sheet = book.add_sheet('SheetName', cell_overwrite_ok=True)  # Ability to overwrite may be extremely handy 

# You might want to change column widths. 700 is 0.21" as I've found out experimentally
sheet.col(0).width = 700

# Or row hights, but in this case enabling height_mismatch helps you achieve the desired effect.
sheet.row(0).height_mismatch = 1
sheet.row(0).height = 260  # 0.18"

sheet.write(0, 0, u"Current date/time:",
            xlwt.easyxf('font: name Arial, height 160; align: vertical bottom, horizontal left; '
                        'pattern: fore_colour white, pattern solid;'))
sheet.write(0, 2, datetime.now(),
            xlwt.easyxf('font: name Arial, height 160; '
                        'align: vertical center, horizontal center; '
                        'borders: left thin, right thin, top thin, bottom thin; '
                        'pattern: fore_colour white, pattern solid;',
                        num_format_str="DD/MM/YY H:MM:SS;@"))
sheet.col(2).width = 4000  # Hopefully this is enough to show datetime

sheet.write_merge(1, 1, 0, 2,
                  123.55,
                  xlwt.easyxf('font: name Arial Cyr, height 160; '
                              'align: vertical center, horizontal right; '
                              'pattern: fore_colour white, pattern solid;',
                              num_format_str="#,##0.00"))

book.save("out.xls")

Need to create a nice PDF from Python?

pdfkit is a package that can help. This package can cook you some PDFs from HTML. It's a wrapper around wkhtmltopdf, so make sure you install that. On Debian/Ubuntu I wouldn't apt-get it from the standard repository - those wkhtmltopdf QT patches sure provide nice functionality.

Installing pdfkit is as simple as
$ pip install pdfkit
Then you can do this:
import pdfkit

pdfkit.from_url('http://google.com', 'out1.pdf')
pdfkit.from_file('test.html', 'out2.pdf')  # Provided you have test.html in your current folder
pdfkit.from_string('Hello!', 'out3.pdf')
pdfkit.from_string('<html><table><tr><th>Header</th></tr><tr><td>Row 1<td></tr><tr><td>Row 2<td></tr></table></html>', 'out4.pdf')

Must validate

your Python dictionary against a certain set of rules you know it must comply with (schema)?Voluptuous is a Python data validation library! (Despite the name)

Say you've got a dictionary from json.loads. Just define your schema and check if what you've got is good:
from voluptuous import Schema, Required, All, Length, Range
schema = Schema({
    Required('q'): All(str, Length(min=1)),
    Required('per_page', default=5): All(int, Range(min=1, max=20)),
        'page': All(int, Range(min=0)),
    })
"q" is required:
from voluptuous import MultipleInvalid, Invalid
try:
    schema({})
    print "MultipleInvalid not raised"
except MultipleInvalid as e:
    print e
required key not provided @ data['q']
...must be a string:
try:
    schema({'q': 123})
    print "MultipleInvalid not raised"
except MultipleInvalid as e:
    print e
expected str for dictionary value @ data['q']
...and must be at least one character long:
try:
    schema({'q': ''})
    print "MultipleInvalid not raised"
except MultipleInvalid as e:
    print e
length of value must be at least 1 for dictionary value @ data['q']
Note how per_page is assigned its default value:
try:
    s = schema({'q': '#topic'})
    print "s = {0}".format(s)
except MultipleInvalid as e:
    print e
s = {'q': '#topic', 'per_page': 5}

Gedit as a developer's editor

A good text editor is an essential tool for anyone who writes code. Gedit is okay-ish out of the box, but many nice features are lacking. Here are the plugins I use to make life with Gedit easier:

  1. Gedit Source Code Browser: adds a new side panel that shows symbols (functions, classes, variables, etc.) in the code you're editing. This is a common feature found in virtually any IDE out there.
    Sadly, this plugin didn't work out of the box, so I had to make several modifications to make it:

    Went to ~/.local/share/gedit/plugins/ and in sourcecodebrowser.plugin replaced
    Loader=python
    
    with
    Loader=python3
    

    Because of switch to Python 3, I also had to replace the following line in sourcecodebrowser/ctags.py, in parse(self, command, executable=None:
    symbols = self._parse_text(p.communicate()[0])
    
    with
    symbols = self._parse_text(p.communicate()[0].decode("utf-8"))
    

    I'm not sure if this was really necessary, but it seemed logical to me not to supply 'ctags' executable name in the parameters string (since it's given separately as self.ctags_executable anyway). In sourcecodebrowser/plugin.py:
    command = "ctags -nu --fields=fiKlmnsSzt -f - '%s'" % path
    
    replaced with
    command = "-nu --fields=fiKlmnsSzt -f - '%s'" % path
    
    Once again, not sure this was needed.
  2. Gedit Restore Tabs. Does what it says - Gedit automatically opens all the files you had open in your previous session. Not having to recall where exactly are the files I was editing helps me concentrate on the code.
    Once again had to modify plugin definition file here. In restoretabs.plugin replaced
    Loader=python
    
    with
    Loader=python3
    
    But that was it. No source-code modification was required.

    Important update: I've encountered a text document that somehow causes Restore Tabs to crash Gedit on startup. A workaround is to remove this document from the list of files to be loaded on Gedit startup using dconf-editor tool (if you don't have it, do sudo apt install dconf-editor). To find the list, run dconf-editor and go to org -> gnome -> gedit -> plugins -> restoretabs. Remove the offending file from "uris", or just clear the list if you don't know which file is causing the problem.
  3. gedit-file-search: Gedit plugin to search a text in all files in a directory. No tweaking needed, nice!
  4. Plugins in gedit-plugins package, like Color Scheme Editor, Draw Spaces, File Browser Panel, Smart Spaces, Text Size and even a Python Console!

Sunday, December 21, 2014

Adding command line arguments to your Python program

is so simple using Click package! From Click documentation page:
import click

@click.command()
@click.option('--count', default=1, help='Number of greetings.')
@click.option('--name', prompt='Your name',
              help='The person to greet.')
def hello(count, name):
    """Simple program that greets NAME for a total of COUNT times."""
    for x in range(count):
        click.echo('Hello %s!' % name)

if __name__ == '__main__':
    hello()
And what it looks like when run:
$ python hello.py --count=3
Your name: John
Hello John!
Hello John!
Hello John!
It automatically generates nicely formatted help pages:
$ python hello.py --help
Usage: hello.py [OPTIONS]

  Simple program that greets NAME for a total of COUNT times.

Options:
  --count INTEGER  Number of greetings.
  --name TEXT      The person to greet.
  --help           Show this message and exit.
It's magic! Intallation is super-simple, too:
pip install click
And you're set!

Python logging

module has several interesting types of handlers, useful if you want your log files to roll over, like RotatingFileHandler and TimedRotatingFileHandler. The former is useful if you want to limit log file size, but I wanted my logs to roll over at midnight, so I went with the later.

What I didn't know is that TimedRotatingFileHandler has to be created before the moment of rollover and be present during or after it for the rollover to occur. So if your code runs occasionaly and you create your TimedRotatingFileHandler only when you need it, it's not of any help to you.

But there's a simple solution - when creating my FileHandler I just give it the name of the log file which includes current date!

log_fname = "log-{0}.log".format(datetime.now().strftime("%Y-%m-%d"))
log_full_fname = os.join(LOG_PATH, log_fname)
file_handler = logging.FileHandler(log_full_fname)
It works for me since I create the handler every time I need to log something.