30 Day Blogging Streak

Yesterday I completed a 30 day blogging streak on this blog. While this is no big deal, it is pretty cool because I could keep up with my goal of writing something everyday and making it a habit.

The idea was to show up each day and write something useful. As mentioned in the first blog post on this blog, I did my best to avoid perfection paralysis. I did so by writing each day and pushing posts out even if they weren’t good enough.

I could do so much better by using screenshots and creating cool illustrations but instead of doing all that, I just pushed those out as soon as possible, without trying to make them perfect.

They’re not great but also not terrible. I said to myself, as long as the output isn’t bad, I’ll publish it. This made me achieve a 30 day blogging streak, something I failed to do since 2012 (past 7 years).

Next

Note: When I started, I didn’t exactly plan on publishing a post every day. I know that isn’t a sustainable long term goal. I actually thought of writing for 10 minutes each day (something that I can do long term with or without my laptop or an internet connection).

I’ll continue to try and push posts out as soon as possible but I know there will be days where I won’t be able to keep up. On those days, I’ll fall back to the goal of “write something 10 minutes a day”.

If I don’t have 10 minutes, I’ll get it down to 5 minute and then 1 minute. The idea is to produce something, even if that means writing just one line or one word.

Ok! With that said, I don’t wish to slack off today. Here’s a bonus “useful” thing that I’d like to add to this post –

Bonus

You can check for open ports for a site by using the nmap tool in terminal. For example: nmap csmumbai.com will return the following result –

Omkars-iMac:~ omkarbhagat$ nmap csmumbai.com

