-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add existing blogs from current website
Signed-off-by: Aaqa Ishtyaq <[email protected]>
- Loading branch information
1 parent
7a986f1
commit 8b1a095
Showing
13 changed files
with
2,141 additions
and
3 deletions.
There are no files selected for viewing
147 changes: 147 additions & 0 deletions
147
content/notes/2018-01-08-algorithms-in-python-bubble-sort.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
+++ | ||
title = "Algorithms in Python: Bubble Sort" | ||
date = "2018-01-08" | ||
+++ | ||
|
||
## Some theory | ||
|
||
Bubble sort is another commonly known sorting algorithm. The idea here is to | ||
scan a list of items (say integers) sequentially (from left to right) and | ||
compare consecutive pairs of elements starting at index 0. | ||
|
||
Example: | ||
```python | ||
|
||
my_numbers = [92,11,45,2234,0,7,65] | ||
# 92 is index 0 and the consecutive pairs are | ||
# (92,11), (11,45), (45,2234) and so on ... | ||
``` | ||
At first we compare elements (list[0],list[1]) then (list[1],list[2]) then | ||
(list[2],list[3]) and so on until the end of the list is reached. | ||
|
||
When comparing we check if element i is greater than element i + 1, if they are | ||
we just swap the two elements and move on to the next pair. If they are not this | ||
means that the pair is already sorted, so we also move on to the next pair. | ||
|
||
Example: | ||
```python | ||
my_numbers = [92,11,45,2234,0,7,65] | ||
|
||
# Let's compare my_numbers[0] and my_numbers[1] | ||
if my_numbers[0] > my_numbers[1]: | ||
swap(my_numbers[0], my_numbers[1]) | ||
|
||
print(my_numbers) # [11, 92, 45, 2234, 0, 7, 65] | ||
``` | ||
|
||
This process has to be repeated for however many items are on the list. So if | ||
the list holds 9 items, it means we need to loop through it 9 times at most. | ||
But what if our original list is partially sorted? We might not need 9 passes | ||
through the list. | ||
|
||
One way for us to know that the list is fully sorted is if we have made no | ||
swaps during our pass. For that, we need a variable to keep track of how many | ||
swaps were made during a pass. | ||
|
||
Example: | ||
```python | ||
my_numbers = [92,11,45,2234,0,7,65] | ||
|
||
# Elements (0,1) are compared and swapped. List is now 11,92,45,2234,0,7,65 | ||
# Elements (1,2) are compared and swapped. List now 11,45,92,2234,0,7,65 | ||
# Elements (2,3) are compared and not swapped. List remains the same. | ||
# Elements (3,4) are compared and swapped. List is now 11,45,92,0,2234,0,7,65 | ||
# Elements (4,5) are compared and swapped. List is now 11,45,92,0,7,2234,65 | ||
# Elements (5,6) are compared and swapped. List is now 11,45,92,0,7,65,2234 | ||
|
||
# This represents one unique pass through the list. | ||
``` | ||
|
||
Notice how after each pass the highest value number is pushed at len(list) - 1. | ||
|
||
## Some code | ||
|
||
Let's look at how to implement Bubble Sort using Python: | ||
|
||
```python | ||
def bubble_sort(some_list): | ||
|
||
is_sorted = False | ||
|
||
while not is_sorted: | ||
|
||
is_sorted = True | ||
|
||
for i in range(0, len(some_list) - 1): | ||
|
||
if some_list[i] > some_list[i + 1]: | ||
|
||
some_list[i], some_list[i+1] = some_list[i+1], some_list[i] | ||
is_sorted = False | ||
``` | ||
This works right and it will sort any list you throw at it. However we can | ||
slightly optimise it: We know that, after each pass the highest value element is | ||
guaranteed to be sorted and placed at len(some\_list) - 1. Because of this, for | ||
each subsequent pass, we can stop comparing the last sorted item. instead of | ||
comparing pairs that we know are already sorted. | ||
This is what it looks like: | ||
|
||
```python | ||
def bubble_sort(some_list): | ||
|
||
is_sorted = False | ||
last_sorted_item = len(some_list) - 1 | ||
|
||
while not is_sorted: | ||
|
||
is_sorted = True | ||
|
||
for i in range(0, last_sorted_item): | ||
|
||
if some_list[i] > some_list[i + 1]: | ||
|
||
some_list[i], some_list[i+1] = some_list[i+1], some_list[i] | ||
is_sorted = False | ||
|
||
last_sorted_item -= 1 | ||
``` | ||
|
||
After each pass through the loop, we know the right side of the list is sorted | ||
so we decrement the value of last\_sorted\_item. What this means is that the 1st | ||
pass will loop from 0 to len(some\_list) -1, the second time, it will be from 0 | ||
to len(some\_list) - 2 and so on ... | ||
|
||
## Time complexity | ||
|
||
The rate of growth of this algorithm is quadratic. Expressed as O(n^2) in | ||
"big-oh" notation. | ||
|
||
```python | ||
def bubble_sort(some_list): | ||
|
||
is_sorted = False # time here is constant | ||
last_sorted_item = len(some_list) - 1 | ||
|
||
while not is_sorted: # We go through this first loop n times | ||
|
||
is_sorted = True | ||
|
||
for i in range(0, last_sorted_item): # we go through this loop n-1 times | ||
|
||
if some_list[i] > some_list[i + 1]: | ||
|
||
# execution here is constant | ||
some_list[i], some_list[i+1] = some_list[i+1], some_list[i] | ||
is_sorted = False | ||
|
||
last_sorted_item -= 1 # constant time | ||
``` | ||
|
||
It's O(n^2) because, for each pass through the loop n times, we loop n times | ||
through the consecutive pairs. It's not a very efficient algorithm when used on large samples of data. It should only be used if you have a | ||
specific case on a small data set. | ||
|
||
Next in the series is QuickSort, another interesting and more efficient sorting | ||
algorithm. As always, if you have questions, comments or if you spotted a typo | ||
or a mistake, please feel free to let me know on Twitter, I'm | ||
[@aaqaishtyaq](https://twitter.com/zabanaa) and always happy to help! |
100 changes: 100 additions & 0 deletions
100
content/notes/2018-01-18-algorithms-in-python-quick-sort.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
+++ | ||
title = "Algorithms in Python: Quick Sort" | ||
date = "2018-01-08" | ||
+++ | ||
|
||
## Theory | ||
|
||
Quicksort is a "divide and conquer" type of algorithm. The good thing about | ||
it is that the worst case can almost always be avoided by using what is called a | ||
randomized version of quicksort (more on that later). | ||
|
||
The idea of Quicksort is to take an unsorted list and select an element (on that | ||
list) called a "pivot". Then the list is rearranged such that all elements greater | ||
(in value) than the pivot are placed to its right, and all elements lesser (in | ||
value) are placed to its left. | ||
|
||
This process is called partitioning. At this stage in the execution of the | ||
algorithm, the order of the elements doesn't matter so long as the | ||
lesser/bigger values are placed on the correct side of the pivot. | ||
|
||
Partitioning will produce two sublists with the pivot as a separator ( | ||
this is because the pivot will be at its natural place after the first pass aka | ||
sorted). The problem then becomes sorting these two sublists. | ||
|
||
*Note: Partitioning does not require creating copies of the | ||
list, we work on it directly as long as we keep track of the start and end | ||
indices of each sublist.* | ||
|
||
To sort the two sublists, we can apply the same logic as above (choosing a | ||
pivot, and sorting the two resulting sublists) because QuickSort is a recursive | ||
algorithm. | ||
|
||
When a sublist only contains a single element, it's already sorted so we can | ||
stop the recursion at this point, it's our exit condition. | ||
|
||
**Note on choosing a pivot** | ||
|
||
Some people use the last item of the list, and some people use the median of the | ||
first, last, and medium elements but the most common way is to choose a random | ||
pivot to ensure `n log n` execution. | ||
|
||
## Some Code | ||
|
||
```python | ||
def swap_values(lst, val1, val2): | ||
lst[val1], lst[val2] = lst[val2], lst[val1] | ||
|
||
def quicksort(array, start, end): | ||
|
||
if start < end: | ||
|
||
partition_index = partition(array, start, end) # | ||
quicksort(array, start, partition_index - 1) | ||
quicksort(array, partition_index + 1, end) | ||
|
||
def partition(array, start, end): | ||
|
||
pivot = end | ||
partition_index = start | ||
|
||
for i in range(start, end): | ||
|
||
if array[i] < array[pivot]: | ||
print("{} is less than {}".format(array[i], array[pivot])) | ||
swap_values(array, partition_index, i) | ||
partition_index += 1 | ||
|
||
array[pivot], array[partition_index] = array[partition_index], array[pivot] | ||
return partition_index | ||
``` | ||
|
||
A randomized version of Quicksort would look similar to what's above except that | ||
we must randomize the selection of our pivot. | ||
|
||
```python | ||
import random | ||
# ... | ||
def partition(array, start, end): | ||
if start < end: | ||
pivot = random.randint(start, end) | ||
array[end], array[pivot] = array[pivot], array[end] | ||
partition_index(array, start, end) | ||
# ... | ||
``` | ||
Here, we set the pivot to a random integer in the range between `start` | ||
and `end`. Then, we swap the value at that index with the value at array[end]. | ||
If you run the code successively, you'll notice that the pivot is | ||
different every time. It's a nice optimization that can save some time. | ||
|
||
## Time Complexity | ||
|
||
It's one of the most efficient sorting algorithm. In fact, most sorting | ||
functions that come packaged in many language's standard libraries use an | ||
implementation of QuickSort. | ||
|
||
The order of growth for QuickSort in the worst case is quadratic O(n^2). The | ||
average case, however, which is the most common scenario, has a complexity of | ||
O(n log n). | ||
|
||
QuickSort works best when used on large sets of data because of its recursive nature. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
+++ | ||
title = "Don't be scared. Switch to vim." | ||
date = "2018-02-03" | ||
+++ | ||
|
||
I'm currently sitting at the most boring meetup I've probably ever attended in | ||
Delhi. It's about chatbots. I don't care about chatbots, I care about free | ||
stickers and pizza. So I'll take this opportunity to open up about a subject | ||
that's dear to my heart: vim. | ||
|
||
I used to believe vim was exclusive to this superior race of developers who | ||
gulp coffee like it's water and seem to only read HN and nothing else. (Hi, if | ||
you're coming from HN). Architecture and Software design comes naturally to them, | ||
they never run into bugs and they can recognize the most obscure of algorithms | ||
at a glance (Shout out to Shashank, one of my mentors). | ||
|
||
Shanky is a good, productive developer. Shany uses vim. I want to be like Shanky. I want | ||
to use vim. | ||
|
||
There are a million reasons why you should jump ship and join the cult. In the | ||
next paragraphs, I will detail some of these reasons. | ||
|
||
## It's not (that) hard | ||
|
||
There's a learning curve to vim. But it's worth the | ||
trouble. And if you're on Linux or MacOS, there's a built-in tool called | ||
`vimtutor` (just fire it up from a terminal, I am not sure about Windows though) and | ||
a wide variety of online tools to learn vim. Namely [openvim][0], | ||
[vim adventures][1], and [vim genius][2]. | ||
|
||
Personally, The way I learned was by using it on small, fun side projects of | ||
mine during the weekends, mostly to become familiar with the new mental model. | ||
And just like everything in life, shit takes time, and practice makes perfect. | ||
So keep at it and you'll eventually come to your "aha" moment. | ||
As you get more and more comfortable using vim, it will become harder and harder | ||
to go back to a regular editor / IDE. | ||
|
||
## It's Fast and Customisable | ||
|
||
Because it runs on the terminal, you'll never have to wait 20 seconds to get | ||
on with your work. (Atom anyone ?) | ||
|
||
And if you like pretty things, there's a [large selection of colorschemes][11] | ||
for you to choose from. On top of that, there's a plugin for just about anything | ||
you might need. And if there isn't, you can program your own. | ||
|
||
## Ubiquity | ||
|
||
Not really, but I wanted to place a complicated word to sound smart. | ||
Seriously though, it's everywhere. On Mac OS, Windows and of course Linux/Unix. If | ||
you work on remote servers you can quickly edit files on the fly without having | ||
to use nano. (Don't use nano) | ||
|
||
Say for example a coworker/friend is running into a bug, you come to help and | ||
they're using an IDE you're not familiar with, well you can just access the files | ||
from their terminal and start debugging right away. | ||
|
||
Or if you're like me, and you spill water on your Macbook keyboard and it becomes | ||
toast, you can spin up a VPS on Digital Ocean or AWS, and pick up where you | ||
left off (almost) right away. | ||
|
||
## Bonus: Some of my favorite plugins | ||
|
||
My color scheme of choice (at the time of writing) is [afterglow][10]. | ||
|
||
And here's a list of my favorite plugins: | ||
|
||
|
||
- [ Nerdtree ][3] (A tree explorer much like the sidebar in traditional IDEs) | ||
- [ Airline ][4] (A sleek, customizable status bar) | ||
- [ Surround ][5] (Helpful tool that helps with "surrounding" words with brackets etc) | ||
- [ CtrlP ][6] (A fuzzy finder for vim) | ||
- [ UtilSnips ][7] (Snippet utility for many languages) | ||
- [ Vim Markdown][8] (Markdown syntax highlighting) | ||
- [ Goyo ][9] (Allows for distraction-free editing) | ||
|
||
I'll end this article with a quote from a Chamillionaire: | ||
> They see you vimmin', they hatin'. Patroling they tryna catch me coding dirty | ||
[0]: http://www.openvim.com/ | ||
[1]: https://vim-adventures.com/ | ||
[2]: http://www.vimgenius.com/ | ||
[3]: https://github.com/scrooloose/nerdtree | ||
[4]: https://github.com/vim-airline/vim-airline | ||
[5]: https://github.com/tpope/vim-surround | ||
[6]: https://github.com/kien/ctrlp.vim | ||
[7]: https://github.com/SirVer/ultisnips | ||
[8]: https://github.com/plasticboy/vim-markdown | ||
[9]: https://github.com/junegunn/goyo.vim | ||
[10]: https://github.com/danilo-augusto/vim-afterglow | ||
[11]: http://vimcolors.com/ | ||
|
||
|
Oops, something went wrong.