Hi!

My name is Serhii Hamotskyi. I work as Machine learning engineer in Leipzig, Germany, but have a very wide array of interests; this website was born as a way to organize resources about it all.

Feel free to look at what you can find here and enjoy yourself.


Work log

Day 1059

211124-1744 argparse notes

(Those too after a long talk to MO at work)

Cool things about argparse:1

  • parser.add_argument('--two-words') would automatically map to args.two_words (_ vs -)!
  • One can provide complex types!2 For files, two options.
    • The first one allows to set file permissions etc., but it opens them and returns the handle to you, which you may not want.
    • pathlib.Path() works as expected, and even automagically parses string paths from args into the Path!
      • Additionally we can then establish that we’re working with Paths from the very beginning, getting rid of the str or Path ambiguity.
      • “Be strict and clear from the very beginning, then you don’t have to deal Path or str”

    • Sample of both from official documentation:
      parser.add_argument('a', type=argparse.FileType('w', encoding='latin-1'))
      parser.add_argument('b', type=pathlib.Path)
      
  • You can get defalut values from os.environ()! Then you can also run it as
    WHATVEER_VALUE=234 python3 file.py
    

A nice structure for it all is:

  1. if __name__ == '__main__': runs a function like main() getting rid of the scope issues
  2. Parsing is done my a separate function, that returns the Namespace:
    def parse_args() -> argparse.Namespace:
        parser = argparse.ArgumentParser()
        parser.add_argument('--input-directory' ..)
        return parser.parse_args()
    
  3. Then in main() we use it like args = parse_args(); if args.input_directory == ... This is nice also because then we don’t have to deal with an arparse object in main, just its results.

Also, in general, CLI programs have arguments like program --arg-one, not program --arg_one. I write the latter one because I still feel I’m in a python world, but Python would parse such dashed arguments into classic ones (see above). TODO look for some best practices for CLI programs, including Python ones, POSIX etc etc etc.


  1. argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 documentation ↩︎

  2. argparse — Parser for command-line options, arguments and sub-commands — Python 3.10.0 documentation ↩︎

211124-1731 python logging setup

(By MO at work)

Naming loggers after the package / files

Logger names can be used to cleanly output and separate them.

Assuming one has a package with multiple files/subfolders in it, it’s possible to give each one their own logger, like this:

In the main file of the package:

logger = logging.getLogger(__package__)

In all the other files:

logger = logging.getLogger(__name__)

That way paths ./package/my_module.py lead to loggers named like package.my_module that map the semantical and the directory structure.

Changing settings of the loggers

In a setup above, one can then easily change the settings of the loggers referring to them by their names.

Configuring logging: Logging HOWTO — Python 3.10.0 documentation

Changing loglevel is easy from code,

if args.debug:
		logger.setLevel(logging.DEBUG)

logging.config allows to change the config from ini-like config files. Two main ways: logging.config.fileConfig reads ini-like config files, logging.config.dictConfig 1 from dictionaries.

Sample .yaml that when converted to dict would change the loglevel of different loggers:

version: 1
                               
loggers:
	packageName.mymodule1:
		level: DEBUG
	packageName.mymodule2:
		level: DEBUG

These loggers can even include external ones!


  1. logging.config — Logging configuration — Python 3.10.0 documentation ↩︎

Day 1058

211123-2348 poetry for package management

poetry new packagename creates a poetry project

From within the folder with the package:

  • poetry install == pip3 install -r requierements.txt
  • poetry shell == source .venv/bin/activate
  • exit == deactivate

Basic usage | Documentation | Poetry - Python dependency management and packaging made easy:

  • venvs live in {cache-dir}/virtualenvs, which on my box is /home/me/.cache/pypoetry/virtualenvs/ptest-eeSDLvcF-py3.6/bin/activate
  • poetry.lock caches the resolved packages once we install things once.
    • Must mach pyproject.toml, a warning will be shown otherwise
    • It’s important to commit it to a VCS! It has the exact versions it resolves, beneficial for everyone to use them
  • poetry update updates everything to the latest versions, overwriting poetry.lock
  • poetry init initializes a project and creates a pyproject.toml interactively, allowing even to search for packages etc!

Adding packages:

  • poetry add yaml adds a package
  • poetry search yaml looks for packages in remote repos! Will tell you that you actually want pyyaml

211123-2345 python packaging

Providing a __main__.py along with __init__.py makes the package itself executable:

$ python -m module_name

__main__.py would have an usual if __name__ == "__main__" block and run stuff imported from other files of that package.

211123-2333 python packaging and poetry

