diff --git a/docs/index.html b/docs/index.html index e99ac04..cc7355c 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,6 +1,6 @@ Andrey Nautilus blog

Hi there 👋

Welcome to my blog

Random point in circle with uniform distribution

angle = random(); distance = R * sqrt(random())

July 29, 2024 · 1 min

Evenly distributed random points

Bridson’s Algorithm to build Poisson disk distribution of points

July 21, 2024 · 3 min

Linux process memory: RSS, VSZ, etc

RSS, VSZ, PSS, USS explained

July 16, 2024 · 1 min

Documenting code

names = what, code = how, comments = why

May 26, 2024 · 1 min

git with multiple users

Configure multiple git users on the same workstation

May 22, 2024 · 3 min

git push --force vs --force-with-lease

Prefer ‘git push –force-with-lease’ over ‘git push –force’

May 16, 2024 · 5 min

Random points in circle with uniform distribution

angle = random(); distance = R * sqrt(random())

Evenly distributed random points

Bridson’s Algorithm to build Poisson disk distribution of points

Linux process memory: RSS, VSZ, etc

RSS, VSZ, PSS, USS explained

Documenting code

names = what, code = how, comments = why

git with multiple users

Configure multiple git users on the same workstation

git push --force vs --force-with-lease

Prefer ‘git push –force-with-lease’ over ‘git push –force’

