Skip to content

Commit ee5c19b

Browse files
committed
port old TILs from PC
1 parent ed439f8 commit ee5c19b

File tree

8 files changed

+178
-29
lines changed

8 files changed

+178
-29
lines changed

.vitepress/sidebar.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,10 @@ export const sidebar = [
373373
"text": "Creating Python's next() alternative using Go Closures",
374374
"link": "/go/python-next-alternative-go-clousers"
375375
},
376+
{
377+
"text": "Getting close string matches in Go",
378+
"link": "/go/fuzzy-string-matching-in-golang"
379+
},
376380
{
377381
"text": "Measure Exection time in Go",
378382
"link": "/go/measure-execution-time-in-go"
@@ -428,6 +432,15 @@ export const sidebar = [
428432
}
429433
]
430434
},
435+
{
436+
"text": "Infra",
437+
"items": [
438+
{
439+
"text": "Brief intro to HTTP 3",
440+
"link": "/infra/http3"
441+
}
442+
]
443+
},
431444
{
432445
"text": "Management",
433446
"items": [
@@ -608,6 +621,10 @@ export const sidebar = [
608621
"text": "Generate random secure password using python",
609622
"link": "/python/generating-random-secure-password-python"
610623
},
624+
{
625+
"text": "Make python scripts independent",
626+
"link": "/python/independent-python-scripts"
627+
},
611628
{
612629
"text": "Measure code execution time using timer",
613630
"link": "/python/measure-code-execution-time-python"

README.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,29 +47,29 @@
4747
<td><a href="#git">Git</a><sup>[10]</sup></td>
4848
</tr>
4949
<tr>
50-
<td><a href="#go">Go</a><sup>[17]</sup></td>
50+
<td><a href="#go">Go</a><sup>[18]</sup></td>
5151
<td><a href="#hotwheels">Hotwheels</a><sup>[1]</sup></td>
52-
<td><a href="#management">Management</a><sup>[1]</sup></td>
52+
<td><a href="#infra">Infra</a><sup>[1]</sup></td>
5353
</tr>
5454
<tr>
55+
<td><a href="#management">Management</a><sup>[1]</sup></td>
5556
<td><a href="#meta">Meta</a><sup>[4]</sup></td>
5657
<td><a href="#miscellaneous">Miscellaneous</a><sup>[15]</sup></td>
57-
<td><a href="#people">People</a><sup>[2]</sup></td>
5858
</tr>
5959
<tr>
60+
<td><a href="#people">People</a><sup>[2]</sup></td>
6061
<td><a href="#psychology">Psychology</a><sup>[5]</sup></td>
61-
<td><a href="#python">Python</a><sup>[19]</sup></td>
62-
<td><a href="#sales">Sales</a><sup>[1]</sup></td>
62+
<td><a href="#python">Python</a><sup>[20]</sup></td>
6363
</tr>
6464
<tr>
65+
<td><a href="#sales">Sales</a><sup>[1]</sup></td>
6566
<td><a href="#shell">Shell</a><sup>[30]</sup></td>
6667
<td><a href="#software-design">Software Design</a><sup>[1]</sup></td>
67-
<td><a href="#startups">Startups</a><sup>[1]</sup></td>
6868
</tr>
6969
<tr>
70+
<td><a href="#startups">Startups</a><sup>[1]</sup></td>
7071
<td><a href="#vim">Vim</a><sup>[8]</sup></td>
7172
<td><a href="#webdev">Webdev</a><sup>[5]</sup></td>
72-
<td></td>
7373
</tr>
7474
</tbody>
7575
</table>
@@ -276,6 +276,7 @@
276276
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/go/concurrency-difference-go-vs-elixir.md">Concurrency Comparison: Go v/s Elixir</a></li>
277277
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/go/string-to-int-and-vice-versa.md">Convert `string` to `int` and vice-versa in Go</a></li>
278278
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/go/python-next-alternative-go-clousers.md">Creating Python's next() alternative using Go Closures</a></li>
279+
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/go/fuzzy-string-matching-in-golang.md">Getting close string matches in Go</a></li>
279280
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/go/measure-execution-time-in-go.md">Measure Exection time in Go</a></li>
280281
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/go/writing-performant-go-code-megalist.md">Mega List of Tips for Writing Performant Go Code</a></li>
281282
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/go/memoization-using-golang-generics.md">Memoization using Golang Generics</a></li>
@@ -301,6 +302,15 @@
301302

302303

303304

305+
### Infra
306+
307+
<ul>
308+
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/infra/http3.md">Brief intro to HTTP 3</a></li>
309+
</ul>
310+
311+
312+
313+
304314
### Management
305315

306316
<ul>
@@ -382,6 +392,7 @@
382392
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/python/faster-python-tips-and-tricks.md">Fastest Python First: Tips and Tricks 🏃</a></li>
383393
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/python/functional-programming-in-python.md">Functional Programming in Python 🐍</a></li>
384394
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/python/generating-random-secure-password-python.md">Generate random secure password using python</a></li>
395+
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/python/independent-python-scripts.md">Make python scripts independent</a></li>
385396
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/python/measure-code-execution-time-python.md">Measure code execution time using timer</a></li>
386397
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/python/pep8.md">PEP8 - the fashion 💃 police of Python</a></li>
387398
<li><a target="_blank" href="https://github.com/Bhupesh-V/til/blob/master/python/preventing-global-package-install.md">Preventing global package install with `PIP_REQUIRE_VIRTUALENV`</a></li>

count.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"count": 178
2+
"count": 181
33
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Getting close string matches in Go
2+
3+
A while back I got to know about [`get_close_matches`](https://docs.python.org/3.8/library/difflib.html#difflib.get_close_matches) in Python's `difflib` that works like a fuzzy string match. It returns a list of the best "good enough" close string matches from a list of words.
4+
5+
```python
6+
>>> from difflib import get_close_matches
7+
>>> fruits = ["apple", "orange", "banana", "peach"]
8+
>>> get_close_matches('app', fruits)
9+
['apple']
10+
>>> get_close_matches('aple', fruits)
11+
['apple']
12+
```
13+
14+
This sparked my curiosity to hunt a similar method in Go. Unfortunately there is no direct alternative to this in Go but I was able to put together 2 different ways to do so, let's have a look at them
15+
16+
## The `strings.Index()` approach
17+
18+
Go standard library `strings` offers various method to manipulate strings, once such method is `Index()` which returns the first index of a sub-string match.
19+
20+
```go
21+
func SubstringSearchSimple() {
22+
23+
words := []string{"bhupesh", "varshney", "golang"}
24+
var first_index int
25+
lookup_word := "bhu"
26+
27+
for index := range words {
28+
first_index = strings.Index(words[index], lookup_word)
29+
if first_index != -1 {
30+
break
31+
}
32+
}
33+
fmt.Println(words[first_index])
34+
}
35+
```
36+
37+
## The `suffixarray` approach`
38+
39+
The [`suffixarray`](https://pkg.go.dev/index/suffixarray#pkg-overview) package provides substring search in logarithmic time by building an index over available data.
40+
41+
### What's a suffixarray anyways?
42+
43+
A suffix array is a sorted array of all suffixes of a string.
44+
45+
```go
46+
func SubstringSearchSuffixArray() {
47+
48+
words := []byte("bhupesh varshney golang")
49+
50+
// Create a new suffixarray index.
51+
index := suffixarray.New(words)
52+
53+
// Find exactly 1 instance of this byte slice in the source slice.
54+
lookup_word := index.Lookup([]byte("bhu"), 1)
55+
data := string(words[lookup_word[0]:])
56+
57+
fmt.Println(strings.Split(data, " ")[0])
58+
}
59+
```
60+
61+
## So what's the best/fast way?
62+
63+
I did some rudimentary benchmarking, and it turns out that the suffixarray approach is probably the fastest way to do fuzzy string match in Go. But in comes with a unnecessary overhead over serialising your data in `byte` form, If that's a problem for you, go with the standard strings approach.
64+
65+
66+
## Resources
67+
68+
Some of the stuff I read while writing this blog post
69+
70+
- [Why is []byte used as a string type?](https://www.reddit.com/r/golang/comments/4ologg/why_is_byte_used_as_a_string_type/)
71+
- [Demystifying Bytes, Runes, and Strings in Go](https://levelup.gitconnected.com/demystifying-bytes-runes-and-strings-in-go-1f94df215615)
72+
- [Suffix arrays in the Go standard library](https://eli.thegreenplace.net/2016/suffix-arrays-in-the-go-standard-library/)

index.md

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,29 +34,29 @@
3434
<td><a href="#git">Git</a><sup>[10]</sup></td>
3535
</tr>
3636
<tr>
37-
<td><a href="#go">Go</a><sup>[17]</sup></td>
37+
<td><a href="#go">Go</a><sup>[18]</sup></td>
3838
<td><a href="#hotwheels">Hotwheels</a><sup>[1]</sup></td>
39-
<td><a href="#management">Management</a><sup>[1]</sup></td>
39+
<td><a href="#infra">Infra</a><sup>[1]</sup></td>
4040
</tr>
4141
<tr>
42+
<td><a href="#management">Management</a><sup>[1]</sup></td>
4243
<td><a href="#meta">Meta</a><sup>[4]</sup></td>
4344
<td><a href="#miscellaneous">Miscellaneous</a><sup>[15]</sup></td>
44-
<td><a href="#people">People</a><sup>[2]</sup></td>
4545
</tr>
4646
<tr>
47+
<td><a href="#people">People</a><sup>[2]</sup></td>
4748
<td><a href="#psychology">Psychology</a><sup>[5]</sup></td>
48-
<td><a href="#python">Python</a><sup>[19]</sup></td>
49-
<td><a href="#sales">Sales</a><sup>[1]</sup></td>
49+
<td><a href="#python">Python</a><sup>[20]</sup></td>
5050
</tr>
5151
<tr>
52+
<td><a href="#sales">Sales</a><sup>[1]</sup></td>
5253
<td><a href="#shell">Shell</a><sup>[30]</sup></td>
5354
<td><a href="#software-design">Software Design</a><sup>[1]</sup></td>
54-
<td><a href="#startups">Startups</a><sup>[1]</sup></td>
5555
</tr>
5656
<tr>
57+
<td><a href="#startups">Startups</a><sup>[1]</sup></td>
5758
<td><a href="#vim">Vim</a><sup>[8]</sup></td>
5859
<td><a href="#webdev">Webdev</a><sup>[5]</sup></td>
59-
<td></td>
6060
</tr>
6161
</tbody>
6262
</table>
@@ -67,6 +67,12 @@
6767
<table align="center">
6868
<tbody>
6969
<tr>
70+
<td><a href="https://til.bhupesh.me/citizen/property">Accquiring properties in India</a></td>
71+
</tr>
72+
<tr>
73+
<td><a href="https://til.bhupesh.me/meta/creative-writing">Creative Writing</a></td>
74+
</tr>
75+
<tr>
7076
<td><a href="https://til.bhupesh.me/citizen/scam-spam">Figthing Scams</a></td>
7177
</tr>
7278
<tr>
@@ -90,12 +96,6 @@
9096
<tr>
9197
<td><a href="https://til.bhupesh.me/go/writing-benchmarks">Writing benchmarks for Go apps</a></td>
9298
</tr>
93-
<tr>
94-
<td><a href="https://til.bhupesh.me/psychology/unconsious-thought-theory">Unconscious Thought Theory</a></td>
95-
</tr>
96-
<tr>
97-
<td><a href="https://til.bhupesh.me/databases/oath-for-3-normal-forms">The 3NF Oath ✋🏼</a></td>
98-
</tr>
9999
</tbody>
100100
</table>
101101

@@ -301,6 +301,7 @@
301301
<li><a href="/go/concurrency-difference-go-vs-elixir">Concurrency Comparison: Go v/s Elixir</a></li>
302302
<li><a href="/go/string-to-int-and-vice-versa">Convert `string` to `int` and vice-versa in Go</a></li>
303303
<li><a href="/go/python-next-alternative-go-clousers">Creating Python's next() alternative using Go Closures</a></li>
304+
<li><a href="/go/fuzzy-string-matching-in-golang">Getting close string matches in Go</a></li>
304305
<li><a href="/go/measure-execution-time-in-go">Measure Exection time in Go</a></li>
305306
<li><a href="/go/writing-performant-go-code-megalist">Mega List of Tips for Writing Performant Go Code</a></li>
306307
<li><a href="/go/memoization-using-golang-generics">Memoization using Golang Generics</a></li>
@@ -326,6 +327,15 @@
326327

327328

328329

330+
### Infra
331+
332+
<ul>
333+
<li><a href="/infra/http3">Brief intro to HTTP 3</a></li>
334+
</ul>
335+
336+
337+
338+
329339
### Management
330340

331341
<ul>
@@ -407,6 +417,7 @@
407417
<li><a href="/python/faster-python-tips-and-tricks">Fastest Python First: Tips and Tricks 🏃</a></li>
408418
<li><a href="/python/functional-programming-in-python">Functional Programming in Python 🐍</a></li>
409419
<li><a href="/python/generating-random-secure-password-python">Generate random secure password using python</a></li>
420+
<li><a href="/python/independent-python-scripts">Make python scripts independent</a></li>
410421
<li><a href="/python/measure-code-execution-time-python">Measure code execution time using timer</a></li>
411422
<li><a href="/python/pep8">PEP8 - the fashion 💃 police of Python</a></li>
412423
<li><a href="/python/preventing-global-package-install">Preventing global package install with `PIP_REQUIRE_VIRTUALENV`</a></li>

infra/http3.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Brief intro to HTTP 3
2+
3+
## HTTP/1.1
4+
- Many parallel TCP connections
5+
- Ineffective TCP use
6+
- HTTP head-of-line blocking: finite set of connections, where to put request from a pool of connection
7+
8+
## HTTP/2
9+
- use single connection per host
10+
- Parallel streams.
11+
- TCP head-of-line blocking
12+
13+
## Google QUIC
14+
- Google deployed http2 frames over UDP in 2013
15+
16+
## IETF QUIC
17+
- Faster handshakes
18+
- Earlier data
19+
- Connection-id
20+
- Built on top of UDP instead of IP.
21+
- Its a transport protocol, means different types of application protocols can be built on top of it. One example is HTTP3.
22+
- HTTP3 is built on top of UDP instead of TCP
23+
- QUIC looks like a DDoS Attack.
24+
- High CPU usage (x2)
25+
26+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Make python scripts independent
2+
3+
List of ideas
4+
5+
1. Self-updating python script (also: https://docs.python.org/3/library/os.html#os.execv)
6+
2. Automatically installing dependencies
7+
3. Graciously handling Keyboard Interrupts
8+
4. Running scripts as processes
9+
5. Parsing configs(https://docs.python.org/3/library/configparser.html)
10+
6. Handling Sensitive data using hashes
11+
- https://docs.python.org/3/library/hashlib.html#key-derivation
12+
- https://stackoverflow.com/a/56915300/8209510

recent_tils.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
[
2+
{
3+
"title": "Accquiring properties in India",
4+
"url": "https://til.bhupesh.me/citizen/property"
5+
},
6+
{
7+
"title": "Creative Writing",
8+
"url": "https://til.bhupesh.me/meta/creative-writing"
9+
},
210
{
311
"title": "Figthing Scams",
412
"url": "https://til.bhupesh.me/citizen/scam-spam"
@@ -30,13 +38,5 @@
3038
{
3139
"title": "Writing benchmarks for Go apps",
3240
"url": "https://til.bhupesh.me/go/writing-benchmarks"
33-
},
34-
{
35-
"title": "Unconscious Thought Theory",
36-
"url": "https://til.bhupesh.me/psychology/unconsious-thought-theory"
37-
},
38-
{
39-
"title": "The 3NF Oath ✋🏼",
40-
"url": "https://til.bhupesh.me/databases/oath-for-3-normal-forms"
4141
}
4242
]

0 commit comments

Comments
 (0)