(From MO’s python riddle at work)

Things declared in if __name__ == '__main__' are in global scope. Not because it’s special, but because ..global scope. All these bugs go away if you move main() to a separate function.

Code from SO answer:[^2]

In main:

>>> if __name__ == '__main__':
...     x = 1
... print 'x' in globals()
True

Inside a function:

>>> def foo():
...     if __name__ == '__main__':
...         bar = 1
... foo()
... print 'bar' in globals()
False

Python doesn’t have block-local scope, so any variables you use inside an if block will be added to the closest enclosing “real” scope.

Someone mentioned that if __name__ == '__main__' can happen anywhere in the code. Never thought about this

211123-2333 python packaging and poetry

(From MO’s python riddle at work)

Things declared in if __name__ == '__main__' are in global scope. Not because it’s special, but because ..global scope.

Code from SO answer:[^2]

In main:

>>> if __name__ == '__main__':
...     x = 1
... print 'x' in globals()
True

Inside a function:

>>> def foo():
...     if __name__ == '__main__':
...         bar = 1
... foo()
... print 'bar' in globals()
False

Python doesn’t have block-local scope, so any variables you use inside an if block will be added to the closest enclosing “real” scope.

Someone mentioned that if __name__ == '__main__' can happen anywhere in the code. Never thought about this

211123-2122 obsidian undeleting files

If sync is enabled, in settings -> Sync there’s a “Deleted files” with versions and actions.

If not, unless a setting is set to delete to Obsidian’s trash, it’s left to the filesystem, so trash can or extundelete in my case or whatever.

211123-1558 nix data science overlay

Link by M.O.: nix-community/nix-data-science: Standard set of packages and overlays for data-scientists [maintainer=@tbenst]

Day 1057

211122-0905 detectron Instances initialization

Detectron’s Instances object gets created like this, creating attributes with names unknown initially:

def __init__(self, image_size: Tuple[int, int], **kwargs: Any):
    """
    Args:
        image_size (height, width): the spatial size of the image.
        kwargs: fields to add to this `Instances`.
    """
    self._image_size = image_size
    self._fields: Dict[str, Any] = {}
    for k, v in kwargs.items():
        self.set(k, v)

Which is neat.

To create an Instances object for unit tests I did:

pred_boxes = Boxes(tensor(
[
    [ 143.8892, 1166.6632, 1358.7292, 1411.6588],
    [ 131.3727,  864.3126, 1355.7804, 1144.3668],
    [ 585.6373,  747.7184,  922.6433,  815.9998]
]))
scores = tensor(
    [0.9971, 0.9967, 0.9938]
)
pred_classes = tensor([3, 3, 3])

instances = Instances(
    image_size=(2122, 1500),
    scores=scores,
    pred_classes=pred_classes,
    pred_boxes=pred_boxes
)

211122-0256 quickly forming an URI in markdown

Found this in old markdown code from my old blog, I guess I forgot about this:

<what@ever.com>
<https://example.com>

Day 1056

211121-2201 vim opening more than 10 tabs

When opening a lot of files as vim -p *.md* only 10 kept being opened, finally googled it.

Solution: adding set tabpagemax=50 to ~/.vimrc

211121-2137 replace a string in all files recursively

From SO1:

find . -name '*.php' -exec sed -i -e 's/www.fubar.com/www.fubar.ftw.com/g' {} \;

  1. bash - Replace a string with another string in all files below my current dir - Stack Overflow ↩︎

211121-2123 git undoing git add unstaging files


title: “211121-2123 Undoing git add / unstaging files” tags:

  • “zc”
  • “zc/it”
  • “git” fulldate: 2021-11-21T21:11:47+0100 date: 2021-11-21 layout: post hidden: false draft: false

Two different questions here! Both options are: 1 If you add a file for the first time, git rm --cached . or git -rm -r --cached . will reverse that.

If you want to un-add changes to a file that’s already in the repo, git reset <file> / git reset will undo that.


  1. How do I undo ‘git add’ before commit? - Stack Overflow ↩︎

Day 1053

211118-1832 mob programming and mob review

(heard at work)

The basic concept of mob programming is simple: the entire team works as a team together on one task at the time. That is: one team – one (active) keyboard – one screen (projector of course).

— Marcus Hammarberg, Mob programming – Full Team, Full Throttle1

“"Mob programming is a software development approach where the whole team works on the same thing, at the same time, in the same space, and at the same computer. “Mob code review is a software development approach where the whole team reviews on the same thing, at the same time, in the same space, and at the same computer.”2


  1. Mob programming - Wikipedia ↩︎

  2. From no code review to mob code review | by Nicolas Dupont | Akeneo Labs | Medium↩︎

