Doom source ports¶
It happened again, I got the craving to play DOOM — the original. And I wanted it to really have the feel of the original.
GZDoom is very popular, or should I say notorious for definitely not being faithful to the original. Running the actual original through DOSBox seemed quite ugly. At first, Chocolate Doom seemed to be exactly what I wanted, but unfortunately it lacked basic quality-of-life improvements, especially regarding controls. I concluded that Crispy Doom is a strictly better source port: it adds a lot of improvements over Chocolate Doom, and that doesn't mean we have to use all of them.
On Arch Linux I just needed to run
yay -S crispy-doom to install it from AUR.
This article is about using the Wooting One analog mechanical keyboard on Linux.
(Information as of Wootility v2.3.3)
If you just got the keyboard and downloaded the latest Wootility software, it is possible that it will be unable to detect the keyboard. From what I heard from technical support, I figure that this is because somewhere along the way the software lost the ability to communicate with old versions of keyboard firmware (and it has old firmware from the factory). So the solution is to get an old version (v2.1.0) of the software, run it with
sudo and go through the restore procedure which includes a firmware update. Then latest software will work properly.
This is a basic evaluation of the Wooting One analog mechanical keyboard from the perspective of a Linux user. Perhaps it does not deserve a full blog post, I just wanted to separate subjectivity from the technical article, which you should check out:
Wooting for Linux users: technical tips + XInput key mappings
So, did I like the keyboard? No, though I suspect it's mostly about me being used to slim keyboards.
I can never get around to writing this blog post. It's an ambitious one, with great examples an schematics planned. Anyway, maybe someone will still find the beginnings of it useful.
This is a writeup in layman's terms about how memory is being allocated and managed in most modern programming languages. Its target audience is users of Crystal programming language, but the parts specific to that language will be on purple background. Expect some omissions and inaccuracies for the purpose of explanation.
Crystal Programming Language does not yet support Windows, but the progress is ongoing, and programs that use isolated parts of the standard library can be properly cross-compiled. Note that, even though there are multiple mentions of Windows Subsystem for Linux here, it is used only for one of the build steps. The resulting binaries run natively on Windows, no strings attached.
Basic Crystal setup¶
You need a POSIX-compatible system that Crystal officially supports (like Linux) and also Windows. If you are already on Windows 10, the obvious choice is Bash on Ubuntu on Windows. If on a different OS, use a virtual machine with Windows — VirtualBox is a good choice. Microsoft offers virtual machine images for free.
Let's start with the minimal Travis configuration that allows you to test Nim projects.
.travis.ymllanguage: c install: - | # Download the latest release of Nim into the "nim-master" folder git clone -b master --depth 1 git://github.com/nim-lang/nim nim-master/ cd nim-master # Download the latest release of Nim's prepared C sources, for bootstrapping git clone -b master --depth 1 git://github.com/nim-lang/csources csources/ cd csources # Build C sources sh build.sh cd .. # This concludes the first step of bootstrapping, don't need C sources anymore rm -rf csources # Use the executable built from C sources to compile the build tool bin/nim c koch # Compile Nim in release mode, using the Nim compiler we already have ./koch boot -d:release cd .. before_script: # Add the 'bin' folder to PATH - export PATH="nim-master/bin:$PATH" script: # Run 'tests/all.nim'. Feel free to change this, but it needs to be a program # that returns a non-zero status code in case of failure. The testing facilities # in Nim's standard library do this. - nim compile --verbosity:0 --run tests/all
ksshaskpass is a KDE-based passphrase dialog for use with OpenSSH. It is intended to be called by the ssh-add(1) program and not invoked directly. It allows ssh-add(1) to obtain a passphrase from a user [...]
So this utility is useful if you want to store the passphrases to your SSH keys in the KDE Wallet (there are plenty of instructions on how to do that).
But all it really does is receive a string as an argument, tries to query KWallet for a password saved under this key string (or asks for this password in a dialog and stores it), then writes it to stdout. This means that ksshaskpass can be used to store any kind of password in KWallet for use in your Bash scripting.
We will be using Bash, ksshaskpass, sshpass.
TL;DR: Use skype1ico
Install xbindkeys, qdbus.
Enable KWin zoom effect. For best experience, lower the zoom multiplier.
Add this to .xbindkeysrc in your home folder (or create the file):
~/.xbindkeysrc"qdbus org.kde.kglobalaccel /component/kwin invokeShortcut view_zoom_in" alt + b:4 "qdbus org.kde.kglobalaccel /component/kwin invokeShortcut view_zoom_out" alt + b:5
assert 2 + 2 == 5 #< 2 + 2 => 4 == 5 <= 5 (AssertionError) assert "a,b,c".split == "a b c".split #< "a,b,c".split => ["a,b,c"] == ["a", "b", "c"] <= "a b c".split (AssertionError) assert [2, 4, 6].any? &.odd? #< [2, 4, 6].any?(&.odd?) (AssertionError)
Sometimes in Python you may need to diagnose some format strings. Maybe they are supposed to be provided by the user and you need to know which keys to fill it with. Another prominent example is translation software: format string placeholders are definitely a thing there, and you may want to do something special about them.
First, let's get the old-style format strings out of the way. I haven't seen any introspection capabilities for them in the standard library, so instead this neat workaround can be used: a format string is formatted by a dict-like object, which really just stores every key that it gets asked for.
The problem of intersection of two rectangles is very easy to solve. But difference of two rectangles is something considered much less frequently.
To clarify, we will be looking only at rectangles that are parallel to the 2D axes.
Obviously, when one rectangle chomps away a part of another, typically it can no longer be represented as just one rectangle. The illustration shows these different cases. The solution described here represents the difference as a sum of multiple rectangles. It does not try to represent it in as few rectangles as possible, because there are multiple ways to do that and no objective way to pick one.
This example is about Flask-Admin, which is a library that adds a smart automatic CRUD panel according to your data models (typically SQLAlchemy models).
If you have a simple website or want to separate your normal user authentication system from the admin login, or just want a quick temporary solution for securing your admin panel, here is how you can do it using simple HTTP authentication:
If you are the sole user of your computer, you may want to just enable autologin without asking for password. But most often this is not an option. So when you turn on your computer, you wait for the login screen to appear, then enter the password, then wait for the auto-start programs to complete loading (or cope with the slowness).
Instead, you can have your system automatically log into your account and let the startup process take place, but also lock the screen, so the password still needs to be entered. The difference is, you can turn on your computer, then walk away somewhere, and be sure that it's 100% ready for work when you come back. Even without walking away, the time you take to enter your password is used for startup, so it's still quicker.
I realize that suspending may be an even better solution, but it's not always an option.
Let's say we got some bytestring through a socket, but it was cut off in the middle of a UTF-8 character.
We can simulate this:
bs = "приклад".encode('utf-8')[:-1] # last byte was lost print(bs) #< b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xba\xd0\xbb\xd0\xb0\xd0' bs.decode('utf-8') # UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 12: unexpected end of data
So, is this string completely undecodable? Can't we just get
Don't worry, I have a solution. Works with 3.x and 2.7!
import io import codecs bs = b'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xba\xd0\xbb\xd0\xb0\xd0' stream = io.BytesIO(bs) stream_reader = codecs.getreader('utf-8')(stream) print(stream_reader.read()) #< прикла
from sqlalchemy import create_engine from sqlalchemy.orm import scoped_session, sessionmaker from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String database_uris = ['sqlite:///a.sqlite', 'sqlite:///b.sqlite'] engines = [create_engine(uri, convert_unicode=True) for uri in database_uris] scoped_sessions = [scoped_session(sessionmaker(engine)) for engine in engines] Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String(50), unique=True) email = Column(String(120), unique=True)
import strutils, algorithm, future var names = "Brian Chris Pamela Michael Tammy Michelle Roy Timothy".split() # Find shortest and longest name block: proc `<`(a, b: string): bool = a.len < b.len echo min(names), " and ", max(names) #< Roy and Michelle # Sort names by length names.sort((a, b) => cmp(a.len, b.len)) echo names #< @[Roy, Brian, Chris, Tammy, Pamela, Michael, Timothy, Michelle]