Starting Nmap 7.80 ( https://nmap.org ) at 2020-01-21 12:09 IST
Nmap scan report for csmumbai.com (192.0.78.25)

Host is up (0.047s latency).
Other addresses for csmumbai.com (not scanned): 192.0.78.24
Not shown: 998 filtered ports

PORT    STATE SERVICE
80/tcp  open  http
443/tcp open  https

Nmap done: 1 IP address (1 host up) scanned in 23.37 seconds

If nmap isn’t installed on your computer, you can get it from https://nmap.org/download.html. If you’re on a Mac and have Xcode installed, I believe nmap should come with it.

That’s all in this post. Thanks for reading! 🙂

WP: Install WordPress Locally

There are different ways to install WordPress locally. Some of the popular ways are listed below. WordPress can be installed locally via –

  • MAMP (Mac, Apache, MysQL, PHP)
  • WAMP (Windows, Apache, MySQL, PHP)
  • XAMP (Cross-platform, Apache, MariaDB, PHP, Perl)
  • VVV (Varying Vagrant Vagrants)

Tutorials for the same can be found on their official sites or around the web (Google it). In this post, I’ll just cover one of the ways to install WordPress (which is by using MAMP).

For this, you’ll need to download MAMP and WordPress on your Mac computer. Next, install MAMP and run it.

Create a folder in your home folder, say wpdev and extract WordPress in there. Here’s how it will appear –

Next, open MAMP preferences, goto General tab and change the document root to the new folder we created, which is wp-dev.

Next, start all servers in MAMP (from the front/main screen which you see when you open MAMP).

This will open http://localhost:8888/MAMP/ in your web-browser. If it doesn’t, you can open it manually.

Next go to tools > phpMyAdmin > Databases. Enter a database name, say testdb1 and hit the create button.

Finally go to http://localhost:8888/wordpress/ where you will see a page to start installing WordPress. Go through the setup and enter the following database details when asked:

Once done, you’ll be asked for site details like site title, admin username/pass, etc. With that your WordPress installation will be complete.

Finally, you can access your site’s wp-admin dashboard at http://localhost:8888/wordpress/wp-admin/

That’s all! You have successfully installed WordPress on your local machine.

Python: Find Nth Last Node In A Linked List

The goal is to find Nth last node in a given linked list. This can be done by using an imaginary stick.

A stick can be imagined in code by using left and right pointers.

# Problem: Getting Nth to last node in LinkedList
# Logic: Use a stick with two pointers

def find_nth_node(n, node):
    
    left_pointer = node
    right_pointer = node
    
    for i in range(n):
        
        if right_pointer:
            right_pointer = right_pointer.next
        
    # right_pointer is now n nodes ahead
    
    while right_pointer:
        left_pointer = left_pointer.next
        right_pointer = right_pointer.next
        
    return left_pointer

# Testing the result

a = Node(1) #0 -- default right_pointer value
b = Node(2) #1 -- first iteration
c = Node(3) #2 -- second iteration - right_pointer gets here after being n nodes ahead
d = Node(4) #3
e = Node(5) #4

a.next = b
b.next = c
c.next = d
d.next = e

find_nth_node(2, a).value # second last node's val is 4

The first for loop in the code brings our right_pointer in position (n steps ahead of left_pointer), thus creating our imaginary stick.

Once that’s in place, we are ready to find the Nth last node.

The second for loop keeps moving the left_pointer and the right_pointer to the next node as long as the right_pointer points to some node. It stops once it points to Null or None (which is at the end of the Linked List).

The above can be imagined as our stick moving across the given Linked List with left_pointer and right_pointer moving to the right one step (one node) at a time.

Once the second for loop stops, the right_pointer will point to None (the end of the Linked List). Since the length of the stick is N, we can safely say our left_pointer is now pointing at Nth last node.

Therefore printing the value of the node pointed by the left_pointer gives us the value of Nth last node.

In the example given above, the Nth last node (the second last node) is 4.

A Good Bad Password

Disclaimer: This is not the ideal way to generate a password. The best way to generate a good and strong password is by using password manager apps. Read more about this in my previous post here.

This is an OKAY way to quickly generate a memorable password and can be used for less serious online accounts or throwaway online accounts that are in no way connected to your other important accounts like Gmail, Facebook, etc.

I don’t recommend this but it is much better than using “test”, “root”, “admin” or “pass123” type of passwords.

Ok! Now that I have clarified what this is about, let’s look at how to generate a good bad password.

The Good Bad Formula

I suggest the following quick and dirty formula to generate a password/passcode:

capital_letter + first_three_char_of_service_name + symbol + numbers

For example, if I had to generate a password for a throwaway reddit account using the formula above, it would be:

  • Capital Letter: O
  • First three characters of a service name: red
  • A symbol: #
  • Numbers: 892

The result: Ored#892

I’d always remember this password because I could always generate it just by looking at the service name (which is reddit in this case).

Again, I don’t recommend this for all your passwords. For serious, sensitive and important stuff, please use a password generator app and follow the security measures listed in my previous post.

Security 101: Passwords

Using a strong password is the first step in keeping your internet account secure. But how strong it needs to be? how to generate it? how to remember it? where to store it? how to store it? should you store it anywhere at all? Let’s answer these questions in this post.

Unique Passwords

First of all, never use the same password in two different places or services. Why? because if one of them is compromised, you will lose control of everything else.

For example: If you use the same password for your Google and Facebook account and if one of them is hacked, there’s a good chance for the hacker to get into your other account.

Choose a unique password for each service and store it some place safe (not your memory). More about it later in this post.

No Repeat Passwords

Have you ever tried resetting the password to your bank account? If so you must’ve noticed they don’t let you use the same password which you’ve used in the past. This is a security measure.

Never use repeat passwords. Always generate new ones!

Password Strength

A strong password is a mix of alphabets, numbers, symbols and usually has a length of more than 8 characters in total (more is better). It doesn’t have any “word” or “phrase” and is hard to guess. For example: kjUld3%6

You may be wondering how to create or generate such a password. Also, you may have noticed that I’ve used the word “generate” multiple times in this post. That’s because I recommend that you generate a password using a password manager app. More on that in the next section.

Generating Passwords

I recommend using a password manager app like 1Password or LastPass. I personally use 1Password but feel free to use any, they all mostly have the same features.

They’re paid apps but if you care about the security of your internet accounts, investing in a good password manager app is the right thing to do.

1Password – Password Generation Screen

The screenshot above illustrates what the password generation screen looks like in an app like 1Password. You can see it gives you an option to customize your password by choosing its length, symbols, numbers, etc.

Storing Passwords

Again, a password manager app will do this job for you. The only thing you’ll need to remember is a master password to the password manager app. Once that’s entered, you can access all your account credentials (usernames & passwords).

You may wonder how is this secure? Especially because all your accounts will be at stake if your master password is compromised.

You’re right but it there’s an added layer of security using something called a secret key. If you’d like to read more about how that works, please checkout this good article on 1Password’s official blog.

Conclusion

To conclude: Please always use a password manager app if you can afford one. It is a small investment and will help to stay secure.

Don’t use repeat passwords, don’t use words or phrases in your password, don’t write it down on a physical piece of paper, don’t share it with anyone (not even with your s/o unless absolutely necessary).

Do use unique passwords. Do use letters, numbersm, symbols in your password. Do change your password every 6 months or a year if you can. Do use two step verification (also called 2FA – Two Factor Authentication). Do log out after you are done, especially if you are using a public computer.

Most password manager apps have an option to add 2FA code. If yours has one, I recommend using that over other “Authenticator” apps. Why? because you can get your 2FA code via the desktop/mobile app even if you don’t have access to your mobile phone.

That’s all in this post. I plan to write more on this subject in the future but for now I think I have covered enough to get you started with online security.

Python: Linked List Cycle Check

Today let’s look at a python program that will help us check whether there’s a cycle in a given linked list.

Source: LeetCode.com

The above example illustrates a cycle in Linked List. The best way to check whether it has a cycle is to have two markers (or runners).

The first runner takes one step at a time. The second one takes two steps at a time. With this setup, if there is a cycle, both runners will come to the same place eventually.

You can imagine this happening for runners running around a lake with one person running slow and the other one running fast. The faster runner will eventually complete a round and pass by the slower runner. If this happens, we know there is a cycle.

The code below does exactly that by using two markers.

# Problem: Finding cycle in linked list
# Logic: Maintain two markers, one that moves 2 steps faster
# If markers meet at the end, there's a cycle

def cycle_check(node):
    
    marker1 = node
    marker2 = node
    
    while marker2 != None and marker2.next != None:
        
        marker1 = marker1.next
        marker2 = marker2.next.next
        
        if marker2 == marker1:
            return True
        
    return False

# Testing the result

a = Node(1)
b = Node(2)
c = Node(3)
d = Node(4)

a.next = b
b.next = c
c.next = d
d.next = c

cycle_check(a)

Since we’re making marker2 take two steps at a time, we want to run the while loop till marker2’s current value and its next value doesn’t equal to None. If it is, we stop and return False.

Python: Bracket Validator

Today let’s look at a bracket validator program. This will accept an input string that contains a bunch of brackets. It’ll check whether they are correctly opened and closed (in the right order).

The examples below will give a better idea of valid and invalid inputs:

s1 = ['(((}})))']
bracket_validator(s1) # returns False

s2 = '[](([[{{}}]]))'
bracket_validator(s2) # returns True

Now let’s have a look at the code:

# Problem: Bracket validator (balanced vs unbalanced) (using Stack)

def bracket_validator(s):
    
    if len(s)%2 != 0:
        return False
    
    openers_to_closers = {
        '(' : ')',
        '{' : '}',
        '[' : ']'
    }
    
    openers = openers_to_closers.keys()
    closers = openers_to_closers.values()
    
    openers_stack = []
    
    for char in s:
        
        if char in openers:
            openers_stack.append(char)
        elif char in closers:
            if not openers_stack:
                return False
            else:
                last_unclosed_opener = openers_stack.pop()
                if openers_to_closers[last_unclosed_opener] != char:
                    return False
    
    if len(openers_stack) == 0:
        return True
        

s1 = ['(((}})))']
bracket_validator(s1) # returns False

s2 = '[](([[{{}}]]))'
bracket_validator(s2) # returns True

The very first thing we do is check the input is odd or even in length. If it is odd, return False.

Next we maintain a dictionary of openers to closers and turn those into sets of openers and closers. We also maintain a openers_stack as a list.

We then run a for loop going through each character in the input string. If the character is in opener, add it to the openers stack.

If we find a closer and openers stack doesn’t is empty, return False. If openers stack is not empty, pop the top element from the openers stack and check whether our current closer is the correct closing pair for the top element in the stack (last unclosed opener).

For example, if our closer is ] and the last unclosed opener is [ then we’re good. If not, we return False.

At the very end if length of openers_stack is zero, return True.

Python: String Compression

The idea of string compression is as follows: AAAB > A3B1. That is, if we’re given 3 A’s and 1 B, the output should be A3B1.

If we go by this logic, for input of AAABaaaaAA, we should get A5B1a4. This can be achieved by the code given below:

# string compression problem
# AAAB > A3B1

def compress_string(s):
    
    temp = {}
    for letter in s:
        if letter in temp:
            temp[letter] += 1
        else:
            temp[letter] = 1
            
    compressed_string = ''
    
    for letter in temp:
        compressed_string += letter + str(temp[letter])
        
    return compressed_string

compress_string('AAABaaaaAA') #Output: A5B1a4

The code starts with a temp dictionary. It then looks at each letter in the input string and counts it using temp.

Next it simply concatenates letter (the actual character) and str(temp[letter]) (the count of that character) in a variable called compressed_String and prints it.

Python: Sentence Reversal

In the previous post I wrote about reversing a word or an input string. In this one, let’s look at reversing a sentence. For example: “landed has Eagle The” should become “The Eagle has landed”.

To achieve this we’re going to build on top of the string reversal code from the previous post.

def reverse_word(word):
    
    letters = list(word)
    start = 0
    end = len(letters)-1
    
    while start < end:
        letters[start], letters[end] = letters[end], letters[start]
        start+=1
        end-=1
        
    return ''.join(letters)

def reverse_sentence(words):
    
    # reverse the whole string -- # O(n)
    words = reverse_word(words) 
    
    # convert string to a list
    temp = words.split(' ')
    
    # reverse each word in that list -- # O(n)
    for i in range(len(temp)):
        temp[i] = reverse_word(temp[i]) 
        
    # the above loop is O(n) 
    # because we only go through every letter once
        
    # convert list to a string and return it
    return ' '.join(temp)
    
reverse_sentence('landed has Eagle The') #Output: The Eagle has landed

In the code above, we accept an input string, use the string reversal function to reverse it. This gets us ehT elgaE sah dednal as the output and we store it in temp by splitting it at spaces.

The next step is to use string reversal code again but this time we use it for each word and that gets us our intended output, which is: The Eagle has landed.

Python: String Reversal

Today I’m sharing a simple python program that accepts an input string and reverses it.

def reverse_word(word):
    
    letters = list(word)
    start = 0
    end = len(letters)-1
    
    while start < end:
        letters[start], letters[end] = letters[end], letters[start]
        start+=1
        end-=1
        
    return ''.join(letters)

reverse_word('Nice work') #output: krow eciN

The program starts by accepting a string word, converts it to a list type in letters, sets the start to 0 and end index to length of the input string minus one.

Next a while loop runs from while start and end pointers don’t cross each other. In each iteration, we swap the characters at start and end index and also increment and decrement the start and end pointers respectively.

The end result gets us a reversed version of input string. For example: “Nice work” gets turned into “krow eciN”.

In one of the next posts I’ll write about “sentence” reversal. For example: “Nice work” will be turned into “work Nice”.