211118-0024 python namedtuple

Python’s NamedTuple is really cool!

Python’s Instance, Class, and Static Methods Demystified – Real Python is an excellent guide, as is the entire website.

NamedTuple VS Dataclass, copying from SO answer:[^1] When your data structure needs to/can be immutable, hashable, iterable, unpackable, comparable then you can use NamedTuple. If you need something more complicated, for example, a possibility of inheritance for your data structure then use Dataclass.

The immutable part is important - can’t do named_tuple.value = 3 after creating it.

Can be created also through colections.namedtuple, copied directly from :

>>> from collections import namedtuple

>>> Person = namedtuple("Person", "name children")
>>> john = Person("John Doe", ["Timmy", "Jimmy"])
>>> john
Person(name='John Doe', children=['Timmy', 'Jimmy'])
>>> id(john.children)
139695902374144

Journal

Old blog - randomness of this week

date: 2013-10-03T16:52:37+00:00
guid: http://shmt.pp.ua/blog/?p=326

Nowplaying: Amber Route – “Don’t drink lemonade formaldehyde”

Музика, про яку не варто було б забути:

  • Amber route
  • September Malevolence
  • Franco Battiato
  • Аквариум
  • Smokie

Нові слова:

  • Ерзац (ersatz) — німецьке слово, що буквально означає заміну (замінюючи) або заміни[1]. Продукт, зазвичай, поступається за якістю, наприклад, «цикорієва ерзац-кава»; неповноцінний замінник.

    • (вперше зіштовхнувся з ним у Чубая ще влітку, не мав під рукою словника)
  • In the United States, a furlough (/ˈfɜrl/; from Dutch: “verlof”) is a temporary unpaid leave of some employees due to special needs of a company, which may be due to economic conditions at the specific employer or in the economy as a whole

  • Thanatology is the scientific study of death.

Programming is

From old blog, date: 2015-11-29T13:49:32+00:00

  • Programming as a way to do brilliant things.
  • Programming as an art.
  • Programming as a way to challenge my skills.
  • Programming as a way to change the world.
  • Programming as a way to be free.
  • Programming as a way to have a purpose.
  • Programming as a way not to be afraid — “Я могу все.”
  • Programming as a way to improve myself.
  • Programming to BE.
  • Programming as an awesome thing to know.
  • Programming as magic.
  • Programming as a way to solve many problems.
  • Programming as beauty.
  • Programming as learning; programming as hunger for knowledge.
  • Programming as playing God.
  • Programming as constant self-improvement.
  • Programming as mindset.
  • Programming as opportunity to understand how complex systems work.
  • Programming as opportunity to understand how complex systems can be made work differently than intended.
  • Programming as a medium of expression.

Quotes from my old blog

From my old blog:

Я никогда не могла понять, почему так мало людей не могут мне ответить на вопрос: “Чего ты хочешь?” Это серьезно какой-то баг в большинстве людей. Свои цели на будущее нужно осознавать предельно четко, и периодически вспоминать о них. (с) М.

“Keeping options open” often means “not being successful in anything” ((https://www.quora.com/How-do-you-decide-what-to-do-when-you-are-multitalented-and-want-to-have-all-of-it/answer/Shulamit-Widawsky))


W/o sources:

Whenever Jobs suffered a setback, it wasn’t too long before he was looking forward and thinking about what he should do next.

“What’s the point in looking back,” he told me in one email. “I’d rather look forward to all the good things to come.”- Brent Schlender and Rick Tetzeli, Becoming Steve Jobs

Celebrate other people’s success and you’ve accomplished, but raise the bar a little higher each time you succeed.

Refuse to accept that something is beyond your understanding. Sometimes, you have to learn a set of special codes and symbols to get at the knowledge you want. You cannot allow language acquisition, whether of spoken  communication or a set of mathematical, electric, or other scientific code, to daunt you.

First find a good direction, and once you’re sure you’re going the right direction, start going faster. First be resultative, then increase productivity; Success is measured in output of value, not input of effort. + http://www.arhivstatey.ru/articles/organizer/index.html

Two kinds of self-confidence

From old blog:

date: 2016-09-19T15:36:09+00:00

There are two forms of confidence: contextual — how well you can do something particular (driving, public speaking, …), and general — the confidence that no matter in which unknown situation you are thrown in, you’ll find a way. The second kind is necessary to continually try new things. (from http://highability.org/756/using-your-multipotentiality-to-grow-your-confidence/)

Fail fast and iterate