The TrackPoint on a ThinkPad laptop is one of the main reasons why I kept buying laptops from them. However, as a heavy laptop user who refused to carry around one extra mouse, the constant usage of TrackPoint can cause a significant amount of pain to my fingertip, which is very unpleasant. An once-in-a-while quick movement is okay, but scrolling up/down takes longer and requires more pressure, which is the main cause of discomfort.
As a possible solution, I’ve tried to enable TouchPad and two-finger scrolling. However, for some reason it didn’t work by setting it in gnome-control-center, so instead I used the old faithful xinput. From the output of xinput list-props "SynPS/2 Synaptics TouchPad", it’s easy to spot “Synaptics Two-Finger Scrolling”, and the two parameters can enable vertical and horizontal scrolling, respectively.
The default setting of two-finger scrolling was far from intuitive – normally people would expect it to work just like the way it works on touch devices: you touch the screen, then you can push the document up by moving your finger up. That means scrolling down when your finger is moving up. But on my laptop, moving two fingers up means scrolling up, which causes the document to move down!
To make this problem worse, there is no setting in gnome-control-center to inverse this. Again, this can be solved with xinput by simply changing the values of “Synaptics Scrolling Distance” from 100 100 to -100 -100.
Pencil is simply the best (open) sketchy mockup solution on Ubuntu. However, as described on its download page, you cannot install it as a Firefox extension because it’s not compatible with the Firefox 18.x that comes with Ubuntu 12.04. The standalone version runs okay but some features such as export as PNG fails silently because of the same compatibility issue.
Turns out you don’t need to install the deb package provided on its website. Simply download the latest tar ball from the download page on google code, then download xulrunner (Mozilla runtime) from ftp.mozilla.org. I used the latest supported version: 16.0.2.
Now extract these to a preferred place, then add a file called pencil anywhere in your $PATH with the following content:
<<判斷作法>>= void condition(constchar *list[], constint len) { int i; for (i = 0; i < len; i++) { if (i != 0) printf(", "); printf("%s", list[i]); } puts(""); } @
python-ropemac is really useful for developing python in emacs, and pylint is also very handy as a analyzer. However, they both don’t work very well with virtualenv, especially because I always run emacs in server mode, and the server instance is usually not under virtualenv.
Here is how to make things work:
Edit .ropeproject/config.py:
1 2 3
# You can extend python path for looking up modules prefs.add('python_path', '/your-virtualenv-dir/lib/python2.7/site-packages/')
For pylint, generate (by pylint --generate-rcfile) or copy your default pylintrc to project root dir. Edit it:
1 2 3
# Python code to execute, usually for sys.path manipulation such as # pygtk.require(). init-hook='this_file="/your-virtialenv-dir/bin/activate_this.py";execfile(this_file, dict(__file__=this_file))'
To me, variable sum is similiar to ‘instance variable’, in Object-oriented’s terminology. However, in Python, things can be quite different.
1 2 3 4 5 6 7 8 9 10 11 12
defadder(): sum = 0
deff(x): sum += x return sum return f
defmain(): pos, neg = adder(), adder() for i in xrange(0, 10): print pos(i), neg(-2 * i)
The code looks roughly the same, but it will raise the following exception:
1 2 3 4 5 6 7 8
Traceback (most recent calllast): File"closure.py", line 17, in main() File"closure.py", line 13, inmain print pos(i), neg(-2 * i) File"closure.py", line 5, in f sum += x UnboundLocalError: localvariable'sum'referencedbefore assignment
This is because if sum is to be modified, Python must decide which variable to change. **sum += x** is the same as **sum = sum + x**, and **sum = ** suggests it’s a local variable, since all variable is by default local in Python. Given that, expression **sum + x** can not be evaluated because sum, as a local variable, is still undefined here.
If the **sum += x** line is removed, and **sum + x** is returned directly, the result will be:
It runs okay, but the result is wrong. Where does function f get the value of sum? If Python cannot find a variable in locals(), it will try to find it from the scope above it, i.e. function adder, and sum is indeed defined in it. The real Python equivelent of the Go program above will be:
defmain(): pos, neg = adder(), adder() for i in xrange(0, 10): print pos(i), neg(-2 * i)
if __name__ == '__main__': main()
Functions are already first class objects in Python. Here we create a class that its instance behaves like a function, so it is a function because of duck typing.
awesome is the tiling windows manager I use daily and I just wrote a very useful (at least for me) function for it. Basically it swaps every client (similar to windows) between the current tag (similar to workspace) and the target tag. Normally I put terminal clients for my current task at tag#3, right next to my Emacs-only tag#2 so I can quickly switch between browser (#1), editor and terminals. Now if I want to switch to a different task I just need to swap in terminals from another tag while swap out current terminals to that tag.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
-- i is the index of target tag in variable `tags' function() local screen = mouse.screen local from = client.focus:tags()[1] local to = tags[screen][i] if to then t = to:clients() for i, c inipairs(from:clients()) do awful.client.movetotag(to, c) end for i, c inipairs(t) do awful.client.movetotag(from, c) end end end
I put this under
1 2 3 4 5 6 7 8 9 10 11 12 13
-- Bind all key numbers to tags. -- Be careful: we use keycodes to make it works on any keyboard layout. -- This should map on the top row of your keyboard, usually 1 to 9. for i = 1, keynumber do globalkeys = awful.util.table.join(globalkeys, awful.key({ modkey }, "#" .. i + 9, function() local screen = mouse.screen if tags[screen][i] then awful.tag.viewonly(tags[screen][i]) end end), awful.key({ modkey, "Control" }, "#" .. i + 9,
If you want to do multi-thread testing in Pyramid, it probably won’t work the first time because request and registry are thread local, and things like get_renderer will call get_current_registry. When it happens in a thread, it won’t get the same value as it would have in the main thread.
pyramid_thread_locals = pyramid.threadlocal.manager.get() threads = [Thread(target=random_func, args=(pyramid_thread_locals, ),) for i in range(100)] for thread in threads: thread.start() for thread in threads: thread.join()
There is no guarantee that pyramid.threadlocal.manager will always be there. Even if it’s there, there’s no guarantee it can be used this way. So, this should only be considered as a temporary workaround.
JJ’s Studio is a software consultancy specialized in Android technologies. We are experienced in both system and application layers, plus several years of experience before that in Linux mobile phone development.
We have co-founded the well-known 0xlab.org, as well as created/contributed to several Free and Open Source Software projects, such as 0xdroid, 0xbench, OpenEmbedded, and OpenWrt.
Our services include:
Android application: standard Android application that fits into the varieties of Android devices.
Framework development: develop or integrate new features into device firmware in framework layer and below.
Performance analysis: get more out of your hardware by profiling and tuning.
JJ’s Studio differentiates ourselves by the unique combination of knowledge in different layers of Android architecture. This enables us to work in different areas from developing a mobile application to delivering a complete device firmware.
Please also check my partner Julian’s article on this (in Traditional Chinese).
I have been too lazy to write this but today I was finally bothered enough. I don’t pipe it to sh inside awk because you may want to check what it will do before you actually do it.
1 2 3 4 5 6 7 8 9 10 11
#!/usr/bin/awk -f
# Usage: ls -1 | lowercase.awk | sh
match($0, /\.[[:upper:]]+$/) { if (RSTART == 1) next name = substr($0, 1, RSTART-1) ext = substr($0, RSTART, RLENGTH) printf("mv \"%s%s\" \"%s%s\"\n", name, ext, name, tolower(ext)) }