diff --git a/docs/index.json b/docs/index.json index 4d19000..c77454f 100644 --- a/docs/index.json +++ b/docs/index.json @@ -1 +1 @@ -[{"content":"We need to generate a random point in a circle with uniform distribution.\nA naive approach with picking a random angle and a random distance doesn\u0026rsquo;t have uniform distribution - there are more points close to center and fewer points at the radius. This article has explanation and visualization.\nCorrect formula for polar coordinates In polar coordinates:\nangle = random(0, 2 * PI) distance = R * sqrt(random(0, 1)) Where R is the radius of the circle. And transformation to Cortesian coordinates:\nx = distance * cos(angle) y = distance * sin(angle) This article and StackOverflow threads give a mathematically correct explanation.\nMultiple attempts Another approach is to generate uniformly distributed random points in the bounding box of the circle and pick the first point that is inside the circle.\nWith random() being a uniformly random number, the naive approach for a point in a square:\nx = random() y = random() give uniformly distributed points. And x * x + y * y \u0026lt;= R * R provides an easy test for point being inside the circle.\nObvious drawback - undefined number of attempts, but with uniformly distributed points in a box the average amount of attempt should not be greater than 2.\n","permalink":"https://andreynautilus.github.io/posts/2024-07-29-random-point-in-circle/","summary":"angle = random(); distance = R * sqrt(random())","title":"Random point in circle with uniform distribution"},{"content":"\u0026ldquo;Random\u0026rdquo; points on a plane We need to generate random, evenly distributed points on a plane. Possible use-cases:\ngenerate trees in a forest in a game world; generate points for Voronoi diagram (with areas of similar size); The simplest approach - to use uniformly distributed points with (random(), random()) - doesn\u0026rsquo;t work, because there will be areas with high density of points and areas with no points at all. Such distribution doesn\u0026rsquo;t look natural.\nCaption Various types of grids with gaps can give even distribution, but the picture will not look random. There will always be a pattern, sometimes more visible, sometimes less, but still visible. This doesn\u0026rsquo;t look natural either.\nA solution to this problem is Poisson disk sampling (or Poisson disk distribution): points are placed randomly, but not too close and not too far away from each other.\nCaption This article compares randomly placed points with Poisson disk distribution, and shows \u0026ldquo;best candidate\u0026rdquo; and Bridson’s algorithms to build such distribution (with great examples and visualizations).\nBridson’s algorithm for Poisson disk sampling Summary of this page. Bridson\u0026rsquo;s algorithm allows us to generate random points with Poisson disk distribution.\nFormal problem description: generate tightly packed random points maintaining minimal distance between them.\nAlgorithm parameters:\narea where points should be generated; r - minimum distance between any 2 points; k - amount of attempts to generate a new point; The algorithm uses a grid with r/sqrt(2) cell size. There could be at most 1 point in any grid cell. The value of a cell is either an index of a generated point or -1.\nThe algorithm:\ninitialize the grid that covers the requested area with -1 in each cell; generate an initial point p0 and set the corresponding grid cell to 0 (the first point); initialize a list of active points with index 0; pick a random index from active points (let\u0026rsquo;s say p-i). Generate up to k random points in annulus between r and 2r form the selected point p-i; test every generated point if it\u0026rsquo;s far enough (dist \u0026gt;=r) from already existing points (use the grid to test only nearby cells); if a generated point is far enough from all existing points, add it to the list of generated points, update the grid cell with its index and add this new point to active points; if all k points are too close to already existing points, then remove p-i from active points; repeat until list of active points is empty; Side notes:\ncomplexity is O(N); easy to implement; the cluster of points grows naturally from the starting point to all directions; easily extensible to 3D (and more dimensional) space; the number of points is not known until the generation process is complete (it\u0026rsquo;s \u0026ldquo;generate some points with specific condition\u0026rdquo; rather than \u0026ldquo;generate N points\u0026rdquo;); Links https://www.jasondavies.com/poisson-disc/ ","permalink":"https://andreynautilus.github.io/posts/2024-07-21-evenly-random-points-on-plane/","summary":"Bridson’s Algorithm to build Poisson disk distribution of points","title":"Evenly distributed random points"},{"content":"Linux has multiple values that represent the amount of memory associated with a process:\nRSS or Resident Set Size or RES - total amount of physical memory associated with the process including all shared libraries. PSS or Proportional Set Size - similar to RSS, but shared libraries are counted proportionally: if a library is loaded by multiple (let\u0026rsquo;s say 5) processes, associated memory will be distributed proporiaonally between them (each process will get 1/5 of the library memory). Sum of PSS values of all processes shows total system usage. USS or Unique Set Size - memory unique to the process. When the process is killed, this amount will be returned to the system. VSS or Virtual Set Size or VSZ - total accessible address space of a process including swapped memory and allocated, but not yet used. Examples top command shows VSS (as VIRT) and RSS (as RES):\nPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 650 andrey 20 0 2892 932 840 S 0.0 0.0 0:00.00 sh ps -ux shows VSS (as VSZ) and RSS:\nUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND andrey 650 0.0 0.0 2892 932 pts/0 S+ Jul20 0:00 sh Links For more details see:\nhttps://stackoverflow.com/questions/22372960/is-this-explanation-about-vss-rss-pss-uss-accurate https://2net.co.uk/tutorial/procrank ","permalink":"https://andreynautilus.github.io/posts/2024-07-16-linux-process-memory/","summary":"RSS, VSZ, PSS, USS explained","title":"Linux process memory: RSS, VSZ, etc"},{"content":"Summary of \u0026ldquo;My 3 Rules for Documenting Code\u0026rdquo; article.\nNames (classes, variables, functions) should explain What (what is it? what does this function do?). Code should explain How (how is it implemented?). Comments should explain Why (why is it implemented this way?). Added to the Collection of links.\n","permalink":"https://andreynautilus.github.io/posts/2024-05-26-documenting-code/","summary":"names = what, code = how, comments = why","title":"Documenting code"},{"content":"Multiple users Quite often we need to have multiple git users on the same workstation. For example:\na user for working account; a user for personal account; These users should have different name and email, and might need different configuration and authentication. Accounts for the users can be on different platforms (GitHub, GitLab, BitBucket etc) or on the same.\nA simple solution would be to use repository-local (git config --local) configuration, but this means repeating it over and over again for every cloned repository. This is not an engineers way.\nConfigure git per directory Git stores global configuration in ~/.gitconfig file. It\u0026rsquo;s a text file which supports conditional includes via includeIf directive. We\u0026rsquo;re interested in gitdir condition, which includes the file if the current repository (.git folder of the current repository) is in the specified directory.\nSo, we can nicely isolate all work-related repositories in ~/work directory and all personal repositories in ~/personal directory. For example, the main ~/.gitconfig file may look like:\n[user] name = Alex Green email = alex.green@company.com [includeIf \u0026#34;gitdir:~/work/\u0026#34;] path = ~/.gitconfig-work [includeIf \u0026#34;gitdir:~/personal/\u0026#34;] path = ~/.gitconfig-personal while ~/.gitconfig-work enables commit signing for work account:\n[user] signingkey = XXXXXXX [gpg] program = gpg [commit] gpgsign = true and ~/.gitconfig-personal redefines user name and email for personal account:\n[user] name = Mr Green email = mr-green@personal.com See:\n~/work/company-project $ git config --get user.name Alex Green ~/personal/awesome-project $ git config --get user.name Mr Green ssh authentication Most git platforms (GitHub, GitLab, BitBucket etc) support ssh authentication, and we can configure it in ~/.ssh/config file of our ssh client:\nHost github.com IdentityFile ~/.ssh/github Host bitbucket.com IdentityFile ~/.ssh/bitbucket Then both\ngit clone git@github.com:organization/repository.git git clone git@bitbucket.org:organization/repository.git work and use corresponding ssh keys.\nssh authnetication for the same host But what if we have multiple accounts on the same platform (both accounts are on GitHub for example)? Well, ssh client doesn\u0026rsquo;t know which key to use, so we need to tell it via different host. We can configure the ssh client with artificial host for one of the accounts (for example for personal account):\nHost github.com-personal IdentityFile ~/.ssh/github-personal Host github.com IdentityFile ~/.ssh/github-work Then git clone git@github.com:organization/repository.git will use ~/.ssh/github-work key.\nBut in order to clone a repository using personal ~/.ssh/github-personal key, we need to change the host in url manually (note github.com-personal instead of github.com):\ngit clone git@github.com-personal:organization/repository.git This means we can\u0026rsquo;t use the \u0026ldquo;default\u0026rdquo; clone command provided by the platform, we need to manually adjust it.\nHint: it\u0026rsquo;s generally more convenient to have the \u0026ldquo;default\u0026rdquo; configuration for the account which is used to clone repositories more often, because we can use the \u0026ldquo;default\u0026rdquo; clone command from the platform.\nSome references:\nhttps://stackoverflow.com/questions/67593657/setting-up-multiple-ssh-key-access-to-github https://gist.github.com/alejandro-martin/aabe88cf15871121e076f66b65306610 using core.sshCommand config option (or GIT_SSH_COMMAND environment variable) it\u0026rsquo;s possible to distinguish ssh keys based on current folder; Commit signing Some platforms may require commit signing. I use gpg key for that. GitHub documentation explains how to set it up. We can also configure git to sign our commits by default:\n[user] signingkey = XXXXXXX [gpg] program = gpg [commit] gpgsign = true ","permalink":"https://andreynautilus.github.io/posts/2024-05-22-git-multiple-users/","summary":"Configure multiple git users on the same workstation","title":"git with multiple users"},{"content":"Why do we need to force-push? Force-pushing is not always a bad thing. Sometimes we actually want to re-write the git history. This can be useful if:\nwe want to update a commit message of a previous commit (git commit --amend); we want to squash-merge dozens of small commits before presenting the code to the review (git rebase autosquash -i). When combined with fixup commits this allows to group changes in well-described commits; we want to remove sensitive information (like leaked credential) from the repository; we rebase our branch (on top of the updated main for example); In all these cases we actually want to re-write the git history, so we need to use force-push.\nA safer force-push But git push --force is a dangerous, unconditional override of the history on remote.\nIn git we usually have a branch per feature. This branch is usually maintained by a single developer from the creation till merge, and usually force-pushing to this branch is a relatively safe operation with low risk of overriding someones work. Still sometimes other authors (developers or automation) may push to your feature branch and we don\u0026rsquo;t want to lose these changes.\nTo completely avoid the risk, we should use git push --force-with-lease instead of git push --force. --force-with-lease will block the operation if the remote branch has changes that are not in your local copy. Official documentation has a bit more detailed explanation, but in simple words:\n--force-with-lease will not allow you to override someones changes that were not pulled to your local copy.\nAs a rule of thumb: always use --force-with-lease unless you have very good reasons to use --force.\nDanger zone If after re-writing your local history, but before pushing the changes to remote, you update your local remote-tracking branches (with git fetch for example), --force-with-lease will not save you from overriding others changes. In this case git assumes that\u0026rsquo;s your intention to override someones changes.\nExample Let\u0026rsquo;s simulate this scenario locally, I\u0026rsquo;ll use fixup commits as example. git can use a local repository as remote (I\u0026rsquo;ll use bare repository for this). We\u0026rsquo;re interested in commits, not the actual changes, so all commits will be empty (done with --allow-empty flag).\nInitial setup First, let\u0026rsquo;s create a remote (a bare git repository):\n$ mkdir remote $ cd remote remote $ git init --bare Mr.Green clones the repository, configures the user, initializes the main branch with an empty commit and pushes it to the remote:\n$ mkdir green $ git clone remote green $ cd green green $ git config --local user.name \u0026#34;Alex Green\u0026#34; green $ git config --local user.email \u0026#34;alex.green@address.com\u0026#34; green $ git commit -m \u0026#34;initial commit\u0026#34; --allow-empty green $ git push origin main Next, his co-worker, Mr.Red clones the repository and configures his user:\n$ mkdir red $ git clone remote red $ cd red red $ git config --local user.name \u0026#34;Bob Red\u0026#34; red $ git config --local user.email \u0026#34;bob.red@address.com\u0026#34; Now we have 2 clones from different people of the same remote.\nCreating a conflict Mr.Red creates a branch, makes a few changes and pushes the branch to the remote:\nred $ git checkout -b feature_branch red $ git commit -m \u0026#34;change from Red 1\u0026#34; --allow-empty red $ git commit --fixup HEAD --allow-empty red $ git push --set-upstream origin feature_branch Mr.Red invites his co-worker - Mr.Green - to help. Mr.Green checks out feature_branch, makes some changes and pushes the branch back to remote:\ngreen $ git pull green $ git checkout feature_branch green $ git commit -m \u0026#34;change from Green 1\u0026#34; --allow-empty green $ git push origin feature_branch In the meanwhile, Mr.Red continues to make changes. When ready, he squashes the changes to produce a \u0026ldquo;clean\u0026rdquo; history for the review process:\nred $ git commit --fixup HEAD~1 --allow-empty red $ git rebase --autosquash --interactive HEAD~3 # accept all changes Boom! Now the git history in Mr.Reds local copy has a conflict with the remote (what Mr.Green pushed):\nred $ git log --oneline feature_branch 266b934 (HEAD -\u0026gt; feature_branch) change from Red 1 71737b9 (origin/main, origin/HEAD, main) initial commit green $ git log --oneline feature_branch fa25da6 (HEAD -\u0026gt; feature_branch, origin/feature_branch) change from Green 1 c905bcf fixup! change from Red 1 863c570 change from Red 1 71737b9 (origin/main, main) initial commit (note the commit hashes!)\nHandling the conflict Mr.Red re-wrote the history of his branch, and if he tries to git push, the operation will fail. Mr.Red knows that he needs to force-push in order to send his branch to the remote.\nMr.Red might not be aware of the changes from Mr.Green, so using git push --force will override the commit from Mr.Green. --force-with-lease prevents it:\nred $ git push origin feature_branch --force-with-lease To C:/Projects/git_push_force_example/remote ! [rejected] feature_branch -\u0026gt; feature_branch (stale info) error: failed to push some refs to \u0026#39;C:/Projects/git_push_force_example/remote\u0026#39; Voila! Mr.Red didn\u0026rsquo;t override someones commit and needs to rebase and re-apply his changes.\nDanger zone If Mr.Red updates his local remote-tracking branches (with git fetch):\nred $ git log --oneline origin/feature_branch c905bcf (origin/feature_branch) fixup! change from Red 1 863c570 change from Red 1 71737b9 (origin/main, origin/HEAD, main) initial commit red $ git fetch red $ git log --oneline origin/feature_branch fa25da6 (origin/feature_branch) change from Green 1 c905bcf fixup! change from Red 1 863c570 change from Red 1 71737b9 (origin/main, origin/HEAD, main) initial commit the push operation will succeed and it will override the commit from Mr.Green on the remote. This happens, because git fetch brings the commit from Mr.Green to the local copy of Mr.Red, and git assumes that Mr.Red actually wants to override the commit from Mr.Green.\nConclusion Always prefer git push --force-with-lease over git push --force and use git fetch consciously.\n","permalink":"https://andreynautilus.github.io/posts/2024-05-16-git-force-vs-force-with-lease/","summary":"Prefer \u0026lsquo;git push \u0026ndash;force-with-lease\u0026rsquo; over \u0026lsquo;git push \u0026ndash;force\u0026rsquo;","title":"git push --force vs --force-with-lease"},{"content":"Tools https://regex101.com/ - online RegEx tester/debugger https://crontab.guru/ - cron explainer https://github.com/refined-github/refined-github - browser extension to greatly enrich GitHub UI https://ohshitgit.com/ - git cheatsheet for \u0026ldquo;shit happened\u0026rdquo; cases Procedural generation https://www.boristhebrave.com/ - blog about procedural generation: diablo 1 dungeon generation, unexplored dungeon generation, etc. Overview of Maze generation algorithms Poisson disk sampling and Bridson’s algorithm - (post) Random point in a circle with uniform distribution - (post) Other \u0026ldquo;My 3 Rules for Documenting Code\u0026rdquo; article (post) Linux process memory: RSS, PSS, USS explained (post) Soma on dev.to - collection of 101 articles about System Design ","permalink":"https://andreynautilus.github.io/links/","summary":"Tools https://regex101.com/ - online RegEx tester/debugger https://crontab.guru/ - cron explainer https://github.com/refined-github/refined-github - browser extension to greatly enrich GitHub UI https://ohshitgit.com/ - git cheatsheet for \u0026ldquo;shit happened\u0026rdquo; cases Procedural generation https://www.boristhebrave.com/ - blog about procedural generation: diablo 1 dungeon generation, unexplored dungeon generation, etc. Overview of Maze generation algorithms Poisson disk sampling and Bridson’s algorithm - (post) Random point in a circle with uniform distribution - (post) Other \u0026ldquo;My 3 Rules for Documenting Code\u0026rdquo; article (post) Linux process memory: RSS, PSS, USS explained (post) Soma on dev.","title":"Collection of useful links"}] \ No newline at end of file +[{"content":"We need to generate a random point in a circle with uniform distribution.\nA naive approach with picking a random angle and a random distance doesn\u0026rsquo;t have uniform distribution - there are more points close to center and fewer points at the radius. This article has explanation and visualization.\nNNN points, left to right: naive approach, correct formula, Monte Carlo (XXX attempts) Correct formula for polar coordinates In polar coordinates:\nangle = random(0, 2 * PI) distance = R * sqrt(random(0, 1)) Where R is the radius of the circle. And transformation to Cortesian coordinates:\nx = distance * cos(angle) y = distance * sin(angle) This article and StackOverflow threads give a mathematically correct explanation.\nMonte Carlo (multiple attempts) Another approach is to generate uniformly distributed random points in the bounding box of the circle and pick the first point that is inside the circle.\nWith random() being a uniformly random number, the naive approach for a point in a square:\nx = random() y = random() give uniformly distributed points. And x * x + y * y \u0026lt;= R * R provides an easy test for point being inside the circle.\nObvious drawback - undefined number of attempts, but with uniformly distributed points in a box the average amount of attempt should not be greater than 2 (on average we need 4 / PI attempts).\n","permalink":"https://andreynautilus.github.io/posts/2024-07-29-random-points-in-circle/","summary":"angle = random(); distance = R * sqrt(random())","title":"Random points in circle with uniform distribution"},{"content":"\u0026ldquo;Random\u0026rdquo; points on a plane We need to generate random, evenly distributed points on a plane. Possible use-cases:\ngenerate trees in a forest in a game world; generate points for Voronoi diagram (with areas of similar size); The simplest approach - to use uniformly distributed points with (random(), random()) - doesn\u0026rsquo;t work, because there will be areas with high density of points and areas with no points at all. Such distribution doesn\u0026rsquo;t look natural.\nCaption Various types of grids with gaps can give even distribution, but the picture will not look random. There will always be a pattern, sometimes more visible, sometimes less, but still visible. This doesn\u0026rsquo;t look natural either.\nA solution to this problem is Poisson disk sampling (or Poisson disk distribution): points are placed randomly, but not too close and not too far away from each other.\nCaption This article compares randomly placed points with Poisson disk distribution, and shows \u0026ldquo;best candidate\u0026rdquo; and Bridson’s algorithms to build such distribution (with great examples and visualizations).\nBridson’s algorithm for Poisson disk sampling Summary of this page. Bridson\u0026rsquo;s algorithm allows us to generate random points with Poisson disk distribution.\nFormal problem description: generate tightly packed random points maintaining minimal distance between them.\nAlgorithm parameters:\narea where points should be generated; r - minimum distance between any 2 points; k - amount of attempts to generate a new point; The algorithm uses a grid with r/sqrt(2) cell size. There could be at most 1 point in any grid cell. The value of a cell is either an index of a generated point or -1.\nThe algorithm:\ninitialize the grid that covers the requested area with -1 in each cell; generate an initial point p0 and set the corresponding grid cell to 0 (the first point); initialize a list of active points with index 0; pick a random index from active points (let\u0026rsquo;s say p-i). Generate up to k random points in annulus between r and 2r form the selected point p-i; test every generated point if it\u0026rsquo;s far enough (dist \u0026gt;=r) from already existing points (use the grid to test only nearby cells); if a generated point is far enough from all existing points, add it to the list of generated points, update the grid cell with its index and add this new point to active points; if all k points are too close to already existing points, then remove p-i from active points; repeat until list of active points is empty; Side notes:\ncomplexity is O(N); easy to implement; the cluster of points grows naturally from the starting point to all directions; easily extensible to 3D (and more dimensional) space; the number of points is not known until the generation process is complete (it\u0026rsquo;s \u0026ldquo;generate some points with specific condition\u0026rdquo; rather than \u0026ldquo;generate N points\u0026rdquo;); Links https://www.jasondavies.com/poisson-disc/ ","permalink":"https://andreynautilus.github.io/posts/2024-07-21-evenly-random-points-on-plane/","summary":"Bridson’s Algorithm to build Poisson disk distribution of points","title":"Evenly distributed random points"},{"content":"Linux has multiple values that represent the amount of memory associated with a process:\nRSS or Resident Set Size or RES - total amount of physical memory associated with the process including all shared libraries. PSS or Proportional Set Size - similar to RSS, but shared libraries are counted proportionally: if a library is loaded by multiple (let\u0026rsquo;s say 5) processes, associated memory will be distributed proporiaonally between them (each process will get 1/5 of the library memory). Sum of PSS values of all processes shows total system usage. USS or Unique Set Size - memory unique to the process. When the process is killed, this amount will be returned to the system. VSS or Virtual Set Size or VSZ - total accessible address space of a process including swapped memory and allocated, but not yet used. Examples top command shows VSS (as VIRT) and RSS (as RES):\nPID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 650 andrey 20 0 2892 932 840 S 0.0 0.0 0:00.00 sh ps -ux shows VSS (as VSZ) and RSS:\nUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND andrey 650 0.0 0.0 2892 932 pts/0 S+ Jul20 0:00 sh Links For more details see:\nhttps://stackoverflow.com/questions/22372960/is-this-explanation-about-vss-rss-pss-uss-accurate https://2net.co.uk/tutorial/procrank ","permalink":"https://andreynautilus.github.io/posts/2024-07-16-linux-process-memory/","summary":"RSS, VSZ, PSS, USS explained","title":"Linux process memory: RSS, VSZ, etc"},{"content":"Summary of \u0026ldquo;My 3 Rules for Documenting Code\u0026rdquo; article.\nNames (classes, variables, functions) should explain What (what is it? what does this function do?). Code should explain How (how is it implemented?). Comments should explain Why (why is it implemented this way?). Added to the Collection of links.\n","permalink":"https://andreynautilus.github.io/posts/2024-05-26-documenting-code/","summary":"names = what, code = how, comments = why","title":"Documenting code"},{"content":"Multiple users Quite often we need to have multiple git users on the same workstation. For example:\na user for working account; a user for personal account; These users should have different name and email, and might need different configuration and authentication. Accounts for the users can be on different platforms (GitHub, GitLab, BitBucket etc) or on the same.\nA simple solution would be to use repository-local (git config --local) configuration, but this means repeating it over and over again for every cloned repository. This is not an engineers way.\nConfigure git per directory Git stores global configuration in ~/.gitconfig file. It\u0026rsquo;s a text file which supports conditional includes via includeIf directive. We\u0026rsquo;re interested in gitdir condition, which includes the file if the current repository (.git folder of the current repository) is in the specified directory.\nSo, we can nicely isolate all work-related repositories in ~/work directory and all personal repositories in ~/personal directory. For example, the main ~/.gitconfig file may look like:\n[user] name = Alex Green email = alex.green@company.com [includeIf \u0026#34;gitdir:~/work/\u0026#34;] path = ~/.gitconfig-work [includeIf \u0026#34;gitdir:~/personal/\u0026#34;] path = ~/.gitconfig-personal while ~/.gitconfig-work enables commit signing for work account:\n[user] signingkey = XXXXXXX [gpg] program = gpg [commit] gpgsign = true and ~/.gitconfig-personal redefines user name and email for personal account:\n[user] name = Mr Green email = mr-green@personal.com See:\n~/work/company-project $ git config --get user.name Alex Green ~/personal/awesome-project $ git config --get user.name Mr Green ssh authentication Most git platforms (GitHub, GitLab, BitBucket etc) support ssh authentication, and we can configure it in ~/.ssh/config file of our ssh client:\nHost github.com IdentityFile ~/.ssh/github Host bitbucket.com IdentityFile ~/.ssh/bitbucket Then both\ngit clone git@github.com:organization/repository.git git clone git@bitbucket.org:organization/repository.git work and use corresponding ssh keys.\nssh authnetication for the same host But what if we have multiple accounts on the same platform (both accounts are on GitHub for example)? Well, ssh client doesn\u0026rsquo;t know which key to use, so we need to tell it via different host. We can configure the ssh client with artificial host for one of the accounts (for example for personal account):\nHost github.com-personal IdentityFile ~/.ssh/github-personal Host github.com IdentityFile ~/.ssh/github-work Then git clone git@github.com:organization/repository.git will use ~/.ssh/github-work key.\nBut in order to clone a repository using personal ~/.ssh/github-personal key, we need to change the host in url manually (note github.com-personal instead of github.com):\ngit clone git@github.com-personal:organization/repository.git This means we can\u0026rsquo;t use the \u0026ldquo;default\u0026rdquo; clone command provided by the platform, we need to manually adjust it.\nHint: it\u0026rsquo;s generally more convenient to have the \u0026ldquo;default\u0026rdquo; configuration for the account which is used to clone repositories more often, because we can use the \u0026ldquo;default\u0026rdquo; clone command from the platform.\nSome references:\nhttps://stackoverflow.com/questions/67593657/setting-up-multiple-ssh-key-access-to-github https://gist.github.com/alejandro-martin/aabe88cf15871121e076f66b65306610 using core.sshCommand config option (or GIT_SSH_COMMAND environment variable) it\u0026rsquo;s possible to distinguish ssh keys based on current folder; Commit signing Some platforms may require commit signing. I use gpg key for that. GitHub documentation explains how to set it up. We can also configure git to sign our commits by default:\n[user] signingkey = XXXXXXX [gpg] program = gpg [commit] gpgsign = true ","permalink":"https://andreynautilus.github.io/posts/2024-05-22-git-multiple-users/","summary":"Configure multiple git users on the same workstation","title":"git with multiple users"},{"content":"Why do we need to force-push? Force-pushing is not always a bad thing. Sometimes we actually want to re-write the git history. This can be useful if:\nwe want to update a commit message of a previous commit (git commit --amend); we want to squash-merge dozens of small commits before presenting the code to the review (git rebase autosquash -i). When combined with fixup commits this allows to group changes in well-described commits; we want to remove sensitive information (like leaked credential) from the repository; we rebase our branch (on top of the updated main for example); In all these cases we actually want to re-write the git history, so we need to use force-push.\nA safer force-push But git push --force is a dangerous, unconditional override of the history on remote.\nIn git we usually have a branch per feature. This branch is usually maintained by a single developer from the creation till merge, and usually force-pushing to this branch is a relatively safe operation with low risk of overriding someones work. Still sometimes other authors (developers or automation) may push to your feature branch and we don\u0026rsquo;t want to lose these changes.\nTo completely avoid the risk, we should use git push --force-with-lease instead of git push --force. --force-with-lease will block the operation if the remote branch has changes that are not in your local copy. Official documentation has a bit more detailed explanation, but in simple words:\n--force-with-lease will not allow you to override someones changes that were not pulled to your local copy.\nAs a rule of thumb: always use --force-with-lease unless you have very good reasons to use --force.\nDanger zone If after re-writing your local history, but before pushing the changes to remote, you update your local remote-tracking branches (with git fetch for example), --force-with-lease will not save you from overriding others changes. In this case git assumes that\u0026rsquo;s your intention to override someones changes.\nExample Let\u0026rsquo;s simulate this scenario locally, I\u0026rsquo;ll use fixup commits as example. git can use a local repository as remote (I\u0026rsquo;ll use bare repository for this). We\u0026rsquo;re interested in commits, not the actual changes, so all commits will be empty (done with --allow-empty flag).\nInitial setup First, let\u0026rsquo;s create a remote (a bare git repository):\n$ mkdir remote $ cd remote remote $ git init --bare Mr.Green clones the repository, configures the user, initializes the main branch with an empty commit and pushes it to the remote:\n$ mkdir green $ git clone remote green $ cd green green $ git config --local user.name \u0026#34;Alex Green\u0026#34; green $ git config --local user.email \u0026#34;alex.green@address.com\u0026#34; green $ git commit -m \u0026#34;initial commit\u0026#34; --allow-empty green $ git push origin main Next, his co-worker, Mr.Red clones the repository and configures his user:\n$ mkdir red $ git clone remote red $ cd red red $ git config --local user.name \u0026#34;Bob Red\u0026#34; red $ git config --local user.email \u0026#34;bob.red@address.com\u0026#34; Now we have 2 clones from different people of the same remote.\nCreating a conflict Mr.Red creates a branch, makes a few changes and pushes the branch to the remote:\nred $ git checkout -b feature_branch red $ git commit -m \u0026#34;change from Red 1\u0026#34; --allow-empty red $ git commit --fixup HEAD --allow-empty red $ git push --set-upstream origin feature_branch Mr.Red invites his co-worker - Mr.Green - to help. Mr.Green checks out feature_branch, makes some changes and pushes the branch back to remote:\ngreen $ git pull green $ git checkout feature_branch green $ git commit -m \u0026#34;change from Green 1\u0026#34; --allow-empty green $ git push origin feature_branch In the meanwhile, Mr.Red continues to make changes. When ready, he squashes the changes to produce a \u0026ldquo;clean\u0026rdquo; history for the review process:\nred $ git commit --fixup HEAD~1 --allow-empty red $ git rebase --autosquash --interactive HEAD~3 # accept all changes Boom! Now the git history in Mr.Reds local copy has a conflict with the remote (what Mr.Green pushed):\nred $ git log --oneline feature_branch 266b934 (HEAD -\u0026gt; feature_branch) change from Red 1 71737b9 (origin/main, origin/HEAD, main) initial commit green $ git log --oneline feature_branch fa25da6 (HEAD -\u0026gt; feature_branch, origin/feature_branch) change from Green 1 c905bcf fixup! change from Red 1 863c570 change from Red 1 71737b9 (origin/main, main) initial commit (note the commit hashes!)\nHandling the conflict Mr.Red re-wrote the history of his branch, and if he tries to git push, the operation will fail. Mr.Red knows that he needs to force-push in order to send his branch to the remote.\nMr.Red might not be aware of the changes from Mr.Green, so using git push --force will override the commit from Mr.Green. --force-with-lease prevents it:\nred $ git push origin feature_branch --force-with-lease To C:/Projects/git_push_force_example/remote ! [rejected] feature_branch -\u0026gt; feature_branch (stale info) error: failed to push some refs to \u0026#39;C:/Projects/git_push_force_example/remote\u0026#39; Voila! Mr.Red didn\u0026rsquo;t override someones commit and needs to rebase and re-apply his changes.\nDanger zone If Mr.Red updates his local remote-tracking branches (with git fetch):\nred $ git log --oneline origin/feature_branch c905bcf (origin/feature_branch) fixup! change from Red 1 863c570 change from Red 1 71737b9 (origin/main, origin/HEAD, main) initial commit red $ git fetch red $ git log --oneline origin/feature_branch fa25da6 (origin/feature_branch) change from Green 1 c905bcf fixup! change from Red 1 863c570 change from Red 1 71737b9 (origin/main, origin/HEAD, main) initial commit the push operation will succeed and it will override the commit from Mr.Green on the remote. This happens, because git fetch brings the commit from Mr.Green to the local copy of Mr.Red, and git assumes that Mr.Red actually wants to override the commit from Mr.Green.\nConclusion Always prefer git push --force-with-lease over git push --force and use git fetch consciously.\n","permalink":"https://andreynautilus.github.io/posts/2024-05-16-git-force-vs-force-with-lease/","summary":"Prefer \u0026lsquo;git push \u0026ndash;force-with-lease\u0026rsquo; over \u0026lsquo;git push \u0026ndash;force\u0026rsquo;","title":"git push --force vs --force-with-lease"},{"content":"Tools https://regex101.com/ - online RegEx tester/debugger https://crontab.guru/ - cron explainer https://github.com/refined-github/refined-github - browser extension to greatly enrich GitHub UI https://ohshitgit.com/ - git cheatsheet for \u0026ldquo;shit happened\u0026rdquo; cases Procedural generation https://www.boristhebrave.com/ - blog about procedural generation: diablo 1 dungeon generation, unexplored dungeon generation, etc. Overview of Maze generation algorithms Poisson disk sampling and Bridson’s algorithm - (post) Random point in a circle with uniform distribution - (post) Other \u0026ldquo;My 3 Rules for Documenting Code\u0026rdquo; article (post) Linux process memory: RSS, PSS, USS explained (post) Soma on dev.to - collection of 101 articles about System Design ","permalink":"https://andreynautilus.github.io/links/","summary":"Tools https://regex101.com/ - online RegEx tester/debugger https://crontab.guru/ - cron explainer https://github.com/refined-github/refined-github - browser extension to greatly enrich GitHub UI https://ohshitgit.com/ - git cheatsheet for \u0026ldquo;shit happened\u0026rdquo; cases Procedural generation https://www.boristhebrave.com/ - blog about procedural generation: diablo 1 dungeon generation, unexplored dungeon generation, etc. Overview of Maze generation algorithms Poisson disk sampling and Bridson’s algorithm - (post) Random point in a circle with uniform distribution - (post) Other \u0026ldquo;My 3 Rules for Documenting Code\u0026rdquo; article (post) Linux process memory: RSS, PSS, USS explained (post) Soma on dev.","title":"Collection of useful links"}] \ No newline at end of file diff --git a/docs/posts/2024-07-21-evenly-random-points-on-plane/index.html b/docs/posts/2024-07-21-evenly-random-points-on-plane/index.html index fe7e5d8..1f0d44e 100644 --- a/docs/posts/2024-07-21-evenly-random-points-on-plane/index.html +++ b/docs/posts/2024-07-21-evenly-random-points-on-plane/index.html @@ -3,19 +3,19 @@ Possible use-cases:

The simplest approach - to use uniformly distributed points with (random(), random()) - doesn’t work, because there will be areas with high density of points and areas with no points at all. -Such distribution doesn’t look natural.

Caption

Various types of grids with gaps can give even distribution, but the picture will not look random. There will always be a pattern, sometimes more visible, sometimes less, but still visible. This doesn’t look natural either.

A solution to this problem is Poisson disk sampling (or Poisson disk distribution): -points are placed randomly, but not too close and not too far away from each other.

Caption

Random point in circle with uniform distribution

We need to generate a random point in a circle with uniform distribution.

A naive approach with picking a random angle and a random distance doesn’t have uniform distribution - -there are more points close to center and fewer points at the radius. -This article -has explanation and visualization.

Correct formula for polar coordinates

In polar coordinates:

angle = random(0, 2 * PI)
-distance = R * sqrt(random(0, 1))
-

Where R is the radius of the circle. And transformation to Cortesian coordinates:

x = distance * cos(angle)
-y = distance * sin(angle)
-

This article -and StackOverflow threads -give a mathematically correct explanation.

Multiple attempts

Another approach is to generate uniformly distributed random points in the bounding box of the circle -and pick the first point that is inside the circle.

With random() being a uniformly random number, the naive approach for a point in a square:

x = random()
-y = random()
-

