mirror of
https://github.com/dwmkerr/hacker-laws.git
synced 2025-12-17 20:55:02 +01:00
Compare commits
40 Commits
build/page
...
v0.2.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cd48102cb | ||
|
|
46148724e2 | ||
|
|
2140429b95 | ||
|
|
32d95692c6 | ||
|
|
a337004e69 | ||
|
|
a6ae7d8189 | ||
|
|
59465379dd | ||
|
|
f5cf372f03 | ||
|
|
c1c7f013e7 | ||
|
|
5690da764c | ||
|
|
d6a7d4eac3 | ||
|
|
8e99eb1643 | ||
|
|
c535f12797 | ||
|
|
0ed571cae0 | ||
|
|
d83d439df8 | ||
|
|
6f9b1e3334 | ||
|
|
a35ebb9c2e | ||
|
|
bbb716064f | ||
|
|
39506a03e6 | ||
|
|
0de2035d52 | ||
|
|
3075d4c9b6 | ||
|
|
3f730a8538 | ||
|
|
4d795efb0c | ||
|
|
b8cac9c4af | ||
|
|
558f24ad63 | ||
|
|
63adb0a350 | ||
|
|
dd36c58ef4 | ||
|
|
711327b632 | ||
|
|
0a56479bd9 | ||
|
|
692b7cca1a | ||
|
|
0d001f14e1 | ||
|
|
67c135701f | ||
|
|
8bac32a000 | ||
|
|
8142ce0a9f | ||
|
|
5e1cfb7608 | ||
|
|
f810c81da2 | ||
|
|
280ad8d45c | ||
|
|
a97981e735 | ||
|
|
2ce26c0576 | ||
|
|
5f74607c63 |
34
.github/CHANGELOG.md
vendored
Normal file
34
.github/CHANGELOG.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [0.2.1](https://github.com/dwmkerr/hacker-laws/compare/v0.2.0...v0.2.1) (2025-03-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* remove frontmatter ([2140429](https://github.com/dwmkerr/hacker-laws/commit/2140429b959a8284b452c3fa05e1c9fd03e5ebab))
|
||||||
|
|
||||||
|
## [0.2.0](https://github.com/dwmkerr/hacker-laws/compare/v0.1.0...v0.2.0) (2025-03-31)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* 90-90 rule ([4477907](https://github.com/dwmkerr/hacker-laws/commit/44779074caa6495198214100e5bd0a886cc1e680))
|
||||||
|
* add section for Kerckhoff's principle ([5f74607](https://github.com/dwmkerr/hacker-laws/commit/5f74607c63d3a76009ec0546ba515f8f7c1d3864))
|
||||||
|
* add ukranian language to README ([#320](https://github.com/dwmkerr/hacker-laws/issues/320)) ([015d251](https://github.com/dwmkerr/hacker-laws/commit/015d25197f808d66c4dfebcdd0b54675af6a3eae)), closes [#236](https://github.com/dwmkerr/hacker-laws/issues/236)
|
||||||
|
* Dunning Kruger Effect ([3dbc237](https://github.com/dwmkerr/hacker-laws/commit/3dbc237c1f1c59e809969320cc0ae4347a4b45c3))
|
||||||
|
* Dunning-Kruger Effect ([#318](https://github.com/dwmkerr/hacker-laws/issues/318)) ([34c38d8](https://github.com/dwmkerr/hacker-laws/commit/34c38d87edba4b0e36d2ad9488b97d0c77f9b550))
|
||||||
|
* **pages:** update index.html and pages.yaml for deployment ([beb3d57](https://github.com/dwmkerr/hacker-laws/commit/beb3d57a6a5a3a38aa9e692ed13eb01060b85ded))
|
||||||
|
* principle of least astonishment ([4be4827](https://github.com/dwmkerr/hacker-laws/commit/4be482731b6a6009453af7d303d3cd2470a2e73e))
|
||||||
|
* principle of least astonishment ([e4662cb](https://github.com/dwmkerr/hacker-laws/commit/e4662cbc27d04fb968220837633034420b7fb11a))
|
||||||
|
* the scout rule ([716aef8](https://github.com/dwmkerr/hacker-laws/commit/716aef807e758bd8df976f323089db525da9f708))
|
||||||
|
* the scout rule ([c6fccf4](https://github.com/dwmkerr/hacker-laws/commit/c6fccf4978d9483637fba8c7887127abad3de581)), closes [#144](https://github.com/dwmkerr/hacker-laws/issues/144)
|
||||||
|
* twyman's law ([b9ad4c6](https://github.com/dwmkerr/hacker-laws/commit/b9ad4c6f99f991a1bda9a2cfdddef62787e6ae82))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* correct facebook link on website ([6f9b1e3](https://github.com/dwmkerr/hacker-laws/commit/6f9b1e33345bc1332428f0fba8c7aa2900147500))
|
||||||
|
* correct formatting around quote ([d83d439](https://github.com/dwmkerr/hacker-laws/commit/d83d439df89e8af50ae53bafa3a791f8d92a6991))
|
||||||
|
* Fix section's links ([#317](https://github.com/dwmkerr/hacker-laws/issues/317)) ([7b341fc](https://github.com/dwmkerr/hacker-laws/commit/7b341fc0d205f076e25ff8fedb972e652201c3c6))
|
||||||
|
* image paths ([692b7cc](https://github.com/dwmkerr/hacker-laws/commit/692b7cca1a97eb62384db170297b504f51ea408e))
|
||||||
|
* remove superfluous 'is' ([3b78ae6](https://github.com/dwmkerr/hacker-laws/commit/3b78ae65f02fca457bb8adbf113135e1ed042a46))
|
||||||
28
.github/contributing.md
vendored
28
.github/contributing.md
vendored
@@ -2,12 +2,13 @@
|
|||||||
|
|
||||||
<!-- vim-markdown-toc GFM -->
|
<!-- vim-markdown-toc GFM -->
|
||||||
|
|
||||||
* [Goal of the Project](#goal-of-the-project)
|
- [Goal of the Project](#goal-of-the-project)
|
||||||
* [Example Law: The Law of Leaky Abstractions](#example-law-the-law-of-leaky-abstractions)
|
- [Example Law: The Law of Leaky Abstractions](#example-law-the-law-of-leaky-abstractions)
|
||||||
* [Translations](#translations)
|
- [Translations](#translations)
|
||||||
* [How do I know if a law is relevant?](#how-do-i-know-if-a-law-is-relevant)
|
- [How do I know if a law is relevant?](#how-do-i-know-if-a-law-is-relevant)
|
||||||
* [How do I know if a law is 'well known' enough?](#how-do-i-know-if-a-law-is-well-known-enough)
|
- [How do I know if a law is 'well known' enough?](#how-do-i-know-if-a-law-is-well-known-enough)
|
||||||
* [Use of Images](#use-of-images)
|
- [Use of Images](#use-of-images)
|
||||||
|
- [Developer Guide](#developer-guide)
|
||||||
|
|
||||||
<!-- vim-markdown-toc -->
|
<!-- vim-markdown-toc -->
|
||||||
|
|
||||||
@@ -87,3 +88,18 @@ A good test is 'If I search for it on Google, will I find it in the first few re
|
|||||||
## Use of Images
|
## Use of Images
|
||||||
|
|
||||||
Please make sure to attribute images properly if you are referencing them. Also, include a white background, as some viewers will be viewing the site in 'Dark Mode' which can make images with a transparent background difficult to read.
|
Please make sure to attribute images properly if you are referencing them. Also, include a white background, as some viewers will be viewing the site in 'Dark Mode' which can make images with a transparent background difficult to read.
|
||||||
|
|
||||||
|
## Developer Guide
|
||||||
|
|
||||||
|
Where possible, anything which is not the core `README.md` file is kept in the `.github/` folder to keep the landing page for the repository as clean as possible.
|
||||||
|
|
||||||
|
To use the makefile, pass its path explicitly, e.g:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make -f .github/makefile
|
||||||
|
```
|
||||||
|
|
||||||
|
Or create an alias:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
alias hlmake="make -f .github/makefile"
|
||||||
|
|||||||
22
.github/makefile
vendored
Normal file
22
.github/makefile
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
default: help
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: # Show help for each of the Makefile recipes.
|
||||||
|
@grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | sort | while read -r l; do printf "\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done
|
||||||
|
|
||||||
|
.PHONY: prepare-markdown
|
||||||
|
prepare-markdown: # Prepare the markdown for PDF output.
|
||||||
|
./scripts/prepare-markdown-for-ebook.sh "README.md" "hacker-laws.md"
|
||||||
|
|
||||||
|
.PHONY: create-pdf
|
||||||
|
create-pdf: # Create the PDF.
|
||||||
|
docker run --rm \
|
||||||
|
--platform linux/amd64 \
|
||||||
|
-v ${PWD}:/data \
|
||||||
|
pandoc/latex:3.6 \
|
||||||
|
-V toc-title:"Table Of Contents" \
|
||||||
|
--toc \
|
||||||
|
--pdf-engine=lualatex \
|
||||||
|
--standalone \
|
||||||
|
--output hacker-laws.pdf \
|
||||||
|
hacker-laws.md
|
||||||
28
.github/pages/index.html
vendored
28
.github/pages/index.html
vendored
@@ -1,28 +0,0 @@
|
|||||||
<!doctype html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
|
|
||||||
<!-- Bootstrap CSS -->
|
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
|
|
||||||
|
|
||||||
<title>Hacker Laws</title>
|
|
||||||
|
|
||||||
<!-- Google tag (gtag.js) -->
|
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RGJ5TDHWY9"></script>
|
|
||||||
<script>
|
|
||||||
window.dataLayer = window.dataLayer || [];
|
|
||||||
function gtag(){dataLayer.push(arguments);}
|
|
||||||
gtag('js', new Date());
|
|
||||||
|
|
||||||
gtag('config', 'G-RGJ5TDHWY9');
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Hacker Laws</h1>
|
|
||||||
|
|
||||||
<!-- Bootstrap JS -->
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
18
.github/release-please-config.json
vendored
Normal file
18
.github/release-please-config.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"release-type": "simple",
|
||||||
|
"bump-minor-pre-major": true,
|
||||||
|
"packages": {
|
||||||
|
".": {
|
||||||
|
"release-type": "simple",
|
||||||
|
"extra-files": [
|
||||||
|
{
|
||||||
|
"type": "generic",
|
||||||
|
"path": "README.md"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"changelog-path": ".github/CHANGELOG.md"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
3
.github/release-please-manifest.json
vendored
Normal file
3
.github/release-please-manifest.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
".": "0.2.1"
|
||||||
|
}
|
||||||
0
.github/website/backup/ideas.md
vendored
Normal file
0
.github/website/backup/ideas.md
vendored
Normal file
189
.github/website/backup/index2.html
vendored
Normal file
189
.github/website/backup/index2.html
vendored
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Hacker Laws</title>
|
||||||
|
<!-- Bootstrap CSS -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
<!-- Bootstrap Icons -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet" />
|
||||||
|
<style>
|
||||||
|
/* Soft pastel parchment background */
|
||||||
|
body {
|
||||||
|
background-color: #fdf6e3;
|
||||||
|
color: #333;
|
||||||
|
padding-top: 70px; /* to account for sticky navbar */
|
||||||
|
}
|
||||||
|
/* Navbar customization */
|
||||||
|
.navbar-custom {
|
||||||
|
background-color: #ffffff;
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
/* Header styling */
|
||||||
|
header h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
header p.lead {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
/* Law section container */
|
||||||
|
.law-section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
/* Social sharing icons */
|
||||||
|
.social-sharing a {
|
||||||
|
margin-right: 0.75rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #555;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.social-sharing a:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
/* Back to top link styling */
|
||||||
|
.back-to-top a {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
.back-to-top a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body id="top">
|
||||||
|
<!-- Sticky Navbar -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-custom fixed-top">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand fw-bold" href="#top">Hacker Laws</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu" aria-controls="navMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navMenu">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#"><i class="bi bi-book"></i> Effective Shell</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#"><i class="bi bi-cup"></i> Sponsor</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#"><i class="bi bi-brain"></i> Terminal AI</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="navbar-nav ms-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#"><i class="bi bi-github"></i> GitHub</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Page Header -->
|
||||||
|
<header class="container my-4">
|
||||||
|
<h1>Hacker Laws</h1>
|
||||||
|
<p class="lead">Laws, Theories, Principles and Patterns that developers will find useful.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<main class="container">
|
||||||
|
<!-- Introduction Section -->
|
||||||
|
<section id="introduction" class="law-section">
|
||||||
|
<h2>Introduction</h2>
|
||||||
|
<p>There are lots of laws which people discuss when talking about development. This repository is a reference and overview of some of the most common ones. Please share and submit PRs!</p>
|
||||||
|
<p><strong>Note:</strong> This repo contains an explanation of some laws, principles and patterns, but does not <em>advocate</em> for any of them. Whether they should be applied will always be a matter of debate, and greatly dependent on what you are working on.</p>
|
||||||
|
|
||||||
|
<!-- Social Sharing Icons -->
|
||||||
|
<div class="social-sharing">
|
||||||
|
<a href="#" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||||
|
<a href="#" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||||
|
<a href="#" title="Share on LinkedIn"><i class="bi bi-linkedin"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Back to Top Options (choose one) -->
|
||||||
|
<div class="back-to-top mt-2">
|
||||||
|
<a href="#top">↑ Top</a>
|
||||||
|
<!-- Alternative options:
|
||||||
|
<a href="#top">Back to Top</a>
|
||||||
|
<a href="#top">Return to Top</a>
|
||||||
|
<a href="#top">Go Up</a>
|
||||||
|
<a href="#top">Scroll Up</a>
|
||||||
|
-->
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 90–9–1 Principle (1% Rule) Section -->
|
||||||
|
<section id="9091-principle" class="law-section">
|
||||||
|
<h2>90–9–1 Principle (1% Rule)</h2>
|
||||||
|
<p>The 90-9-1 principle suggests that within an internet community such as a wiki, 90% of participants only consume content, 9% edit or modify content and 1% of participants add content.</p>
|
||||||
|
<p>Real-world examples:</p>
|
||||||
|
<ul>
|
||||||
|
<li>A 2014 study of four digital health social networks found the top 1% created 73% of posts, the next 9% accounted for an average of ~25% and the remaining 90% accounted for an average of 2%.</li>
|
||||||
|
</ul>
|
||||||
|
<p>See Also: <a href="#the-pareto-principle-the-8020-rule">Pareto Principle</a></p>
|
||||||
|
|
||||||
|
<!-- Social Sharing Icons -->
|
||||||
|
<div class="social-sharing">
|
||||||
|
<a href="#" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||||
|
<a href="#" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||||
|
<a href="#" title="Share on LinkedIn"><i class="bi bi-linkedin"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Back to Top Options -->
|
||||||
|
<div class="back-to-top mt-2">
|
||||||
|
<a href="#top">↑ Top</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 90–90 Rule Section -->
|
||||||
|
<section id="9090-rule" class="law-section">
|
||||||
|
<h2>90–90 Rule</h2>
|
||||||
|
<p>The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.</p>
|
||||||
|
<p>This is a wry reinterpretation of the <a href="#the-pareto-principle-the-8020-rule">Pareto Principle</a> (or 80-20 rule) that highlights the real-world challenges of completing engineering work. This sentiment is also echoed in <a href="#hofstadters-law">Hofstadter's Law</a>.</p>
|
||||||
|
|
||||||
|
<!-- Social Sharing Icons -->
|
||||||
|
<div class="social-sharing">
|
||||||
|
<a href="#" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||||
|
<a href="#" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||||
|
<a href="#" title="Share on LinkedIn"><i class="bi bi-linkedin"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Back to Top Options -->
|
||||||
|
<div class="back-to-top mt-2">
|
||||||
|
<a href="#top">↑ Top</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- Additional law sections would follow the same structure -->
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="container text-center my-4">
|
||||||
|
<p>© 2025 Hacker Laws</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Bootstrap Bundle with Popper -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
// Optional: Smooth scrolling for in-page links
|
||||||
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||||
|
anchor.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const targetElem = document.querySelector(this.getAttribute('href'));
|
||||||
|
if (targetElem) {
|
||||||
|
targetElem.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
194
.github/website/backup/index3.html
vendored
Normal file
194
.github/website/backup/index3.html
vendored
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Hacker Laws</title>
|
||||||
|
<!-- Google Font for elegant serif fonts -->
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:wght@400;700&display=swap" rel="stylesheet">
|
||||||
|
<!-- Bootstrap CSS -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
<!-- Bootstrap Icons -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet" />
|
||||||
|
<style>
|
||||||
|
/* Use an elegant serif font and a clean, minimal palette */
|
||||||
|
body {
|
||||||
|
font-family: 'Libre Baskerville', Georgia, serif;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #333;
|
||||||
|
padding-top: 70px; /* account for sticky navbar */
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
/* Simplified Navbar */
|
||||||
|
.navbar-custom {
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
.navbar-brand,
|
||||||
|
.nav-link {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
/* Centered, minimal header */
|
||||||
|
header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
header h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
header p.lead {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
/* Law section styling: simple borders instead of shadows */
|
||||||
|
.law-section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
/* Social sharing icons remain the same */
|
||||||
|
.social-sharing a {
|
||||||
|
margin-right: 0.75rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #555;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.social-sharing a:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
/* Back to top link styling */
|
||||||
|
.back-to-top a {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #007bff;
|
||||||
|
}
|
||||||
|
.back-to-top a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body id="top">
|
||||||
|
<!-- Sticky Navbar -->
|
||||||
|
<nav class="navbar navbar-expand-lg navbar-custom fixed-top">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="#top">Hacker Laws</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu" aria-controls="navMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navMenu">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#"><i class="bi bi-book"></i> Effective Shell</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#"><i class="bi bi-cup"></i> Sponsor</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#"><i class="bi bi-brain"></i> Terminal AI</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="navbar-nav ms-auto">
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#"><i class="bi bi-github"></i> GitHub</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- Page Header -->
|
||||||
|
<header class="container my-4">
|
||||||
|
<h1>Hacker Laws</h1>
|
||||||
|
<p class="lead">Laws, Theories, Principles and Patterns that developers will find useful.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- Main Content -->
|
||||||
|
<main class="container">
|
||||||
|
<!-- Introduction Section -->
|
||||||
|
<section id="introduction" class="law-section">
|
||||||
|
<h2>Introduction</h2>
|
||||||
|
<p>There are lots of laws which people discuss when talking about development. This repository is a reference and overview of some of the most common ones. Please share and submit PRs!</p>
|
||||||
|
<p><strong>Note:</strong> This repo contains an explanation of some laws, principles and patterns, but does not <em>advocate</em> for any of them. Whether they should be applied will always be a matter of debate, and greatly dependent on what you are working on.</p>
|
||||||
|
|
||||||
|
<!-- Social Sharing Icons -->
|
||||||
|
<div class="social-sharing">
|
||||||
|
<a href="#" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||||
|
<a href="#" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||||
|
<a href="#" title="Share on LinkedIn"><i class="bi bi-linkedin"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Back to Top -->
|
||||||
|
<div class="back-to-top mt-2">
|
||||||
|
<a href="#top">↑ Top</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 90–9–1 Principle (1% Rule) Section -->
|
||||||
|
<section id="9091-principle" class="law-section">
|
||||||
|
<h2>90–9–1 Principle (1% Rule)</h2>
|
||||||
|
<p>The 90-9-1 principle suggests that within an internet community such as a wiki, 90% of participants only consume content, 9% edit or modify content and 1% of participants add content.</p>
|
||||||
|
<p>Real-world examples:</p>
|
||||||
|
<ul>
|
||||||
|
<li>A 2014 study of four digital health social networks found the top 1% created 73% of posts, the next 9% accounted for an average of ~25% and the remaining 90% accounted for an average of 2%.</li>
|
||||||
|
</ul>
|
||||||
|
<p>See Also: <a href="#the-pareto-principle-the-8020-rule">Pareto Principle</a></p>
|
||||||
|
|
||||||
|
<!-- Social Sharing Icons -->
|
||||||
|
<div class="social-sharing">
|
||||||
|
<a href="#" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||||
|
<a href="#" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||||
|
<a href="#" title="Share on LinkedIn"><i class="bi bi-linkedin"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Back to Top -->
|
||||||
|
<div class="back-to-top mt-2">
|
||||||
|
<a href="#top">↑ Top</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 90–90 Rule Section -->
|
||||||
|
<section id="9090-rule" class="law-section">
|
||||||
|
<h2>90–90 Rule</h2>
|
||||||
|
<p>The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.</p>
|
||||||
|
<p>This is a wry reinterpretation of the <a href="#the-pareto-principle-the-8020-rule">Pareto Principle</a> (or 80-20 rule) that highlights the real-world challenges of completing engineering work. This sentiment is also echoed in <a href="#hofstadters-law">Hofstadter's Law</a>.</p>
|
||||||
|
|
||||||
|
<!-- Social Sharing Icons -->
|
||||||
|
<div class="social-sharing">
|
||||||
|
<a href="#" title="Share on Twitter"><i class="bi bi-twitter"></i></a>
|
||||||
|
<a href="#" title="Share on Facebook"><i class="bi bi-facebook"></i></a>
|
||||||
|
<a href="#" title="Share on LinkedIn"><i class="bi bi-linkedin"></i></a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Back to Top -->
|
||||||
|
<div class="back-to-top mt-2">
|
||||||
|
<a href="#top">↑ Top</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer class="container text-center my-4">
|
||||||
|
<p>© 2025 Hacker Laws</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Bootstrap Bundle with Popper -->
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script>
|
||||||
|
// Smooth scrolling for in-page links
|
||||||
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||||
|
anchor.addEventListener('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
const targetElem = document.querySelector(this.getAttribute('href'));
|
||||||
|
if (targetElem) {
|
||||||
|
targetElem.scrollIntoView({ behavior: 'smooth' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
0
.github/website/backup/index4.html
vendored
Normal file
0
.github/website/backup/index4.html
vendored
Normal file
1
.github/website/build/.gitignore
vendored
Normal file
1
.github/website/build/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
*
|
||||||
161
.github/website/generate.py
vendored
Normal file
161
.github/website/generate.py
vendored
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
"""Generate the Hacker Laws website from the Hacker Laws README"""
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
import markdown
|
||||||
|
from bs4 import BeautifulSoup
|
||||||
|
|
||||||
|
|
||||||
|
def bisect_text(content: str, bisect_line: str) -> tuple[str, str]:
|
||||||
|
lines = content.splitlines()
|
||||||
|
head = []
|
||||||
|
tail = []
|
||||||
|
found = False
|
||||||
|
for line in lines:
|
||||||
|
if found is False and line == bisect_line:
|
||||||
|
found = True
|
||||||
|
continue
|
||||||
|
if found:
|
||||||
|
tail.append(line)
|
||||||
|
else:
|
||||||
|
head.append(line)
|
||||||
|
|
||||||
|
return ("\n".join(head), "\n".join(tail))
|
||||||
|
|
||||||
|
|
||||||
|
def load_template():
|
||||||
|
"""Load Jinja2 template from the specified directory."""
|
||||||
|
env = Environment(loader=FileSystemLoader(TEMPLATE_DIR))
|
||||||
|
return env.get_template(TEMPLATE_FILE)
|
||||||
|
|
||||||
|
|
||||||
|
def prepare_markdown(path: str) -> str:
|
||||||
|
"""
|
||||||
|
Pre-process the README markdown by removing content we will not show in
|
||||||
|
the final website.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Load the markdown content.
|
||||||
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
|
content = f.read()
|
||||||
|
return content
|
||||||
|
|
||||||
|
|
||||||
|
def parse_markdown(markdown_content: str):
|
||||||
|
(_, remains) = bisect_text(markdown_content, "---")
|
||||||
|
(links, remains) = bisect_text(remains, "---")
|
||||||
|
(_, content) = bisect_text(remains, "<!-- vim-markdown-toc -->")
|
||||||
|
|
||||||
|
md = markdown.Markdown(extensions=['toc'])
|
||||||
|
links = md.convert(links)
|
||||||
|
print(f"links: {links}")
|
||||||
|
md.convert(content)
|
||||||
|
toc = md.toc
|
||||||
|
|
||||||
|
markdown_sections = content.split("\n#") # Split by Markdown headings
|
||||||
|
sections = []
|
||||||
|
laws = []
|
||||||
|
for markdown_section in markdown_sections:
|
||||||
|
if markdown_section.strip():
|
||||||
|
lines = markdown_section.split("\n", 1)
|
||||||
|
title = lines[0].strip("# ").strip()
|
||||||
|
content = md.convert(lines[1] if len(lines) > 1 else "")
|
||||||
|
full_content = md.convert(markdown_section)
|
||||||
|
id = title.lower().replace(" ", "-")
|
||||||
|
laws.append({"title": title, "content": content, "id": id})
|
||||||
|
sections.append({
|
||||||
|
"title": title,
|
||||||
|
"content": content,
|
||||||
|
"id": id,
|
||||||
|
"full_content": full_content
|
||||||
|
})
|
||||||
|
|
||||||
|
return (links, toc, sections)
|
||||||
|
|
||||||
|
|
||||||
|
def extract_static_files(html_content, output_dir):
|
||||||
|
"""
|
||||||
|
Extract linked CSS, JS, and image files and copy them to the output
|
||||||
|
directory.
|
||||||
|
"""
|
||||||
|
soup = BeautifulSoup(html_content, "html.parser")
|
||||||
|
files_to_copy = []
|
||||||
|
|
||||||
|
# Extract <link> stylesheets
|
||||||
|
for link in soup.find_all("link", href=True):
|
||||||
|
href = link["href"]
|
||||||
|
if not href.startswith(("http", "//")): # Ignore external links
|
||||||
|
files_to_copy.append(href)
|
||||||
|
|
||||||
|
# Extract <script> files
|
||||||
|
for script in soup.find_all("script", src=True):
|
||||||
|
src = script["src"]
|
||||||
|
if not src.startswith(("http", "//")):
|
||||||
|
files_to_copy.append(src)
|
||||||
|
|
||||||
|
# Extract <img> files
|
||||||
|
for img in soup.find_all("img", src=True):
|
||||||
|
src = img["src"]
|
||||||
|
if not src.startswith(("http", "//")):
|
||||||
|
files_to_copy.append(src)
|
||||||
|
|
||||||
|
# Copy files to the output directory
|
||||||
|
for file_path in files_to_copy:
|
||||||
|
src_path = os.path.join(TEMPLATE_DIR, file_path)
|
||||||
|
dest_path = os.path.join(output_dir, file_path)
|
||||||
|
|
||||||
|
if os.path.exists(src_path): # Ensure file exists before copying
|
||||||
|
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
|
||||||
|
shutil.copy2(src_path, dest_path)
|
||||||
|
print(f"📂 Copied: {src_path} → {dest_path}")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Warning: Missing file {src_path} (skipping)")
|
||||||
|
|
||||||
|
return files_to_copy
|
||||||
|
|
||||||
|
|
||||||
|
def generate_site(markdown_content: str, output_dir: str):
|
||||||
|
"""Generate the static HTML file from Markdown and Jinja2 template."""
|
||||||
|
|
||||||
|
template = load_template()
|
||||||
|
(links, toc, sections) = parse_markdown(markdown_content)
|
||||||
|
|
||||||
|
# Ensure output directory exists
|
||||||
|
os.makedirs(output_dir, exist_ok=True)
|
||||||
|
|
||||||
|
# Render HTML
|
||||||
|
html_output = template.render(links=links, toc=toc, sections=sections)
|
||||||
|
|
||||||
|
# Save HTML to output directory
|
||||||
|
output_file = os.path.join(output_dir, "index.html")
|
||||||
|
with open(output_file, "w", encoding="utf-8") as f:
|
||||||
|
f.write(html_output)
|
||||||
|
|
||||||
|
print(f"✅ Static site generated: {output_file}")
|
||||||
|
|
||||||
|
# Copy static files (CSS, JS, images)
|
||||||
|
extract_static_files(html_output, output_dir)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="Generate a static site from Markdown.")
|
||||||
|
parser.add_argument("-o", "--output-dir", default="build", help="Directory to save the generated site.")
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
# Read environment variables with defaults
|
||||||
|
TEMPLATE_FILE = os.getenv("TEMPLATE_FILE", "template.html")
|
||||||
|
TEMPLATE_DIR = os.getenv("TEMPLATE_DIR", ".")
|
||||||
|
template_path = f"{TEMPLATE_DIR}/{TEMPLATE_FILE}"
|
||||||
|
markdown_path = os.getenv("MARKDOWN_FILE", "laws.md")
|
||||||
|
output_dir = args.output_dir
|
||||||
|
print(f"📝 Loading template from: {template_path}")
|
||||||
|
print(f"📖 Loading markdown from: {markdown_path}")
|
||||||
|
print(f"💾 Outputting files to: {output_dir}")
|
||||||
|
|
||||||
|
# First, extract that markdown that we want to process.
|
||||||
|
markdown_content = prepare_markdown(markdown_path)
|
||||||
|
|
||||||
|
# Generate the site from the markdown.
|
||||||
|
generate_site(markdown_content, args.output_dir)
|
||||||
38
.github/website/makefile
vendored
Normal file
38
.github/website/makefile
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
SHELL := /bin/bash
|
||||||
|
TEMPLATE_DIR=src
|
||||||
|
TEMPLATE_FILE=index.html.jinja
|
||||||
|
MARKDOWN_FILE=../../README.md
|
||||||
|
OUTPUT_FILE=build/index.html
|
||||||
|
|
||||||
|
default: help
|
||||||
|
|
||||||
|
.PHONY: help
|
||||||
|
help: # Show help for each of the Makefile recipes.
|
||||||
|
@grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | sort | while read -r l; do printf "\033[1;32m$$(echo $$l | cut -f 1 -d':')\033[00m:$$(echo $$l | cut -f 2- -d'#')\n"; done
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
install: # 📦 install dependencies
|
||||||
|
@echo "📦 Installing dependencies..."
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build: #🔨 building static site
|
||||||
|
@echo "🔨 Building static site..."
|
||||||
|
cp -rf ../../images ./build
|
||||||
|
TEMPLATE_FILE=$(TEMPLATE_FILE) MARKDOWN_FILE=$(MARKDOWN_FILE) OUTPUT_FILE=$(OUTPUT_FILE) TEMPLATE_DIR=$(TEMPLATE_DIR) \
|
||||||
|
python generate.py
|
||||||
|
|
||||||
|
.PHONY: serve
|
||||||
|
serve: # 🚀 start local server
|
||||||
|
@echo "🚀 Starting local server at http://localhost:8000..."
|
||||||
|
python3 -m http.server 8000
|
||||||
|
|
||||||
|
.PHONY: watch
|
||||||
|
watch: build # 👀 Watch for changes...
|
||||||
|
@echo "👀 Watching for changes..."
|
||||||
|
watchmedo shell-command --patterns="$(MARKDOWN_FILE);*.py;src/*" --command="make build" .
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean: #🧹 Clean up generated files
|
||||||
|
@echo "🧹 Cleaning up generated files..."
|
||||||
|
rm -f $(OUTPUT)
|
||||||
4
.github/website/requirements.txt
vendored
Normal file
4
.github/website/requirements.txt
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
markdown
|
||||||
|
jinja2
|
||||||
|
watchdog
|
||||||
|
beautifulsoup4
|
||||||
3
.github/website/src/favicon.svg
vendored
Normal file
3
.github/website/src/favicon.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M16 0C7.16 0 0 7.16 0 16C0 23.08 4.58 29.06 10.94 31.18C11.74 31.32 12.04 30.84 12.04 30.42C12.04 30.04 12.02 28.78 12.02 27.44C8 28.18 6.96 26.46 6.64 25.56C6.46 25.1 5.68 23.68 5 23.3C4.44 23 3.64 22.26 4.98 22.24C6.24 22.22 7.14 23.4 7.44 23.88C8.88 26.3 11.18 25.62 12.1 25.2C12.24 24.16 12.66 23.46 13.12 23.06C9.56 22.66 5.84 21.28 5.84 15.16C5.84 13.42 6.46 11.98 7.48 10.86C7.32 10.46 6.76 8.82 7.64 6.62C7.64 6.62 8.98 6.2 12.04 8.26C13.32 7.9 14.68 7.72 16.04 7.72C17.4 7.72 18.76 7.9 20.04 8.26C23.1 6.18 24.44 6.62 24.44 6.62C25.32 8.82 24.76 10.46 24.6 10.86C25.62 11.98 26.24 13.4 26.24 15.16C26.24 21.3 22.5 22.66 18.94 23.06C19.52 23.56 20.02 24.52 20.02 26.02C20.02 28.16 20 29.88 20 30.42C20 30.84 20.3 31.34 21.1 31.18C27.42 29.06 32 23.06 32 16C32 7.16 24.84 0 16 0V0Z" fill="#24292E"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 959 B |
76
.github/website/src/index.html.jinja
vendored
Normal file
76
.github/website/src/index.html.jinja
vendored
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>Hacker Laws</title>
|
||||||
|
<!-- Google tag (gtag.js) -->
|
||||||
|
<script async src="https://www.googletagmanager.com/gtag/js?id=G-RGJ5TDHWY9"></script>
|
||||||
|
<script>
|
||||||
|
window.dataLayer = window.dataLayer || [];
|
||||||
|
function gtag(){dataLayer.push(arguments);}
|
||||||
|
gtag('js', new Date());
|
||||||
|
|
||||||
|
gtag('config', 'G-RGJ5TDHWY9');
|
||||||
|
</script>
|
||||||
|
<link rel="icon" href="favicon.svg" type="image/svg+xml">
|
||||||
|
<!-- Google Fonts -->
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Libre+Baskerville:wght@400;700&family=Inter:wght@400;600&display=swap" rel="stylesheet">
|
||||||
|
<!-- Bootstrap CSS -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" />
|
||||||
|
<!-- Bootstrap Icons -->
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css" rel="stylesheet" />
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body id="top">
|
||||||
|
<nav class="navbar navbar-expand-lg fixed-top bg-dark" data-bs-theme="dark">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="#top">Hacker Laws</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navMenu">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse justify-content-end" id="navMenu">
|
||||||
|
<ul class="navbar-nav me-auto">
|
||||||
|
<li class="nav-item"><a class="nav-link" href="https://effective-shell.com" target="_blank"><i class="bi bi-book"></i> Effective Shell</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="https://github.com/dwmkerr/terminal-ai" target="_blank"><i class="bi bi-terminal"></i> Terminal AI</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="https://github.com/sponsors/dwmkerr" target="_blank"><i class="bi bi-cup-hot"></i> Sponsor</a></li>
|
||||||
|
</ul>
|
||||||
|
<a href="https://github.com/dwmkerr/hacker-laws" target="_blank"><button class="btn btn-outline-light" type="submit"><i class="bi bi-github"></i> GitHub</button></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<header class="container">
|
||||||
|
<h1>Hacker Laws</h1>
|
||||||
|
<p class="lead">Laws, Theories, Principles and Patterns that developers will find useful.</p>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="container">
|
||||||
|
<!-- Quick links. -->
|
||||||
|
{{ links }}
|
||||||
|
<hr>
|
||||||
|
<!-- The table of contents. -->
|
||||||
|
{{ toc }}
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<!-- Each of the sections - most of which are laws. -->
|
||||||
|
{% for section in sections %}
|
||||||
|
<section id="{{ section.id }}" class="law-section">
|
||||||
|
{{ section.full_content | safe }}
|
||||||
|
<div class="social-sharing">
|
||||||
|
<a href="https://twitter.com/intent/tweet?url=https://hacker-laws.com/#{{ section.id}}?hashtags=example" title="Share on Twitter" target="_blank"><i class="bi bi-twitter"></i></a>
|
||||||
|
<a href="https://www.facebook.com/sharer/sharer.php?u=https://hacker-laws.com/#{{ section.id }}" title="Share on Facebook" target="_blank"><i class="bi bi-facebook"></i></a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="container text-center my-4">
|
||||||
|
<p>© 2025 Hacker Laws</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
21
.github/website/src/script.js
vendored
Normal file
21
.github/website/src/script.js
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
$(document).ready(function() {
|
||||||
|
$("h1, h2, h3, h4, h5, h6").each(function() {
|
||||||
|
var $heading = $(this);
|
||||||
|
var headingId = $heading.attr("id") || $heading.text().trim().toLowerCase().replace(/\s+/g, "-");
|
||||||
|
|
||||||
|
// Ensure a unique ID
|
||||||
|
$heading.attr("id", headingId);
|
||||||
|
|
||||||
|
// Create the anchor link
|
||||||
|
var $anchor = $('<a>')
|
||||||
|
.attr("href", "#" + headingId)
|
||||||
|
.addClass("header-link")
|
||||||
|
.html("#");
|
||||||
|
|
||||||
|
// Append to the heading
|
||||||
|
$heading.append($anchor);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Bootstrap requires that blockquote elements have the 'blockquote' class.
|
||||||
|
$('blockquote').addClass('blockquote').addClass('.quote');
|
||||||
|
});
|
||||||
80
.github/website/src/styles.css
vendored
Normal file
80
.github/website/src/styles.css
vendored
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
html {
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Inter', sans-serif;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #333;
|
||||||
|
padding-top: 70px;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
max-width: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding: 2rem 0;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-family: 'Libre Baskerville', serif;
|
||||||
|
/* Avoid scrolling under the sticky header. */
|
||||||
|
scroll-margin-top: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.law-section {
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
padding: 1.5rem;
|
||||||
|
background-color: #fff;
|
||||||
|
border-bottom: 1px solid #e5e5e5;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.law-section h2 {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.law-section h2 a.anchor {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #999;
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.law-section:hover h2 a.anchor {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.social-sharing a {
|
||||||
|
margin-right: 0.75rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: #555;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.social-sharing a:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.back-to-top {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initially hide the hash link */
|
||||||
|
.header-link {
|
||||||
|
text-decoration: none;
|
||||||
|
margin-left: 12px; /* Increased left padding */
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
font-size: inherit; /* Matches the heading size */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only show the hash when the whole section is hovered */
|
||||||
|
section:hover .header-link,
|
||||||
|
article:hover .header-link,
|
||||||
|
div:hover .header-link {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
43
.github/workflows/build-on-pull-request.yaml
vendored
43
.github/workflows/build-on-pull-request.yaml
vendored
@@ -1,43 +0,0 @@
|
|||||||
# This pipeline builds the PDF ebook on any pull request to master.
|
|
||||||
name: "Build PDF"
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- master
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
prepare-pdf:
|
|
||||||
# Focal Fossa. Please don't use 'latest' tags, it's an anti-pattern.
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
# Checkout the code.
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
# Set a descriptive version. For PRs it'll be the short sha.
|
|
||||||
- name: Set Version
|
|
||||||
id: set_version
|
|
||||||
run: echo ::set-output name=VERSION::$(git rev-parse --short HEAD)
|
|
||||||
|
|
||||||
# Prepare the content files.
|
|
||||||
- name: Prepare Content
|
|
||||||
run: ./scripts/prepare-markdown-for-ebook.sh ${{ steps.set_version.outputs.VERSION }}
|
|
||||||
|
|
||||||
# Create a PDF from the prepared markdown.
|
|
||||||
- name: Prepare PDF
|
|
||||||
uses: docker://pandoc/latex:2.9
|
|
||||||
with:
|
|
||||||
args: "-V toc-title:\"Table Of Contents\" --toc --pdf-engine=pdflatex --standalone --output hacker-laws.pdf hacker-laws.md"
|
|
||||||
|
|
||||||
# Publish the PDF and intermediate markdown as an artifact.
|
|
||||||
- name: Publish PDF Artifact
|
|
||||||
uses: actions/upload-artifact@master
|
|
||||||
with:
|
|
||||||
name: hacker-laws.pdf
|
|
||||||
path: hacker-laws.pdf
|
|
||||||
|
|
||||||
- name: Publish Intermediate Markdown Artifact
|
|
||||||
uses: actions/upload-artifact@master
|
|
||||||
with:
|
|
||||||
name: hacker-laws.md
|
|
||||||
path: hacker-laws.md
|
|
||||||
108
.github/workflows/cicd.yaml
vendored
Normal file
108
.github/workflows/cicd.yaml
vendored
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
name: CI/CD
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
# Permissions to check contents and open PR (release pleases) and update pages.
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
pages: write
|
||||||
|
id-token: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-website-build:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Test Website Build
|
||||||
|
run: |
|
||||||
|
cd .github/website
|
||||||
|
make install
|
||||||
|
make build
|
||||||
|
cp -r build/. '../pages'
|
||||||
|
ls -al "../pages"
|
||||||
|
|
||||||
|
release:
|
||||||
|
needs: test-website-build
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
outputs:
|
||||||
|
released: ${{ steps.release-please.outputs.release_created }}
|
||||||
|
tag: ${{ steps.release-please.outputs.tag_name }}
|
||||||
|
steps:
|
||||||
|
- uses: googleapis/release-please-action@v4
|
||||||
|
id: release-please
|
||||||
|
with:
|
||||||
|
manifest-file: .github/release-please-manifest.json
|
||||||
|
config-file: .github/release-please-config.json
|
||||||
|
|
||||||
|
release-pdf:
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
needs: release
|
||||||
|
if: ${{ needs.release.outputs.released }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
# Set a descriptive version. For PRs it'll be the short sha.
|
||||||
|
- name: Check Version
|
||||||
|
run: echo "${VERSION}"
|
||||||
|
env:
|
||||||
|
VERSION: ${{ needs.release.outputs.tag }}
|
||||||
|
|
||||||
|
# Set a descriptive version. For PRs it'll be the short sha.
|
||||||
|
- name: Prepare Markdown
|
||||||
|
run: |
|
||||||
|
# Set the env vars we use (version set for clarity).
|
||||||
|
export DATE=$(date +%F)
|
||||||
|
export VERSION="${VERSION}"
|
||||||
|
make -f .github/makefile prepare-markdown
|
||||||
|
env:
|
||||||
|
VERSION: ${{ needs.release.outputs.tag }}
|
||||||
|
|
||||||
|
# Create the PDF files.
|
||||||
|
- name: Create PDF
|
||||||
|
run: make -f .github/makefile create-pdf
|
||||||
|
|
||||||
|
# Publish the PDF and intermediate markdown as an artifact.
|
||||||
|
# - name: Publish PDF Artifact
|
||||||
|
# uses: actions/upload-artifact@3
|
||||||
|
# with:
|
||||||
|
# name: hacker-laws.pdf
|
||||||
|
# path: hacker-laws.pdf
|
||||||
|
|
||||||
|
- name: Attach assets to GitHub Release
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
gh release upload "${{ needs.release.outputs.tag }}" --clobber hacker-laws.pdf hacker-laws.md
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Setup Pages
|
||||||
|
uses: actions/configure-pages@v5
|
||||||
|
- name: Build Website
|
||||||
|
run: |
|
||||||
|
cd .github/website
|
||||||
|
make install
|
||||||
|
make build
|
||||||
|
cp -r build/. '../pages'
|
||||||
|
ls -al "../pages"
|
||||||
|
- name: Upload artifact
|
||||||
|
uses: actions/upload-pages-artifact@v3
|
||||||
|
with:
|
||||||
|
path: './.github/pages'
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
id: deployment
|
||||||
|
uses: actions/deploy-pages@v4
|
||||||
10
.github/workflows/pages.yaml
vendored
10
.github/workflows/pages.yaml
vendored
@@ -3,8 +3,7 @@ name: Deploy to Pages
|
|||||||
on:
|
on:
|
||||||
# Runs on pushes targeting the default branch (or runs manually).
|
# Runs on pushes targeting the default branch (or runs manually).
|
||||||
push:
|
push:
|
||||||
# branches: [$default-branch]
|
branches: [$default-branch]
|
||||||
branches: ['build/pages'] # we're deploying from a build branch for now.
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||||
@@ -31,6 +30,13 @@ jobs:
|
|||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Setup Pages
|
- name: Setup Pages
|
||||||
uses: actions/configure-pages@v5
|
uses: actions/configure-pages@v5
|
||||||
|
- name: Build Website
|
||||||
|
run: |
|
||||||
|
cd .github/website
|
||||||
|
make install
|
||||||
|
make build
|
||||||
|
cp -r build/. '../pages'
|
||||||
|
ls -al "../pages"
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-pages-artifact@v3
|
uses: actions/upload-pages-artifact@v3
|
||||||
with:
|
with:
|
||||||
|
|||||||
69
.github/workflows/release-on-tag.yaml
vendored
69
.github/workflows/release-on-tag.yaml
vendored
@@ -1,69 +0,0 @@
|
|||||||
# This pipeline builds the PDF ebook on any tag starting with 'v'.
|
|
||||||
name: "Create Release"
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
prepare-pdf:
|
|
||||||
# Focal Fossa. Please don't use 'latest' tags, it's an anti-pattern.
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
# Checkout the code.
|
|
||||||
- name: Checkout
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
# Set a descriptive version. For PRs it'll be the short sha.
|
|
||||||
- name: Set Version
|
|
||||||
id: set_version
|
|
||||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
|
||||||
|
|
||||||
# Prepare the content files.
|
|
||||||
- name: Prepare Content
|
|
||||||
run: ./scripts/prepare-markdown-for-ebook.sh ${{ steps.set_version.outputs.VERSION }}
|
|
||||||
|
|
||||||
# Create a PDF from the prepared markdown.
|
|
||||||
- name: Prepare PDF
|
|
||||||
uses: docker://pandoc/latex:2.9
|
|
||||||
with:
|
|
||||||
args: "-V toc-title:\"Table Of Contents\" --toc --pdf-engine=pdflatex --standalone --output hacker-laws.pdf hacker-laws.md"
|
|
||||||
|
|
||||||
# Publish the PDF artifact.
|
|
||||||
- name: Publish PDF Artifacts
|
|
||||||
uses: actions/upload-artifact@master
|
|
||||||
with:
|
|
||||||
name: hacker-laws.pdf
|
|
||||||
path: hacker-laws.pdf
|
|
||||||
|
|
||||||
release:
|
|
||||||
needs: prepare-pdf
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Download artifact
|
|
||||||
uses: actions/download-artifact@v2
|
|
||||||
with:
|
|
||||||
name: hacker-laws.pdf
|
|
||||||
|
|
||||||
- name: Create Release
|
|
||||||
id: create-release
|
|
||||||
uses: actions/create-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
tag_name: ${{ github.ref }}
|
|
||||||
release_name: ${{ github.ref }}
|
|
||||||
body: |
|
|
||||||
Hacker Laws E-Book
|
|
||||||
draft: false
|
|
||||||
prerelease: false
|
|
||||||
|
|
||||||
- name: Upload Release Asset
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create-release.outputs.upload_url }}
|
|
||||||
asset_path: ./hacker-laws.pdf
|
|
||||||
asset_name: hacker-laws.pdf
|
|
||||||
asset_content_type: application/pdf
|
|
||||||
113
README.md
113
README.md
@@ -1,10 +1,15 @@
|
|||||||
# 💻📖 hacker-laws
|
<h1 align="center"><a href="https://hacker-laws.com" target="_blank">hacker-laws</a></h1>
|
||||||
|
<h4 align="center">🧠 Laws, Theories, Principles and Patterns for developers and technologists.</h4>
|
||||||
|
|
||||||
Laws, Theories, Principles and Patterns that developers will find useful.
|
---
|
||||||
|
|
||||||
[Translations](#translations): [🇮🇩](./translations/id.md) [🇧🇷](./translations/pt-BR.md) [🇨🇳](https://github.com/nusr/hacker-laws-zh) [🇩🇪](./translations/de.md) [🇫🇷](./translations/fr.md) [🇬🇷](./translations/el.md) [🇮🇹](https://github.com/csparpa/hacker-laws-it) [🇱🇻](./translations/lv.md) [🇰🇷](https://github.com/codeanddonuts/hacker-laws-kr) [🇵🇱](./translations/pl.md) [🇷🇺](https://github.com/solarrust/hacker-laws) [🇪🇸](./translations/es-ES.md) [🇹🇷](https://github.com/umutphp/hacker-laws-tr) [🇯🇵](./translations/jp.md) [🇺🇦](./translations/uk.md) [🇻🇳](./translations/vi.md)
|
- 📖 My new book [Effective Shell](https://effective-shell) on [Amazon](https://amzn.to/4ho0F91)
|
||||||
|
- 🌍 Try [hacker-laws.com](https://hacker-laws.com)
|
||||||
Like this project? Please considering [sponsoring me](https://github.com/sponsors/dwmkerr) and the [translators](#translations). Also check out this podcast on [The Changelog - Laws for Hackers to Live By](https://changelog.com/podcast/403) to learn more about the project! You can also [download the latest PDF eBook](https://github.com/dwmkerr/hacker-laws/releases/latest/download/hacker-laws.pdf). Check the [Contributor Guide](./.github/contributing.md) if you are keen to contribute!
|
- 🧠 Check out my new project [Terminal AI](https://github.com/dwmkerr/terminal-ai)
|
||||||
|
- ☕️ Like this project? Consider [buying me a coffee with a one-off donation](https://github.com/sponsors/dwmkerr?frequency=one-time)
|
||||||
|
- 🎧 Listen to the podcast [The Changelog - Laws for Hackers to Live By](https://changelog.com/podcast/403)
|
||||||
|
- 📖 Download the [PDF eBook](https://github.com/dwmkerr/hacker-laws/releases/latest/download/hacker-laws.pd)
|
||||||
|
- 🌏 See the [Translations](#translations)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -43,6 +48,7 @@ Like this project? Please considering [sponsoring me](https://github.com/sponsor
|
|||||||
- [Premature Optimization Effect](#premature-optimization-effect)
|
- [Premature Optimization Effect](#premature-optimization-effect)
|
||||||
- [Putt's Law](#putts-law)
|
- [Putt's Law](#putts-law)
|
||||||
- [Reed's Law](#reeds-law)
|
- [Reed's Law](#reeds-law)
|
||||||
|
- [The Bitter Lesson](#the-bitter-lesson)
|
||||||
- [The Ringelmann Effect](#the-ringelmann-effect)
|
- [The Ringelmann Effect](#the-ringelmann-effect)
|
||||||
- [The Law of Conservation of Complexity (Tesler's Law)](#the-law-of-conservation-of-complexity-teslers-law)
|
- [The Law of Conservation of Complexity (Tesler's Law)](#the-law-of-conservation-of-complexity-teslers-law)
|
||||||
- [The Law of Demeter](#the-law-of-demeter)
|
- [The Law of Demeter](#the-law-of-demeter)
|
||||||
@@ -59,6 +65,7 @@ Like this project? Please considering [sponsoring me](https://github.com/sponsor
|
|||||||
- [Principles](#principles)
|
- [Principles](#principles)
|
||||||
- [All Models Are Wrong (George Box's Law)](#all-models-are-wrong-george-boxs-law)
|
- [All Models Are Wrong (George Box's Law)](#all-models-are-wrong-george-boxs-law)
|
||||||
- [Chesterton's Fence](#chestertons-fence)
|
- [Chesterton's Fence](#chestertons-fence)
|
||||||
|
- [Kerckhoffs's principle](#kerckhoffss-principle)
|
||||||
- [The Dead Sea Effect](#the-dead-sea-effect)
|
- [The Dead Sea Effect](#the-dead-sea-effect)
|
||||||
- [The Dilbert Principle](#the-dilbert-principle)
|
- [The Dilbert Principle](#the-dilbert-principle)
|
||||||
- [The Pareto Principle (The 80/20 Rule)](#the-pareto-principle-the-8020-rule)
|
- [The Pareto Principle (The 80/20 Rule)](#the-pareto-principle-the-8020-rule)
|
||||||
@@ -80,10 +87,6 @@ Like this project? Please considering [sponsoring me](https://github.com/sponsor
|
|||||||
- [Online Resources](#online-resources)
|
- [Online Resources](#online-resources)
|
||||||
- [PDF eBook](#pdf-ebook)
|
- [PDF eBook](#pdf-ebook)
|
||||||
- [Podcast](#podcast)
|
- [Podcast](#podcast)
|
||||||
- [Translations](#translations)
|
|
||||||
- [Related Projects](#related-projects)
|
|
||||||
- [Contributing](#contributing)
|
|
||||||
- [TODO](#todo)
|
|
||||||
|
|
||||||
<!-- vim-markdown-toc -->
|
<!-- vim-markdown-toc -->
|
||||||
|
|
||||||
@@ -91,12 +94,11 @@ Like this project? Please considering [sponsoring me](https://github.com/sponsor
|
|||||||
|
|
||||||
There are lots of laws which people discuss when talking about development. This repository is a reference and overview of some of the most common ones. Please share and submit PRs!
|
There are lots of laws which people discuss when talking about development. This repository is a reference and overview of some of the most common ones. Please share and submit PRs!
|
||||||
|
|
||||||
❗: This repo contains an explanation of some laws, principles and patterns, but does not _advocate_ for any of them. Whether they should be applied will always be a matter of debate, and greatly dependent on what you are working on.
|
Warning: This repo contains an explanation of some laws, principles and patterns, but does not _advocate_ for any of them. Whether they should be applied will always be a matter of debate, and greatly dependent on what you are working on.
|
||||||
|
|
||||||
## Laws
|
## Laws
|
||||||
|
|
||||||
And here we go!
|
Laws can be opinions on inevitabilities in the world of software engineering, or wry observations on unavoidable realities.
|
||||||
|
|
||||||
|
|
||||||
### 90–9–1 Principle (1% Rule)
|
### 90–9–1 Principle (1% Rule)
|
||||||
|
|
||||||
@@ -137,7 +139,6 @@ The diagram below shows some examples of potential improvements in speed:
|
|||||||
|
|
||||||
<img width="480px" alt="Diagram: Amdahl's Law" src="./images/amdahls_law.png" />
|
<img width="480px" alt="Diagram: Amdahl's Law" src="./images/amdahls_law.png" />
|
||||||
|
|
||||||
*(Image Reference: By Daniels219 at English Wikipedia, Creative Commons Attribution-Share Alike 3.0 Unported, https://en.wikipedia.org/wiki/File:AmdahlsLaw.svg)*
|
|
||||||
|
|
||||||
As can be seen, even a program which is 50% parallelisable will benefit very little beyond 10 processing units, whereas a program which is 95% parallelisable can still achieve significant speed improvements with over a thousand processing units.
|
As can be seen, even a program which is 50% parallelisable will benefit very little beyond 10 processing units, whereas a program which is 95% parallelisable can still achieve significant speed improvements with over a thousand processing units.
|
||||||
|
|
||||||
@@ -270,7 +271,6 @@ As a person's understanding and experience in a domain grows, they may well enco
|
|||||||
|
|
||||||
Real-world examples:
|
Real-world examples:
|
||||||
|
|
||||||
* [Apple vs. FBI: Why This Anti-Terror Hawk Switched Sides](https://fortune.com/2016/03/10/apple-fbi-lindsay-graham/) - In 2016 Senator Lindsey Graham changed his stance on Apple creating a 'backdoor' in their encryption of devices. Initially Graham had been critical of Apple challenging a request to create a 'backdoor', which he saw as necessary to investigate potential terrorist plots. However, by Graham's own admission, as he learned more about the technical complexity of the domain, he realised that he had assumed it to be far more simple than he had realised, and that such a backdoor could have serious negative consequences. This could potentially be considered an example of the Dunning-Kruger effect - a cyber-security expert would likely understand immediately how such a backdoor could be exploited, as they have deep understanding of the domain, a layperson might assume that phone security is more similar to _physical security_ where the practice of having a 'master key' for law enforcement is possible, but this analogy does not apply sufficiently well to describe modern encryption in cyber-security.
|
|
||||||
|
|
||||||
### Fitts' Law
|
### Fitts' Law
|
||||||
|
|
||||||
@@ -280,7 +280,6 @@ Fitts' law predicts that the time required to move to a target area is a functio
|
|||||||
|
|
||||||
<img width="300px" alt="Diagram: Fitts Law" src="./images/Fitts_Law.svg" />
|
<img width="300px" alt="Diagram: Fitts Law" src="./images/Fitts_Law.svg" />
|
||||||
|
|
||||||
*(Image Reference: By Foobar628 at English Wikipedia, Creative Commons Attribution-Share Alike 3.0 Unported, https://en.wikipedia.org/wiki/Fitts%27s_law#/media/File:Fitts_Law.svg)*
|
|
||||||
|
|
||||||
The consequences of this law dictate that when designing UX or UI, interactive elements should be as large as possible and the distance between the users attention area and interactive element should be as small as possible. This has consequences on design, such as grouping tasks that are commonly used with one another close.
|
The consequences of this law dictate that when designing UX or UI, interactive elements should be as large as possible and the distance between the users attention area and interactive element should be as small as possible. This has consequences on design, such as grouping tasks that are commonly used with one another close.
|
||||||
|
|
||||||
@@ -352,7 +351,6 @@ In the equation below, `T` is the time to make a decision, `n` is the number of
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
*(Image Reference: Creative Commons Attribution-Share Alike 3.0 Unported, https://en.wikipedia.org/wiki/Hick%27s_law)*
|
|
||||||
|
|
||||||
This law only applies when the number of options is _ordered_, for example, alphabetically. This is implied in the base two logarithm - which implies the decision maker is essentially performing a _binary search_. If the options are not well ordered, experiments show the time taken is linear.
|
This law only applies when the number of options is _ordered_, for example, alphabetically. This is implied in the base two logarithm - which implies the decision maker is essentially performing a _binary search_. If the options are not well ordered, experiments show the time taken is linear.
|
||||||
|
|
||||||
@@ -403,7 +401,6 @@ The Hype Cycle is a visual representation of the excitement and development of t
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
*(Image Reference: By Jeremykemp at English Wikipedia, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=10547051)*
|
|
||||||
|
|
||||||
In short, this cycle suggests that there is typically a burst of excitement around new technology and its potential impact. Teams often jump into these technologies quickly, and sometimes find themselves disappointed with the results. This might be because the technology is not yet mature enough, or real-world applications are not yet fully realised. After a certain amount of time, the capabilities of the technology increase and practical opportunities to use it increase, and teams can finally become productive. Roy Amara's quote sums this up most succinctly - "We tend to overestimate the effect of a technology in the short run and underestimate in the long run".
|
In short, this cycle suggests that there is typically a burst of excitement around new technology and its potential impact. Teams often jump into these technologies quickly, and sometimes find themselves disappointed with the results. This might be because the technology is not yet mature enough, or real-world applications are not yet fully realised. After a certain amount of time, the capabilities of the technology increase and practical opportunities to use it increase, and teams can finally become productive. Roy Amara's quote sums this up most succinctly - "We tend to overestimate the effect of a technology in the short run and underestimate in the long run".
|
||||||
|
|
||||||
@@ -418,7 +415,6 @@ In short, this cycle suggests that there is typically a burst of excitement arou
|
|||||||
>
|
>
|
||||||
> (Hyrum Wright)
|
> (Hyrum Wright)
|
||||||
|
|
||||||
Hyrum's Law states that when you have a _large enough number of consumers_ of an API, all behaviours of the API (even those not defined as part of a public contract) will eventually come to be depended on by someone. A trivial example may be non-functional elements such as the response time of an API. A more subtle example might be consumers who are relying on applying a regex to an error message to determine the *type* of error of an API. Even if the public contract of the API states nothing about the contents of the message, indicating users should use an associated error code, _some_ users may use the message, and changing the message essentially breaks the API for those users.
|
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
@@ -545,7 +541,6 @@ Example:
|
|||||||
|
|
||||||
In its original context, this Law was based on studies of bureaucracies. It may be pessimistically applied to software development initiatives, the theory being that teams will be inefficient until deadlines near, then rush to complete work by the deadline, thus making the actual deadline somewhat arbitrary.
|
In its original context, this Law was based on studies of bureaucracies. It may be pessimistically applied to software development initiatives, the theory being that teams will be inefficient until deadlines near, then rush to complete work by the deadline, thus making the actual deadline somewhat arbitrary.
|
||||||
|
|
||||||
If this law were combined with [Hofstadter's Law](#hofstadters-law), an even more pessimistic viewpoint is reached - work will expand to fill the time available for its completion and *still take longer than expected*.
|
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
|
|
||||||
@@ -559,7 +554,6 @@ See also:
|
|||||||
>
|
>
|
||||||
> [(Donald Knuth)](https://twitter.com/realdonaldknuth?lang=en)
|
> [(Donald Knuth)](https://twitter.com/realdonaldknuth?lang=en)
|
||||||
|
|
||||||
In Donald Knuth's paper [Structured Programming With Go To Statements](http://wiki.c2.com/?StructuredProgrammingWithGoToStatements), he wrote: "Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: **premature optimization is the root of all evil**. Yet we should not pass up our opportunities in that critical 3%."
|
|
||||||
|
|
||||||
However, _Premature Optimization_ can be defined (in less loaded terms) as optimizing before we know that we need to.
|
However, _Premature Optimization_ can be defined (in less loaded terms) as optimizing before we know that we need to.
|
||||||
|
|
||||||
@@ -594,6 +588,18 @@ See also:
|
|||||||
- [Metcalfe's Law](#metcalfes-law)
|
- [Metcalfe's Law](#metcalfes-law)
|
||||||
- [Dunbar's Number](#dunbars-number)
|
- [Dunbar's Number](#dunbars-number)
|
||||||
|
|
||||||
|
### The Bitter Lesson
|
||||||
|
|
||||||
|
[The Bitter Lesson by Richard S. Sutton](http://www.incompleteideas.net/IncIdeas/BitterLesson.html)
|
||||||
|
|
||||||
|
> The biggest lesson that can be read from 70 years of AI research is that general methods that leverage computation are ultimately the most effective, and by a large margin.
|
||||||
|
>
|
||||||
|
> Richard S. Sutton (2019)
|
||||||
|
|
||||||
|
The "Bitter Lesson", stated by [Rich S. Sutton](https://en.wikipedia.org/wiki/Richard_S._Sutton), says that scale (in terms of both data and computational power) has driven the most significant advancements in AI research, rather than the intricacies of the research methods themselves.
|
||||||
|
|
||||||
|
He goes on to suggest that this indicates we should stop trying to build simplified (or even complex) models of the mind as history has shown that these have always in the long term been failures compared to (as an example) scaling the capacity of neural networks and applying existing methods such as convolution.
|
||||||
|
|
||||||
### The Ringelmann Effect
|
### The Ringelmann Effect
|
||||||
|
|
||||||
[The Ringelmann effect on Wikipedia](https://en.wikipedia.org/wiki/Ringelmann_effect)
|
[The Ringelmann effect on Wikipedia](https://en.wikipedia.org/wiki/Ringelmann_effect)
|
||||||
@@ -635,7 +641,6 @@ Following this principal limits the scope of changes, making them easier and saf
|
|||||||
|
|
||||||
This law states that abstractions, which are generally used in computing to simplify working with complicated systems, will in certain situations 'leak' elements of the underlying system, this making the abstraction behave in an unexpected way.
|
This law states that abstractions, which are generally used in computing to simplify working with complicated systems, will in certain situations 'leak' elements of the underlying system, this making the abstraction behave in an unexpected way.
|
||||||
|
|
||||||
An example might be loading a file and reading its contents. The file system APIs are an _abstraction_ of the lower level kernel systems, which are themselves an abstraction over the physical processes relating to changing data on a magnetic platter (or flash memory for an SSD). In most cases, the abstraction of treating a file like a stream of binary data will work. However, for a magnetic drive, reading data sequentially will be *significantly* faster than random access (due to increased overhead of page faults), but for an SSD drive, this overhead will not be present. Underlying details will need to be understood to deal with this case (for example, database index files are structured to reduce the overhead of random access), the abstraction 'leaks' implementation details the developer may need to be aware of.
|
|
||||||
|
|
||||||
The example above can become more complex when _more_ abstractions are introduced. The Linux operating system allows files to be accessed over a network but represented locally as 'normal' files. This abstraction will 'leak' if there are network failures. If a developer treats these files as 'normal' files, without considering the fact that they may be subject to network latency and failures, the solutions will be buggy.
|
The example above can become more complex when _more_ abstractions are introduced. The Linux operating system allows files to be accessed over a network but represented locally as 'normal' files. This abstraction will 'leak' if there are network failures. If a developer treats these files as 'normal' files, without considering the fact that they may be subject to network latency and failures, the solutions will be buggy.
|
||||||
|
|
||||||
@@ -801,6 +806,22 @@ This principle is relevant in software engineering when removing technical debt.
|
|||||||
|
|
||||||
The name of this principle comes from a story by [G.K. Chesterton](https://en.wikipedia.org/wiki/G._K._Chesterton). A man comes across a fence crossing the middle of the road. He complains to the mayor that this useless fence is getting in the way, and asks to remove it. The mayor asks why the fence is there in the first place. When the man says he doesn't know, the mayor says, "If you don't know its purpose, I certainly won't let you remove it. Go and find out the use of it, and then I may let you destroy it."
|
The name of this principle comes from a story by [G.K. Chesterton](https://en.wikipedia.org/wiki/G._K._Chesterton). A man comes across a fence crossing the middle of the road. He complains to the mayor that this useless fence is getting in the way, and asks to remove it. The mayor asks why the fence is there in the first place. When the man says he doesn't know, the mayor says, "If you don't know its purpose, I certainly won't let you remove it. Go and find out the use of it, and then I may let you destroy it."
|
||||||
|
|
||||||
|
### Kerckhoffs's principle
|
||||||
|
|
||||||
|
[Kerckhoffs's principle on Wikipedia](https://en.wikipedia.org/wiki/Kerckhoffs%27s_principle)
|
||||||
|
|
||||||
|
> "...design your system assuming that your opponents know it in detail."
|
||||||
|
>
|
||||||
|
> _Steven M. Bellovin's formulation of Kerckhoff's Principle_
|
||||||
|
|
||||||
|
This principle of cryptography was an axiom created by cryptographer Auguste Kerckhoffs. He stated that a cryptosystem should be secure, even if everything about the system, except the key, is public knowledge. Not to be confused with [_"security through obscurity"_](#todo).
|
||||||
|
|
||||||
|
The gold standard for any secret-keeping system is that implementation details should be publicly distributed, without sacrificing or compromising security of said system.
|
||||||
|
|
||||||
|
The history of cryptography has shown that open discussion and analysis of cryptographic systems leads to better and more secure systems - as researchers are able to test for and expose potential vulnerabilities.
|
||||||
|
|
||||||
|
- [Shannon's Maxim](#todo)
|
||||||
|
|
||||||
### The Dead Sea Effect
|
### The Dead Sea Effect
|
||||||
|
|
||||||
[The Dead Sea Effect on Bruce F. Webster](http://brucefwebster.com/2008/04/11/the-wetware-crisis-the-dead-sea-effect/)
|
[The Dead Sea Effect on Bruce F. Webster](http://brucefwebster.com/2008/04/11/the-wetware-crisis-the-dead-sea-effect/)
|
||||||
@@ -906,11 +927,6 @@ See Also:
|
|||||||
|
|
||||||
This is an acronym, which refers to:
|
This is an acronym, which refers to:
|
||||||
|
|
||||||
* S: [The Single Responsibility Principle](#the-single-responsibility-principle)
|
|
||||||
* O: [The Open/Closed Principle](#the-openclosed-principle)
|
|
||||||
* L: [The Liskov Substitution Principle](#the-liskov-substitution-principle)
|
|
||||||
* I: [The Interface Segregation Principle](#the-interface-segregation-principle)
|
|
||||||
* D: [The Dependency Inversion Principle](#the-dependency-inversion-principle)
|
|
||||||
|
|
||||||
These are key principles in [Object-Oriented Programming](#todo). Design principles such as these should be able to aid developers build more maintainable systems.
|
These are key principles in [Object-Oriented Programming](#todo). Design principles such as these should be able to aid developers build more maintainable systems.
|
||||||
|
|
||||||
@@ -1035,7 +1051,6 @@ See also:
|
|||||||
|
|
||||||
[YAGNI on Wikipedia](https://en.wikipedia.org/wiki/You_ain%27t_gonna_need_it)
|
[YAGNI on Wikipedia](https://en.wikipedia.org/wiki/You_ain%27t_gonna_need_it)
|
||||||
|
|
||||||
This is an acronym for _**Y**ou **A**in't **G**onna **N**eed **I**t_.
|
|
||||||
|
|
||||||
> Always implement things when you actually need them, never when you just foresee that you need them.
|
> Always implement things when you actually need them, never when you just foresee that you need them.
|
||||||
>
|
>
|
||||||
@@ -1122,47 +1137,3 @@ Hacker Laws has been featured in [The Changelog](https://changelog.com/podcast/4
|
|||||||
|
|
||||||
<a href="https://changelog.com/podcast/403" target="_blank"><img src="./images/changelog-podcast.png" width="800px" alt="Changelog Podcast Image" /></a>
|
<a href="https://changelog.com/podcast/403" target="_blank"><img src="./images/changelog-podcast.png" width="800px" alt="Changelog Podcast Image" /></a>
|
||||||
|
|
||||||
## Translations
|
|
||||||
|
|
||||||
Thanks to a number of wonderful contributors, Hacker Laws is available in a number of languages. Please consider sponsoring moderators!
|
|
||||||
|
|
||||||
| Language | Moderator | Status |
|
|
||||||
|----------|-----------|--------|
|
|
||||||
| [AR Arabic / Arabic](./translations/ar-AR.md) | [Abdurrahman Rajab - a0m0rajab](https://github.com/a0m0rajab) | . |
|
|
||||||
| [🇮🇩 Bahasa Indonesia / Indonesian](./translations/pt-BR.md) | [arywidiantara](https://github.com/arywidiantara) | [](https://gitlocalize.com/repo/2513/id?utm_source=badge) |
|
|
||||||
| [🇧🇷 Brasileiro / Brazilian](./translations/pt-BR.md) | [Eugênio Moreira](https://github.com/eugenioamn), [Leonardo Costa](https://github.com/leofc97) | [](https://gitlocalize.com/repo/2513/pt-BR?utm_source=badge) |
|
|
||||||
| [🇨🇳 中文 / Chinese](https://github.com/nusr/hacker-laws-zh) | [Steve Xu](https://github.com/nusr) | Partially complete |
|
|
||||||
| [🇩🇪 Deutsch / German](./translations/de.md) | [Vikto](https://github.com/viktodergunov) | [](https://gitlocalize.com/repo/2513/de?utm_source=badge) |
|
|
||||||
| [🇫🇷 Français / French](./translations/fr.md) | [Kevin Bockelandt](https://github.com/KevinBockelandt) | [](https://gitlocalize.com/repo/2513/fr?utm_source=badge) |
|
|
||||||
| [🇬🇷 ελληνικά / Greek](./translations/el.md) | [Panagiotis Gourgaris](https://github.com/0gap) | [](https://gitlocalize.com/repo/2513/el?utm_source=badge) |
|
|
||||||
| [🇮🇹 Italiano / Italian](https://github.com/csparpa/hacker-laws-it) | [Claudio Sparpaglione](https://github.com/csparpa) | Partially complete |
|
|
||||||
| [🇯🇵 JP 日本語 / Japanese](./translations/jp.md) | [Fumikazu Fujiwara](https://github.com/freddiefujiwara)| [](https://gitlocalize.com/repo/2513/ja?utm_source=badge) |
|
|
||||||
| [🇰🇷 한국어 / Korean](https://github.com/codeanddonuts/hacker-laws-kr) | [Doughnut](https://github.com/codeanddonuts) | Partially complete |
|
|
||||||
| [🇱🇻 Latviešu Valoda / Latvian](./translations/lv.md) | [Arturs Jansons](https://github.com/iegik) | [](https://gitlocalize.com/repo/2513/lv?utm_source=badge) |
|
|
||||||
| [🇮🇷 فارسی / Persian](./translations/fa.md) | [MohammadErfan Gooneh](https://github.com/MEgooneh) | . |
|
|
||||||
| [🇵🇱 Polski / Polish](./translations/pl.md) | [Mariusz Kogen](https://github.com/k0gen) | [](https://gitlocalize.com/repo/2513/pl?utm_source=badge) |
|
|
||||||
| [🇷🇺 Русская версия / Russian](https://github.com/solarrust/hacker-laws) | [Alena Batitskaya](https://github.com/solarrust) | Partially complete |
|
|
||||||
| [🇪🇸 Castellano / Spanish](./translations/es-ES.md) | [Manuel Rubio](https://github.com/manuel-rubio) ([Sponsor](https://github.com/sponsors/manuel-rubio)) | Partially complete |
|
|
||||||
| [🇹🇷 Türkçe / Turkish](https://github.com/umutphp/hacker-laws-tr) | [Umut Işık](https://github.com/umutphp) | [](https://gitlocalize.com/repo/2513/tr?utm_source=badge) |
|
|
||||||
| [🇺🇦 українська мова / Ukrainian](./translations/uk.md) | [Nazar](https://github.com/troyane), [Helga Lastivka](https://github.com/HelgaLastivka) | [](https://gitlocalize.com/repo/2513/uk?utm_source=badge) |
|
|
||||||
| [🇻🇳 Tiếng Việt / Vietnamese](./translations/vu.md) | [Nguyên](https://github.com/truonghoangnguyen), [Trương Hoàng](https://github.com/truonghoangnguyen) | [](https://gitlocalize.com/repo/2513/vi?utm_source=badge) |
|
|
||||||
|
|
||||||
If you would like to update a translation, follow the [Translators Contributor Guide](https://github.com/dwmkerr/hacker-laws/blob/main/.github/contributing.md#translations).
|
|
||||||
|
|
||||||
## Related Projects
|
|
||||||
|
|
||||||
- [Tip of the Day](https://tips.darekkay.com/html/hacker-laws-en.html) - Receive a daily hacker law/principle.
|
|
||||||
- [Hacker Laws CLI](https://github.com/umutphp/hacker-laws-cli) - List, view and see random laws from the terminal!
|
|
||||||
- [Hacker Laws Action](https://github.com/marketplace/actions/hacker-laws-action) - Adds a random Hacker Law to a pull request as a small gift for the contributor, thanks [Umut Işık](https://github.com/umutphp)
|
|
||||||
|
|
||||||
## Contributing
|
|
||||||
|
|
||||||
Please do contribute! [Raise an issue](https://github.com/dwmkerr/hacker-laws/issues/new) if you'd like to suggest an addition or change, or [Open a pull request](https://github.com/dwmkerr/hacker-laws/compare) to propose your own changes.
|
|
||||||
|
|
||||||
Please be sure to read the [Contributing Guidelines](./.github/contributing.md) for requirements on text, style and so on. Please be aware of the [Code of Conduct](./.github/CODE_OF_CONDUCT.md) when engaging in discussions on the project.
|
|
||||||
|
|
||||||
## TODO
|
|
||||||
|
|
||||||
Hi! If you land here, you've clicked on a link to a topic I've not written up yet, sorry about this - this is work in progress!
|
|
||||||
|
|
||||||
Feel free to [Raise an Issue](https://github.com/dwmkerr/hacker-laws/issues) requesting more details, or [Open a Pull Request](https://github.com/dwmkerr/hacker-laws/pulls) to submit your proposed definition of the topic.
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
# Sharing
|
|
||||||
|
|
||||||
Copy paste the below for sharing on social media. The channels are:
|
|
||||||
|
|
||||||
- [Hacker News](https://news.ycombinator.com)
|
|
||||||
- [`r/programming`](https://reddit.com/r/programming/)
|
|
||||||
- LinkedIn
|
|
||||||
- Twitter
|
|
||||||
|
|
||||||
## LinkedIn
|
|
||||||
|
|
||||||
#hackerlaws - <Law Name> - <Short Quote>
|
|
||||||
|
|
||||||
<Link>
|
|
||||||
|
|
||||||
Hacker Laws is a set of theories, principles and patterns that developers will find useful.
|
|
||||||
|
|
||||||
Thanks <person>
|
|
||||||
|
|
||||||
#hacking #programming #coding #development #computerscience #logic
|
|
||||||
119
assets/site/index.html
Normal file
119
assets/site/index.html
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Interactive Hacker Laws Stack</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
#stack {
|
||||||
|
width: 400px;
|
||||||
|
height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.law-item {
|
||||||
|
text-align: left;
|
||||||
|
padding: 4px;
|
||||||
|
transition: transform 0.2s ease, opacity 0.2s;
|
||||||
|
transform-origin: left;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #333;
|
||||||
|
margin: 6px 0;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.law-item::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #aaa;
|
||||||
|
margin-right: 8px;
|
||||||
|
transition: height 0.2s, background-color 0.2s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="stack" class="stack"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const laws = [
|
||||||
|
"90–9–1 Principle (1% Rule)", "90–90 Rule", "Amdahl's Law", "The Broken Windows Theory",
|
||||||
|
"Brooks' Law", "CAP Theorem (Brewer's Theorem)", "Clarke's Three Laws", "Conway's Law",
|
||||||
|
"Cunningham's Law", "Dunbar's Number", "The Dunning-Kruger Effect", "Fitts' Law",
|
||||||
|
"Gall's Law", "Goodhart's Law", "Hanlon's Razor", "Hofstadter's Law", "Hutber's Law",
|
||||||
|
"The Hype Cycle & Amara's Law", "Hyrum's Law (The Law of Implicit Interfaces)",
|
||||||
|
"Metcalfe's Law", "Moore's Law", "Murphy's Law / Sod's Law", "Occam's Razor",
|
||||||
|
"Parkinson's Law", "Premature Optimization Effect", "Putt's Law", "Reed's Law",
|
||||||
|
"The Law of Conservation of Complexity (Tesler's Law)", "The Law of Leaky Abstractions",
|
||||||
|
"The Law of Triviality", "The Unix Philosophy", "The Spotify Model", "Wadler's Law",
|
||||||
|
"Wheaton's Law", "The Dilbert Principle", "The Pareto Principle (The 80/20 Rule)",
|
||||||
|
"The Peter Principle", "The Robustness Principle (Postel's Law)", "SOLID",
|
||||||
|
"The Single Responsibility Principle", "The Open/Closed Principle", "The Liskov Substitution Principle",
|
||||||
|
"The Interface Segregation Principle", "The Dependency Inversion Principle", "The DRY Principle",
|
||||||
|
"The KISS Principle", "YAGNI"
|
||||||
|
];
|
||||||
|
|
||||||
|
const stack = document.getElementById('stack');
|
||||||
|
const maxZoom = 1.5;
|
||||||
|
const minZoom = 0.6;
|
||||||
|
|
||||||
|
laws.forEach(title => {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = 'law-item';
|
||||||
|
div.innerText = title;
|
||||||
|
stack.appendChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateScale(e) {
|
||||||
|
const items = document.querySelectorAll('.law-item');
|
||||||
|
|
||||||
|
items.forEach(item => {
|
||||||
|
const itemRect = item.getBoundingClientRect();
|
||||||
|
const itemCenter = (itemRect.top + itemRect.bottom) / 2;
|
||||||
|
const distance = Math.abs(e.clientY - itemCenter);
|
||||||
|
const scale = Math.max(maxZoom - distance / 150, minZoom);
|
||||||
|
const opacity = Math.max(1 - distance / 300, 0.3);
|
||||||
|
|
||||||
|
item.style.transform = `scale(${scale})`;
|
||||||
|
item.style.opacity = opacity;
|
||||||
|
|
||||||
|
const dot = item.querySelector('::before');
|
||||||
|
const barHeight = Math.max(6, 30 - distance / 10);
|
||||||
|
item.style.setProperty('--dot-height', barHeight + 'px');
|
||||||
|
item.style.setProperty('--dot-color', distance < 50 ? '#333' : '#aaa');
|
||||||
|
item.querySelector('::before');
|
||||||
|
item.style.setProperty('--dot-height', barHeight + 'px');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', updateScale);
|
||||||
|
|
||||||
|
// Initial positioning
|
||||||
|
updateScale({ clientY: window.innerHeight / 2 });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.law-item::before {
|
||||||
|
height: var(--dot-height, 6px);
|
||||||
|
background-color: var(--dot-color, #aaa);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
110
assets/site/index2.html
Normal file
110
assets/site/index2.html
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Interactive Hacker Laws Stack</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
}
|
||||||
|
#stack {
|
||||||
|
width: 400px;
|
||||||
|
height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.law-item {
|
||||||
|
text-align: left;
|
||||||
|
padding: 2px 4px;
|
||||||
|
transition: transform 0.2s ease, opacity 0.2s;
|
||||||
|
transform-origin: left;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #333;
|
||||||
|
margin: 4px 0;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.law-item::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: var(--bar-width, 6px);
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: var(--bar-color, #aaa);
|
||||||
|
margin-right: 10px;
|
||||||
|
transition: width 0.2s, background-color 0.2s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="stack" class="stack"></div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const laws = [
|
||||||
|
"90–9–1 Principle (1% Rule)", "90–90 Rule", "Amdahl's Law", "The Broken Windows Theory",
|
||||||
|
"Brooks' Law", "CAP Theorem (Brewer's Theorem)", "Clarke's Three Laws", "Conway's Law",
|
||||||
|
"Cunningham's Law", "Dunbar's Number", "The Dunning-Kruger Effect", "Fitts' Law",
|
||||||
|
"Gall's Law", "Goodhart's Law", "Hanlon's Razor", "Hofstadter's Law", "Hutber's Law",
|
||||||
|
"The Hype Cycle & Amara's Law", "Hyrum's Law (The Law of Implicit Interfaces)",
|
||||||
|
"Metcalfe's Law", "Moore's Law", "Murphy's Law / Sod's Law", "Occam's Razor",
|
||||||
|
"Parkinson's Law", "Premature Optimization Effect", "Putt's Law", "Reed's Law",
|
||||||
|
"The Law of Conservation of Complexity (Tesler's Law)", "The Law of Leaky Abstractions",
|
||||||
|
"The Law of Triviality", "The Unix Philosophy", "The Spotify Model", "Wadler's Law",
|
||||||
|
"Wheaton's Law", "The Dilbert Principle", "The Pareto Principle (The 80/20 Rule)",
|
||||||
|
"The Peter Principle", "The Robustness Principle (Postel's Law)", "SOLID",
|
||||||
|
"The Single Responsibility Principle", "The Open/Closed Principle", "The Liskov Substitution Principle",
|
||||||
|
"The Interface Segregation Principle", "The Dependency Inversion Principle", "The DRY Principle",
|
||||||
|
"The KISS Principle", "YAGNI"
|
||||||
|
];
|
||||||
|
|
||||||
|
const stack = document.getElementById('stack');
|
||||||
|
const maxZoom = 1.8;
|
||||||
|
const minZoom = 0.5;
|
||||||
|
|
||||||
|
laws.forEach(title => {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = 'law-item';
|
||||||
|
div.innerText = title;
|
||||||
|
stack.appendChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateScale(e) {
|
||||||
|
const items = document.querySelectorAll('.law-item');
|
||||||
|
|
||||||
|
items.forEach(item => {
|
||||||
|
const itemRect = item.getBoundingClientRect();
|
||||||
|
const itemCenter = (itemRect.top + itemRect.bottom) / 2;
|
||||||
|
const distance = Math.abs(e.clientY - itemCenter);
|
||||||
|
const scale = Math.max(maxZoom - distance / 120, minZoom);
|
||||||
|
const opacity = Math.max(1 - distance / 250, 0.2);
|
||||||
|
const barWidth = Math.max(6, 60 - distance / 5);
|
||||||
|
|
||||||
|
item.style.transform = `scale(${scale})`;
|
||||||
|
item.style.opacity = opacity;
|
||||||
|
item.style.setProperty('--bar-width', barWidth + 'px');
|
||||||
|
item.style.setProperty('--bar-color', distance < 50 ? '#333' : '#aaa');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', updateScale);
|
||||||
|
|
||||||
|
// Initial positioning
|
||||||
|
updateScale({ clientY: window.innerHeight / 2 });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
127
assets/site/index3.html
Normal file
127
assets/site/index3.html
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Interactive Hacker Laws Stack</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#stack-container {
|
||||||
|
width: 400px;
|
||||||
|
height: 500px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#stack {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.law-item {
|
||||||
|
text-align: left;
|
||||||
|
padding: 2px 4px;
|
||||||
|
transition: transform 0.2s ease, opacity 0.2s;
|
||||||
|
transform-origin: left;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #333;
|
||||||
|
margin: 4px 0;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.law-item::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: var(--bar-width, 6px);
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: var(--bar-color, #aaa);
|
||||||
|
margin-right: 10px;
|
||||||
|
transition: width 0.2s, background-color 0.2s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="stack-container">
|
||||||
|
<div id="stack"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const laws = [
|
||||||
|
"90–9–1 Principle (1% Rule)", "90–90 Rule", "Amdahl's Law", "The Broken Windows Theory",
|
||||||
|
"Brooks' Law", "CAP Theorem (Brewer's Theorem)", "Clarke's Three Laws", "Conway's Law",
|
||||||
|
"Cunningham's Law", "Dunbar's Number", "The Dunning-Kruger Effect", "Fitts' Law",
|
||||||
|
"Gall's Law", "Goodhart's Law", "Hanlon's Razor", "Hofstadter's Law", "Hutber's Law",
|
||||||
|
"The Hype Cycle & Amara's Law", "Hyrum's Law (The Law of Implicit Interfaces)",
|
||||||
|
"Metcalfe's Law", "Moore's Law", "Murphy's Law / Sod's Law", "Occam's Razor",
|
||||||
|
"Parkinson's Law", "Premature Optimization Effect", "Putt's Law", "Reed's Law",
|
||||||
|
"The Law of Conservation of Complexity (Tesler's Law)", "The Law of Leaky Abstractions",
|
||||||
|
"The Law of Triviality", "The Unix Philosophy", "The Spotify Model", "Wadler's Law",
|
||||||
|
"Wheaton's Law", "The Dilbert Principle", "The Pareto Principle (The 80/20 Rule)",
|
||||||
|
"The Peter Principle", "The Robustness Principle (Postel's Law)", "SOLID",
|
||||||
|
"The Single Responsibility Principle", "The Open/Closed Principle", "The Liskov Substitution Principle",
|
||||||
|
"The Interface Segregation Principle", "The Dependency Inversion Principle", "The DRY Principle",
|
||||||
|
"The KISS Principle", "YAGNI"
|
||||||
|
];
|
||||||
|
|
||||||
|
const stack = document.getElementById('stack');
|
||||||
|
const stackContainer = document.getElementById('stack-container');
|
||||||
|
const maxZoom = 1.8;
|
||||||
|
const minZoom = 0.5;
|
||||||
|
let offsetY = 0;
|
||||||
|
|
||||||
|
laws.forEach(title => {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = 'law-item';
|
||||||
|
div.innerText = title;
|
||||||
|
stack.appendChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateScale() {
|
||||||
|
const items = document.querySelectorAll('.law-item');
|
||||||
|
|
||||||
|
items.forEach(item => {
|
||||||
|
const itemRect = item.getBoundingClientRect();
|
||||||
|
const containerRect = stackContainer.getBoundingClientRect();
|
||||||
|
const itemCenter = (itemRect.top + itemRect.bottom) / 2;
|
||||||
|
const containerCenter = (containerRect.top + containerRect.bottom) / 2;
|
||||||
|
const distance = Math.abs(containerCenter - itemCenter);
|
||||||
|
const scale = Math.max(maxZoom - distance / 120, minZoom);
|
||||||
|
const opacity = Math.max(1 - distance / 300, 0.3);
|
||||||
|
const barWidth = Math.max(6, 60 - distance / 3);
|
||||||
|
|
||||||
|
item.style.transform = `scale(${scale})`;
|
||||||
|
item.style.opacity = opacity;
|
||||||
|
item.style.setProperty('--bar-width', barWidth + 'px');
|
||||||
|
item.style.setProperty('--bar-color', distance < 50 ? '#333' : '#aaa');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
stackContainer.addEventListener('wheel', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
offsetY = (offsetY + e.deltaY) % stack.scrollHeight;
|
||||||
|
if (offsetY < 0) offsetY += stack.scrollHeight;
|
||||||
|
stack.style.top = `${-offsetY}px`;
|
||||||
|
updateScale();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('mousemove', updateScale);
|
||||||
|
|
||||||
|
updateScale();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
158
assets/site/index4.html
Normal file
158
assets/site/index4.html
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<!--
|
||||||
|
Interactive Hacker Laws Stack - Specification:
|
||||||
|
|
||||||
|
1. User Experience:
|
||||||
|
- Display a vertically scrolling list of items ("laws") in a visually appealing, interactive format.
|
||||||
|
- The list infinitely loops seamlessly; scrolling beyond the first or last item cycles continuously.
|
||||||
|
- Mouse scrolling moves the entire list vertically within a fixed viewport (no internal scrollbar visible).
|
||||||
|
- The item under the mouse cursor smoothly scales up (zooms) and becomes clearly highlighted.
|
||||||
|
- Items further from the cursor scale down smoothly, fade out gradually, and become visually less prominent.
|
||||||
|
- To the left of each text item, a horizontal bar visually represents the focus, forming a bell-curve-like effect.
|
||||||
|
The bar is smallest (circular) when far from the cursor, and smoothly expands (rectangular with rounded corners) when close.
|
||||||
|
|
||||||
|
2. Sources:
|
||||||
|
- Original Interaction Design Inspiration: https://press.stripe.com/
|
||||||
|
- Data Source (list of "Hacker Laws"): https://github.com/dwmkerr/hacker-laws/
|
||||||
|
|
||||||
|
3. Technical Details:
|
||||||
|
- Implemented using plain HTML, CSS, and JavaScript without third-party libraries.
|
||||||
|
- Clearly defined parameters for customization:
|
||||||
|
- `maxZoom`: maximum scale factor for the item closest to the cursor.
|
||||||
|
- `minZoom`: minimum scale factor for items furthest from the cursor.
|
||||||
|
- Styling is clean, minimalist, and customizable via CSS variables.
|
||||||
|
|
||||||
|
This specification allows easy adjustments, maintenance, and future enhancements of the interactive list.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Interactive Hacker Laws Stack</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
margin: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#stack-container {
|
||||||
|
width: 400px;
|
||||||
|
height: 500px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
|
||||||
|
padding: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#stack {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.law-item {
|
||||||
|
text-align: left;
|
||||||
|
padding: 2px 4px;
|
||||||
|
transition: transform 0.2s ease, opacity 0.2s;
|
||||||
|
transform-origin: left;
|
||||||
|
font-size: 15px;
|
||||||
|
color: #333;
|
||||||
|
margin: 4px 0;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.law-item::before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: var(--bar-width, 6px);
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: var(--bar-color, #aaa);
|
||||||
|
margin-right: 10px;
|
||||||
|
transition: width 0.2s, background-color 0.2s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="stack-container">
|
||||||
|
<div id="stack"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const laws = [
|
||||||
|
"90–9–1 Principle (1% Rule)", "90–90 Rule", "Amdahl's Law", "The Broken Windows Theory",
|
||||||
|
"Brooks' Law", "CAP Theorem (Brewer's Theorem)", "Clarke's Three Laws", "Conway's Law",
|
||||||
|
"Cunningham's Law", "Dunbar's Number", "The Dunning-Kruger Effect", "Fitts' Law",
|
||||||
|
"Gall's Law", "Goodhart's Law", "Hanlon's Razor", "Hofstadter's Law", "Hutber's Law",
|
||||||
|
"The Hype Cycle & Amara's Law", "Hyrum's Law (The Law of Implicit Interfaces)",
|
||||||
|
"Metcalfe's Law", "Moore's Law", "Murphy's Law / Sod's Law", "Occam's Razor",
|
||||||
|
"Parkinson's Law", "Premature Optimization Effect", "Putt's Law", "Reed's Law",
|
||||||
|
"The Law of Conservation of Complexity (Tesler's Law)", "The Law of Leaky Abstractions",
|
||||||
|
"The Law of Triviality", "The Unix Philosophy", "The Spotify Model", "Wadler's Law",
|
||||||
|
"Wheaton's Law", "The Dilbert Principle", "The Pareto Principle (The 80/20 Rule)",
|
||||||
|
"The Peter Principle", "The Robustness Principle (Postel's Law)", "SOLID",
|
||||||
|
"The Single Responsibility Principle", "The Open/Closed Principle", "The Liskov Substitution Principle",
|
||||||
|
"The Interface Segregation Principle", "The Dependency Inversion Principle", "The DRY Principle",
|
||||||
|
"The KISS Principle", "YAGNI"
|
||||||
|
];
|
||||||
|
|
||||||
|
const stack = document.getElementById('stack');
|
||||||
|
const stackContainer = document.getElementById('stack-container');
|
||||||
|
const maxZoom = 1.8;
|
||||||
|
const minZoom = 0.5;
|
||||||
|
let offsetY = 0;
|
||||||
|
|
||||||
|
// Create seamless infinite scrolling
|
||||||
|
const extendedLaws = [...laws, ...laws, ...laws];
|
||||||
|
extendedLaws.forEach(title => {
|
||||||
|
const div = document.createElement('div');
|
||||||
|
div.className = 'law-item';
|
||||||
|
div.innerText = title;
|
||||||
|
stack.appendChild(div);
|
||||||
|
});
|
||||||
|
|
||||||
|
const totalHeight = stack.scrollHeight / 3;
|
||||||
|
stack.style.top = `-${totalHeight}px`;
|
||||||
|
offsetY = totalHeight;
|
||||||
|
|
||||||
|
function updateScale(e) {
|
||||||
|
const items = document.querySelectorAll('.law-item');
|
||||||
|
|
||||||
|
items.forEach(item => {
|
||||||
|
const itemRect = item.getBoundingClientRect();
|
||||||
|
const distance = e.clientY ? Math.abs(e.clientY - (itemRect.top + itemRect.bottom) / 2) : 0;
|
||||||
|
const scale = Math.max(maxZoom - distance / 120, minZoom);
|
||||||
|
const opacity = Math.max(1 - distance / 300, 0.3);
|
||||||
|
const barWidth = Math.max(6, 60 - distance / 3);
|
||||||
|
|
||||||
|
item.style.transform = `scale(${scale})`;
|
||||||
|
item.style.opacity = opacity;
|
||||||
|
item.style.setProperty('--bar-width', barWidth + 'px');
|
||||||
|
item.style.setProperty('--bar-color', distance < 50 ? '#333' : '#aaa');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
stackContainer.addEventListener('wheel', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
offsetY += e.deltaY;
|
||||||
|
if (offsetY >= totalHeight * 2) offsetY -= totalHeight;
|
||||||
|
if (offsetY < totalHeight) offsetY += totalHeight;
|
||||||
|
stack.style.top = `-${offsetY}px`;
|
||||||
|
updateScale(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
stackContainer.addEventListener('mousemove', updateScale);
|
||||||
|
|
||||||
|
// Initial scale update
|
||||||
|
updateScale({ clientY: window.innerHeight / 2 });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
@@ -1,32 +1,44 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# This script prepares a `hacker-laws.md` file for export to PDF or e-book format.
|
|
||||||
|
|
||||||
# Require a version number and get the current date.
|
# Fail on errors.
|
||||||
version=$1
|
set -e -o pipefail
|
||||||
date=$(date "+%Y-%m-%d")
|
|
||||||
|
|
||||||
if [ -z "$version" ]; then
|
# Check if parameters are provided
|
||||||
echo "Usage: $0 <version>"
|
input="$1"
|
||||||
|
output="$2"
|
||||||
|
if [ -z "${input}" ] || [ -z "${output}" ]; then
|
||||||
|
echo "usage: $(basename "$0") <input> <output>" >&2
|
||||||
|
echo " input: source markdown file (usually README.md)" >&2
|
||||||
|
echo " output: output markdown file (usually hacker-laws.md)" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create `hacker-laws.md` with frontmatter and README content in one step.
|
# Grab env vars used to configure output, fail if required are missing.
|
||||||
cat << EOF > hacker-laws.md
|
export date="${DATE:-$(date +%F)}"
|
||||||
|
export version="${VERSION?error: VERSION must be set}"
|
||||||
|
|
||||||
|
|
||||||
|
# Update the input file to an intermedate.
|
||||||
|
intermediate="${input}.temp"
|
||||||
|
cat <<EOF > "${intermediate}"
|
||||||
---
|
---
|
||||||
title: "Hacker Laws"
|
title: "Hacker Laws"
|
||||||
author: "Dave Kerr, github.com/dwmkerr/hacker-laws"
|
author: "Dave Kerr, github.com/dwmkerr/hacker-laws"
|
||||||
subtitle: "Laws, Theories, Principles, and Patterns that developers will find useful. ${version}, ${date}."
|
subtitle: "Laws, Theories, Principles, and Patterns that developers will find useful. ${VERSION}, ${DATE}."
|
||||||
|
version: ${VERSION}
|
||||||
---
|
---
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
cat README.md >> hacker-laws.md
|
cat "${input}" >> "${intermediate}"
|
||||||
|
DATE="${date}" VERSION="${version}" envsubst < "${intermediate}" > "${output}"
|
||||||
|
|
||||||
# Use a single `sed` command to clean up unwanted lines and emojis in one pass.
|
# Use a single `sed` command to clean up unwanted lines and emojis in one pass.
|
||||||
sed -i'' -e '/💻📖.*/d' \
|
sed -e '/💻📖.*/d' \
|
||||||
-e 's/❗/Warning/g' \
|
-e 's/❗/Warning/g' \
|
||||||
-e '/^\[Translations.*/d' \
|
-e '/^\[Translations.*/d' \
|
||||||
-e '/\*.*/d' \
|
-e '/\*.*/d' \
|
||||||
-e '/ \*.*/d' \
|
-e '/ \*.*/d' \
|
||||||
-e '/## Translations/,$d' hacker-laws.md
|
-e '/## Translations/,$d' "${output}" > "${intermediate}"
|
||||||
|
mv "${intermediate}" "${output}"
|
||||||
|
|
||||||
echo "hacker-laws.md prepared successfully."
|
echo "${output} prepared successfully."
|
||||||
|
|||||||
Reference in New Issue
Block a user