In the middle of the desert you can say anything you want
An incredibly clear explanation, copypasted from StackOverflow, about the flavours of git reset --xxx HEAD~1
In the simplest terms:
--soft
: uncommit changes, changes are left staged (index).--mixed
(default): uncommit + unstage changes, changes are left in working tree.--hard
: uncommit + unstage + delete changes, nothing left.A @classmethod
gets the class as first parameter, nice for constructors/factories etc. A @staticmethod
doesn’t know anything about the class at all, and the only use it has is to put functions that logically belong to the class inside the class. 1
Additionally,
Contains books / resources about ML, from foundations to roadmaps / learning paths , “channels” (sites that regularly publish ML content), etc.
Really really impressive.
Yaml 1.1 interprets the following strings as booleans, if unquoted: 1
y|Y|yes|Yes|YES|n|N|no|No|NO
|true|True|TRUE|false|False|FALSE
|on|On|ON|off|Off|OFF
Related + YAML hate:
.. is probably my new obsession, along with getting it to play nicely with Hugo. It’s a closed non-open-source system but files are saved as markdown, has an awesome Android app - everything I’ve ever wanted except openness, basically.
So:
Templater1 is a community plugin for template stuff, but supports neat things like getting clipboard data, creating files, etc. Additionally supports automatically using templates when creating notes in a folder or in general and a lot of other excellent stuff.
This template gets run manually after I create and name a note. When I run it, it autogenerates Hugo front matter, gets the title from the filename, and puts the cursor in the first tag. The second tag is created from the folder name where the note is located, currently I defined two: it
and rl
.
---
title: "<% tp.file.title %>"
tags:
- "zc"
- "zc/<% tp.file.folder() %>"
- "<% tp.file.cursor() %>"
fulldate: <% tp.date.now("YYYY-MM-DDTHH:MM:SSZZ") %>
date: <% tp.date.now("YYYY-MM-DD") %>
hidden: false
draft: true
---
I looked at zoni/obsidian-export: Rust library and CLI to export an Obsidian vault to regular Markdown and khalednassar/obyde: A minimal tool to convert a standardly configured Obsidian vault to a Jekyll or Hugo blog., found the latter to be a bit clearer in how it handles assets etc. It requires a date
in frontmatter in YYYY-MM-DD
format, which I provided.
round()
has weirdly unexpected behaviour that I’m ashamed I didn’t notice or know about:
if two multiples are equally close, rounding is done toward the even choice (so, for example, both round(0.5) and round(-0.5) are 0, and round(1.5) is 2) 1
So:
>>> round(1.5)
2
>>> round(2.5)
2
>>> round(3.5)
4
math.isclose()
to check for “almost equal”Had an issue with checking whether a sum of floats sums up to a number, remembering that python floats are ‘special’:
>>> 0.1 + 0.2
0.30000000000000004
Stack overflow1 told me about math.isclose()
, works as you’d expect:
assert math.isclose(sum(floats), needed_sum)
From unittest documentation 1
class MyTestCase(unittest.TestCase):
@unittest.skipIf(mylib.__version__ < (1, 3), "not supported in this library version")
def test_format(self):
# Tests that work for only a certain version of the library.
pass
You can minimize your own video, and then make the entire window much smaller!
Obvious, but: you can declare strings and format them in separate places!
constants.py
:
my_string = "Hello my name is {0}"
other_file.py
:
from constants import my_string
print(my_string.format("Serhii"))
<C-S-F10>
runs the unittest where the cursor is currently located. Or all of them if located anywhere else in the file.
TODO: set binding to do the same, but debugging.
I wanted to run only some test files, all except the ones where I needed a GPU. Wrote this:
import subprocess
# Parts of filenames to exclude
large_tests = ['component', 'test_temp']
test_folder = Path(__file__).parent.absolute()
test_files = list(test_folder.glob("test_*.py"))
test_files = [x.name for x in test_files]
for l in large_tests:
test_files = list(filter(lambda x: l not in x, test_files))
commands = ["python3", "-m", "unittest"] + test_files
subprocess.run(commands, cwd=test_folder)
Notes:
shell=True
is explicitly passed, no shell is called, ergo no shell-command-injection stuff is possible.os.chdir()
is nicely replaced by the cwd=
parameter, much nicer than what I’d have done previously!def my_function(other_function: Callable) -> Callable:
return other_function
What I’d do as
cd tests
python3 -m unittest
in Pycharm is right-clicking on a directory in Project view and “Run unittests”
Open/Closed principle: you should be able to open a module/class to add stuff easily, but otherwise you shouldn’t need to touch it for existing stuff.
dir
Wrote a line like if dir is not None ..
, but dir
is a builtin! It returns all the names in the current scope.
You can add Watches, values that will be shown and tracked! Nice for debugging stuff that needs values that are deep in other variables
class-level:
setUpClass(cls)
gets called before tests from one class get run, not once per testtearDownClass(cls)
gets called before tests from one class get run, not once per test class Test(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls._connection = createExpensiveConnectionObject()
module-level
setUpModule()
, tearDownModule()
Aaanad if you set any class variables, you can still access them as self.xxx
from within the tests!
or
in argumentsNeat thing seen in detectron default_argument_parser
:
def argparser(epilog=None):
...
x = epilog or "here's some text"
Where “here’s some text” is a long string that doesn’t really belong in the function signature.
A really nice pattern, much better than my usual
if x is None:
x = ...