give uniformly distributed points. And x * x + y * y <= R * R provides an easy test for -point being inside the circle.

Obvious drawback - undefined number of attempts, but with uniformly distributed points in a box the average -amount of attempt should not be greater than 2.

- \ No newline at end of file +https://andreynautilus.github.io/posts/2024-07-29-random-points-in-circle/ + \ No newline at end of file diff --git a/docs/posts/2024-07-29-random-points-in-circle/index.html b/docs/posts/2024-07-29-random-points-in-circle/index.html new file mode 100644 index 0000000..28f86d1 --- /dev/null +++ b/docs/posts/2024-07-29-random-points-in-circle/index.html @@ -0,0 +1,111 @@ +Random points in circle with uniform distribution | Andrey Nautilus blog +

Random points in circle with uniform distribution

We need to generate a random point in a circle with uniform distribution.

A naive approach with picking a random angle and a random distance doesn’t have uniform distribution - +there are more points close to center and fewer points at the radius. +This article +has explanation and visualization.

NNN points, left to right: naive approach, correct formula, Monte Carlo (XXX attempts)

Correct formula for polar coordinates

In polar coordinates:

angle = random(0, 2 * PI)
+distance = R * sqrt(random(0, 1))
+

Where R is the radius of the circle. And transformation to Cortesian coordinates:

x = distance * cos(angle)
+y = distance * sin(angle)
+

This article +and StackOverflow threads +give a mathematically correct explanation.

Monte Carlo (multiple attempts)

Another approach is to generate uniformly distributed random points in the bounding box of the circle +and pick the first point that is inside the circle.

With random() being a uniformly random number, the naive approach for a point in a square:

x = random()
+y = random()
+

give uniformly distributed points. And x * x + y * y <= R * R provides an easy test for +point being inside the circle.

Obvious drawback - undefined number of attempts, but with uniformly distributed points in a box the average +amount of attempt should not be greater than 2 (on average we need 4 / PI attempts).

+ \ No newline at end of file diff --git a/docs/posts/index.html b/docs/posts/index.html index 389f2f3..91eed20 100644 --- a/docs/posts/index.html +++ b/docs/posts/index.html @@ -1,6 +1,6 @@ posts | Andrey Nautilus blog

Random point in circle with uniform distribution

angle = random(); distance = R * sqrt(random())

July 29, 2024 · 1 min

Evenly distributed random points

Bridson’s Algorithm to build Poisson disk distribution of points

July 21, 2024 · 3 min

Linux process memory: RSS, VSZ, etc

RSS, VSZ, PSS, USS explained

July 16, 2024 · 1 min

Documenting code

names = what, code = how, comments = why

May 26, 2024 · 1 min

git with multiple users

Configure multiple git users on the same workstation

May 22, 2024 · 3 min

git push --force vs --force-with-lease

Prefer ‘git push –force-with-lease’ over ‘git push –force’

May 16, 2024 · 5 min