Blog
Turkish Eggs!
Probably one of my favourite way to make eggs, which I stole from my partner. If anyone ever tries eggs it should be this recipie.
Ingredients
- Curd: ( Or Greek Yogurt for the English folks )
- Eggs: the main ingredient!
- Chilly or Chilly powder: We will be toasting this with oil.
- Olive oil: although any oil will work.
- Salt and Pepper: To taste.
- Bread
Process
This is probably the most straightforward processe
- Soft boil the eggs to your preference while preparing a pan to make the chilli oil.
- To soft boil the eggs, bring a pot of water to a boil stage not too rolling but to the point where bubbles are forming.
- Then gently lower the eggs into the pot with a ladle. Prepare a separate bath of cold water to wash and clean the eggs.
- To prepare the chilli oil, pour about 2 teaspoons of olive oil in a pan and once the oil is hot enough, add the chilly flakes or if you don’t have flakes add the chilli powder.
- once the oil is ready, remove it to a different bowl and use the same oil to toast the bread ( This makes it taste lovely )
- Once all parts are ready, immerse the eggs in the cold water and break the shells off by lightly breaking them and removing.
- To serve, take a good amquantity of curd in a bowl and cut the boiled eggs on top. Pour the chilly oil over and enjoy with slices of bread!
Rasam
Whatever happens the most comforting food that I make is Rasam + rice. This goes with anything - appalam, oorga and chicken and this is how I make it.
Ingredients
- mustard seeds: 1 teaspoon
- cumin: 1 teaspoon
- dhaniya seeds: 1.5 teaspoons
- Garlic tooth: about 3
- Red chilly: about 2 ( or chilly powder about 1 teaspoon)
- Curry leaves: a bunch
- Coriander: A few leaves
- Tomato: one
- Tamarind: a small lemon sized ( or 3 teaspoons of concentrate )
Process
This is a straightforward process, but very rewarding if done right.
- Take the cumin, dhaniya seeds, garlic tooth and the red dried chillies and grind them in a mixie.
- This will act as the base masala for our rasam
- Now take about 300ml of water in a bowl and add the tamarind paste.
- To this chop the tomatoes into medium sized cubes and add along with the coriander and half of the curry leaves.
- Now Mash this really well with bare hands till the tomatoes are crushed and everything is nicely ground.
- In a new pan, pour some oil and add the mustard seeds. Now pour the paste we made in the first step and heat it just a bit without making it too burnt
- Now pour the water mixture into the pan and heat it in low flame. Do not heat in high flame to avoid the water boiling too fast
- After about 5 mins you will feel the aroma, and you can decide to add salt to taste.
- This can now be eaten with rice and appalam in the side
Cramfiles
Sparse Matrices:
A sparse matrix is a matrix where most of the elements are zero. For example a social network contains a lot of nodes but not every node is connected to only a few others.
In contrast a dense matrix is a matrix in which most elements are non zero. For example pixel data from an image, where each pixel usually has a non zero value. For every matrix sparsity can be calculated as
Sparsity = Number of zero elements / Number of non zero elements
Mathematically sparse matrices are just normal matrices, but can be represented in a computationally efficient way by not storing the locations of the zero elements.
There are several ways to approach this.
- COO - Coordinate list : In this format we have a list, in which the elements are <row, column, values> of the non zero elements. The size of the list is equal to the number of non zero elements in the matrix
- CSR and CSC : Compressed Sparse Row (CSR) and Compressed Sparse Column (CSC) are formats that compress the matrix into a 1d list.
- For CSR the list has three list a value list, a column index list and a row index list. Each of the rows are compressed to provide a list which corresponds to the elements in the column list. eg: we have a matrix 95 33 0 0 0 12 11 0 0 This can be expressed in CSR as Values = [95, 33, 12, 11] columns = [0, 1, 2, 1] rows = [0, 2, 3, 4] as you can see, the row list is always incrementing and point to the column values list. The row list can be thought of as python like index ranges with which you can iterate and get the particular values.
- LIL - List of Lists. We have one large list where each element is another list for each row of the matrix and the nested list contains the column index and the value.
There are a few packages that are available. I personally deal with Hi-C matrices which are very sparse in nature and the common data formats used are cool and mcool. These files store the matrix in COO format.
For my specific use case I had to access random rows from the matrix and do it multiple times. The problem with cool and other formats is that the files are compressed and every time you want to access a particular element/row/column, you have to load the entire matrix into memory and then access the values. This means that if your matrix is really huge ( which is the case with hi resolution Hi-C matrices ) The uncompressed files come to around 25 GB, which means we will have to use 25 GB of memory to load a bunch of elements which will in total won’t come to a couple of Megabytes in size.
To solve this, I decided to create a new format CRAM - Compressed Row Access Matrix format which handles the tradeoff between loading time and storage space. By increasing the storage space by a little, you can get really good random access without increasing memory pressure.
How it works
Compressed Sparse Rows and Compressed Sparse Columns basically have a really good data structure to solve this particular problem. For example in CSR, the Row list is a naturally increasing range which tracks the location of elements in the other two lists in an efficient way. We will use this feature of the CSR to write it to memory.
Approaching this as a pure engineering problem, a file is a collection of bytes that will be stored on the computer’s memory. each part of the file will have it’s own pointer which.
This works by counting from the start of the file, the next n bytes will contain the Row list. But instead of a normal Row list, we store the bit location to shift from the start of the data to fetch the values from the matrix. So we essentially know the start and end of the Row list. each element in the row list tells us how much to move from the end of the Row list to get to the actual data element. Each data element in turn has the column number and the value, which we know exactly how to fetch.
This is a slight simplification, in reality, we have some header elemnts holding metadata about the matrix which we also know the size of, and we also know the exact size of each element in the matrix.
Why
The idea was greatly influenced by DICOM files, which use a similar approach for tag parsing. This seems like a trivial application of an abstract concept, but improves the performance of loading and cuts down memory requirements by a huge amount. The key takeaway is to know the application and the type of data you are going to use and think of smart ways to take advantage of their structure.
Links
CRAM repository - Github repository with the package implementing the above mentioned idea
Crochet!
Why
I have always been interested and intrigued by crocheting. I have stared in awe when my partner does it and the way the needle just keeps moving around with such ease. I gave it a try about a year ago and in theory I understood the basic concept - You make sure the hook end is aligned with the stretch of the hole and pull it through. But when I tried it, it was just too hard for my fingers to understand and I pushed it off to later.
About a week ago, I got the chance to crochet with a full kit and I jumped on the opportunity. I did’nt really like the patterns that came with the kit and I looked around youtube and found a pattern for a cute little turtle and decided I was going to make it.
How
So the pattern goes like this, you make the head, the tail and the hands, legs and then the shell.
Every part starts as a magic ring and then starts deviating. I started with the head and I didn’t know if it would be easier this time around and went into it, and it was not. The pattern was supposed to be a sphere with 5 increase lines and 4 decrease lines (Don’t worry even I did’nt know what these meant till later) . But somewhere aleng the video I missed the tutorial and went into the fin section and my head ended up looking a bit elongated. I took 2 hours two days to do this. But I realized that I had gotten so much better at the knitting pattern and was speeding up significantly. The eyes I had were a but too large for my thread size, so I had to wrestle with the threads to get them in.
Next I then made the tail, which was just 4 increase lines starting from 7. This looked much better than the head because I followed the tutorial word for word.
But deviating from the actual tutorial I started building the shell, as I had somehow missed the fins and skipped them from the previous mishap. But surprisingly the shell turned out to be so much more simpler and straightforward. The pattern was a magic ring starting from 7 and doing 5 increases till 35 with the shell color, then switching to the body color thread (you don’t finish it fully, but end it with a small hole in the bottom so that the other parts can be stitched in). At around line 4, we leave 5 holes for the turte. one for the tail, and four for the fins/arms,legs by skipping some loops (You don’t go within the earlier stitches and do a normal chain) . By this point I had realized what increases and decreases were and I learnt how to do a vanishing decrease in a different tutorial. This gave me good confidence with the needle and I also tried a different sized needle around the same time to see which felt right and this made me feel very sophisticated.
Then I went into the fins (arms and legs?) of the turtle. This started out as magic circles of size 6 then we do 4 increases for the back fins and 5 increses for the front fins as they are slightly larger. We make two smaller ones and two larger ones. Then we fold one of each size in half and then pull the thread through a needle from one side to the other. so that we have two symmetrical sets. ( These fins are literally the cutest and at this point I had the technique down and could do it pretty fast)
The final part was bringing it all together. I sewed in the front and back legs through their designated holes in the shell, and then sewed the head into the body. At this point the turtle was starting to look really cute and I was very excited. You tie the entire piece together by stuffing the head and body with cotton ( But I used thread because, I couldn’t reach the cotton in the middle of the night but I wanted it done) Then you finish the shell and ta-da you have the full piece ready.
I was really really surprised by how good it looked ( partly because I made it and my partner said it looked like the cyoot baby turtle from neemo ) for a first crachet thing I made. But I went through the comments section of youtube and the video had very bad reviews saying people couldn’t follow it and the instructions were unclear. But for me I guess I did not know what I did not and that stopped me from thinking I shouldn’t try it out.
Things I learnt
- Crochet - pulling thread from one side of a loop to the other and making cyoot art pieces.
- Important part of crochet - If you want the pieces to be together, you have to pull your loop through your previous stitches. The idea is you put the hook through the previous stitch, pull the free thread once ( so the new thread is between your old loop and the previous loop,) then you pull the free end once more through both the loops, so you end up with one final loop. ( might sound complicated but is very simple, look it up)
- Magic Ring - A structure that becomes a ring once you pull both ends and is used a building block for a lot of patterns
- Line - One iteration of the loop pattern.
- Increase - Pattern where you increase the number of loops compared to the previous round. For example if you start out with 6 loops, you do 12 in the next round, 18 in the third round and so on. Usually how you do this is, when you start, you do two loops through one previous stitch every other loop, then you move on to do two normal, then a double loop, then three normal and a double loop and so on.
- Decrease - Pattern where you decrease the number of loops compared to the previous round. For example if are at 24, you decrease to 18, then to 12 and so on. The idea here is to do it in such a way that it is not obvious to the looker.
- Color switch - you pull the free end of a different color through your last loop so that you get a new color for the rest of the stitch. People even switch between colors to get alternating patterns and stuff.
- Stitch - you literally take a stitching needle and stitch stuff in.
- Skill - stuff you learn when you put in patience and overcome frustration.
The full turtle pattern
- Head - A sphere starting as a magic ring starting with 7 loops with 5 increase lines and 4 decrease lines. ( use vanishing decreases for clean output )
- Tail - A magic ring starting with 7 loogs with 4 increase lines resulting in a cut sphere
- Front Legs - Magic ring starting with 6 loops, with 5 increase lines, with the final line being a folded linking line, stitched through the middle for one to get symmetric legs
- Back Legs - Magic ring starting with 6 loops, with 4 increase lines, with the final line being a folded linking line, stitched through the middle for one.
- Body - Magic ring starting from 7 and doing 5 increases till a total of 35 with the shell color, then switching to the body color thread. At around line 4, we leave 5 holes for the turte. one for the tail, and four for the fins/arms,legs by skipping some loops
If there is one moral lesson learnt from this, don’t stop something before you have actually tried it out and given your all. You never know what you are good at and what life will throw at you ( hopefully it’s a cyoot baby turtle ). I am really really happy with the way it turned and will build more, but the first make of anything is always the best. The next thing I want to try is an octopus from the same person.
P.S: I have called the crochet hook a needle everywhere.
My Rating List
Why
I have a mental rating of stuff but never put it in paper, even though I know likes, rates and dislikes make everyone unique and distinct. One of my cousins kept asking everyones rating so here’s a permanent list of mine.
Food
Jose Luis ( Italian )
- Lasagna - 8/10
- Burrata salad - 8/10
- Carbonara - 7/10
Utopia Bagels
- Oreo and Cream Cheese - 7/10
- Olive - 8/10
- Jalepeno Cream - 8/10
- Pastrami - 9/10
- Scallion - 7/10
Shanghai 21
- Pork soup dumplings - 10/10
- Rice Cake - 7/10
- Crispy Pork + noodle - 10/10
- Tea - 7/10
- Tea + water - 9/10
Deli meat
- Brisket sandwich - 9/10
- Beef sandwich - 9/10
- Reuben - 10/10
Ice-Cream
I know people get offended with me calling gelato ice cream, but hey.
- Figo Gelato NYC
- Pistachio - 10/10
- Mango - 8/10
- Tiramisu - 7/10
Dessert
- Mango mango
- red bean + coconut milk with boiled rice - 8/10
- sago + mango ice cream - 8/10
- mango + milk + black rice - 9/10
- Vanilla crepe cake - 9/10
Places
- Cubbon Park - 11/10
- A2 Arboretum - 10/10
- Besant Nagar - 10/10
- Marina Beach - 7/10
Programming languages
- JS - 4/10
- Java - 7/10
- R - 3/10
- Python - 9/10
- Elixir - 10/10 ( I’m biased )
- Matlab - 8/10
Pixel Town
I made a music composition!
So when I joined grad school I wanted to make the best use of the opportunities and I wanted to join a class on music within the University. The video game music ( PAT-305 ) sounded very interesting without looking like a lot of effort so I took it, which was one of the best decisions I made. So the classes were all about the evolution of music within video games, and each class we looked at some history of a particular genre or a particular artist and their work. We would look at clips from a particular game and try to understand what made the audio stand out, what sort of emotions it evoked in the player and how that enhanced or deepened the gameplay. We understood different purposes of music and tricks that the industry employed to make the audio pop and make sense.
The course was structured as a RPG game, where instead of getting scores for your essays or assignments ( quests ), you get exp points and level up based on your exp. As a part of the course, the final project was a composition quest, where you are expected to put all the knowledge learnt in the class into a music piece of 2 mins in length, with contrasting or opposite purposes / genres. I have always wanted to play around with vocaloids and DAWs and see how well I fare in making music, but never got to sit down and do it, and this was the time for me to explore.
With two days to go for the submission, I allocated 20 hours for my 2 minute piece, to learn a DAW, understand how music theory works, and how plugins work. I knew from the start that I will be doing 8 bit chiptune music, as orchestral music never interested me that much, but the vast amount of creativity that pours out of very simple audio channels was always interesting.
To give a brief of what 8 bit audio is - It is basically the poppy hyperactive music tunes you hear in the old NES video game sets like contra, duck hunt and the more famous super mario bros. These were released in the 1970’s and during that time, having a full fledged audio system within such a small device is a huge engineering task. So for that time, the audio system consisted of 5 different channels -
- Lead square wave channel - used for chord progressions
- Melodic square wave channel - melodic lead part of a song.
- A saw ( triangle ) wave channel - acts as the bass.
- first Noise channel - usually percussion like snare and hi-hat
- second Noise channel - deep and heavy percussion
Variation is generated by modifying the amplitude of each of these channels. So music is just an order of modulations that happen during playtime.
In order to make my composition I used FL studio as my DAW and the magical 8 bit plugin to generate the different waveforms.
Process
My library has an amazing recording and audio workstation, which is where I spent almost 2 entire days on the composition. For the first few hours I was just listening to random chiptune mixes on youtube and looking at tutorials for DAW, and various material on how to get started with composition and music production - like composition and music theory. During this time I randomly stumbled onto a new genre of music called jpop and found artists like Zutomayo and listened to a whole bunch of them. One song that stuck was plastic love And I decided, I have to incorporate the happy upbeat vibes in my music. So I looked at a tutorial on jpop music, and there were a bunch of ideas that made jpop stand out.
- The chords are chopped and layered to create upbeat vibes.
- The music was very similar to video game music in that, there was a lot of layers and a lot of things going on at a single time
- There were multiple melody tracks that run around in the same key.
- The bassline should Slap.
But this meant I could not stick to the 5 channel sound, which was fine by me.
I started with the chord progression first with a square wave laying down a foundation key for me to work with, then I chopped up the chords to give the classic jpop vibe. Then I added a percussion track with a noise channel, and a snare and bass drum, which you can hear as the zzzzz white noise in the final music piece. Finding the bass track was probably the hardest part. I had to make it go along with the chord progression while not stealing away from the smooth chord transitions. The most fun I had was with writing the melody part. This was so much fun than I expected. Having played guitar for a while, I started with a random progression but, then I could realize that the note lengths were a bit off and I ended up fixing them one by one.
The final touches were to sort of add and remove some instruments at certain places so that the music is not the same all through and there was a proper beat drop before all the layers came together.
For my second contrasting piece I chose a dark scary theme, which contains very low sounds and unresolved chord progressions that create a really scary dark vibe. Although I used too much low octave sounds and this sounds weird on mobile speakers.
My favourite part of the melody is around 0:22 where I wanted to incorporate the video game pause and play audio into the music and it came out well. I also like the brush hi hat effect before each beat drop.
Overall I learnt a lot about the musical process and how DAW works, but I think I added too many layers, which clouds some of the interesting variations in the music.
Here is where you can listen to the pieces
Murphy
“Anything that can go wrong will go wrong.” - Edward Murphy
I am well aware of Murphy’s law and how it emerges out of pure randomness. But never have I experienced it personally until today. Being back in School after working was a big shift but I thought I was doing pretty well in everything, except the exams. I put in more effort, prepared well and thought I had these exams handled.
I have never missed an assignment or class this semester, but today, everything that should not happen happened. I had asked the professor about the exam date and that was registered as the 12th in my mind. I had a bad sleep yesterday and woke up late and decided to skip class this once, as it’s the last class. Then I get a mail prom the professor asking me if everything was alright. In the stress I took a wrong bus, reached an hour late and did pretty poorly in the exam. Although I know this is not the end of the world, it felt like it for a while and It was interesting to experience it first hand.
Usually when everything goes wrong, I used to have a pretty good understanding of what was not in my control and what is, but this time it felt like everything went wrong and everything could have been handled by me.
Anyways, learnings from this is that checking everything early is a good thing and I need to think more like a schoolkid because it matters.
I like to think of De Morgan’s stament of this. - “whatever can happen will happen” and it’s up to you to take it however you want. But it’s not an excuse to improve or try your best in every situation.
My Setup
I love customizing everything I use, and make it feel like my own. So no wonder I have spent more time learning config files rather than learning an actual programming language.
Naturally I’m curious to see what setup others have and if I find something interesting, I steal the idea and use it. I’m sure other people are curious about my setup too, so I’ll make it easier for anyone to replicate my setup here.
I’ll just add my setup here and the exact configs can be found in my dotfiles repo here
OS : Macos
I don’t like any apple product, except for the mac, It just makes sense for software development and programming. ( Iphones are costly and useless )
Keyboard : Dvorak
I use the dvorak layout which makes so much more sense than qwerty. I don’t have pain after typing so long. Switching cost is around 3-4 months of 20 wpm. But once you are past it it’s a breeze.
Don’t worry about vim bindings. That is just another 1 month of 20 wpm in vim 8^D
Terminal Emulator : kitty
I used to use iterm 2, and it used to work fine. But I wanted to try something different and ran a comparison with kitty and iterm2 and kitty was 5 times smoother, so Kitty it is. I have my own custom color scheme which incorporates a lot of light orange and pink themes.
Multiplexer : tmux
Tmux is really good for session management and makes sense once you have the keystrokes down. I have different keybindings setup for remote sessions and local sessions so that switching is conscious.
Shell : zsh with oh-my-zsh
There’s nothing to say about this. zsh just works, but I want to try fish someday
I have vim mode keybindings to iterate through commands.
zsh theme : af-magic
Looks clean af and is fast to load. I might make my own theme someday.
Shell search : fzf and zoxide
I only use fzf for file searches and don’t really like the reverse search. so fzf reverse search is mapped to ctrl+t and fzf search to ctrl + p
zoxide lets you switch folders with fuzzy searches. Basically you can switch from anywhere to anywhere without having to type the full path. so useful.
Code Editor : Visual studio Code
I was an avid user of Atom, but even though I’m a bit salty to accept it VS code has gotten really good.
Text Editor : Vim
I don’t think of vim as an editor, more like a language. So I have vim everywhere it runs.
A lot of customization and I even wrote my own vim theme bluemint
Programming Language : Elixir
Elixir is just so much fun to write and runs really fast. ( See my other Elixir posts for why I love it )
Browser : Arc
Arc changed the way I look at a browser even though my computer cannot take too many tabs in it anymore. Although I am trying to use arc search and that has’nt worked out too well for me
Notes : Obsidian + md + git
I had all my notes as md files for ages, so it naturally makes sense to use obsidian.
references Management : zotero
Recently started using this, and is the best tool for managing references and research papers.
Why Elixir
Elixir
Whenever I tell someone Elixir is my favourite programming language, I am usually met with one of two responses - “That’s crazy” or “What is this guy talking about?”
I wanted to explain why I personally like elixir, love the paradigm and why I believe parallelization is the way to go ( unless you are a web developer building a very niche product )
The history
In the 1990’s Ericsson needed a fault tolerant and safe system to maintain and run their telephone exchanges. They decided to write their own language called Erlang ( apparently short form for Ericsson Language ) with which they implemented the OTP or Open Telecom Platform. It is a set of tools that implement a sort of pub sub mechanism that can be parallelised without worrying about failure
The basic functioning of the language is as follows. Erlang can start it’s own processes ( which are different from system processes ) That have their own scope and can change their behaviour during runtime. The processes are isolated but can communicate with other processes like a pub sub mechanism but between processes. These processes can also be spawned on different nodes that can have their own listeners offering extremely parallel applications.
How does elixir come into the picture ? Elixir is essentially written on top of erlang. So every elixir program is compiled to run on the Erlang VM and is compatible with any erlang module. This means you have access to all modules within erlang while also getting better syntax and QOL that speeds up development process. This means elixir is the best of both worlds, you get fault tolerant systems with a very modern programming language that is just so good to write.
What I Love about Elixir
- It made me think differently : Having a purely functional programming paradigm meant I had to look at datastructures and algorithms differently.
- Syntactic sugar : Elixir is very modern and has a few inherent mechanisms that make life so much easier. Like the |> syntax, which looks much cleaner and nicer than chaining a hundred different functions.
- Highly parallelizable : The language itself inherently supports parallelisation of code, which I have never written.
Why I fell in love with Elixir
I can go on and on about Elixir, which I have already done Functional Programming with Elixir But here are the main reasons why I really love programming in elixir
- The language gave me a unique perspective to solving some problems.
- I love recursion
- It feels like I’m playing a fresh game every time I code something up in elixir.
- I love atoms.
In conclusion, even though some of the history I shared might not be relevant, this is my reasoning for liking the language. I highly recommend you atleast give the language a try and let me know how it goes.
orange chicken
This is my weekly meal prep recipie. I use this with a lot of dishes, like quesadilla and salads.
Ingredients
- chicken thighs : 500 gms
- all purpose flour : 100 gms
- pepper, salt : required amount
- paprika (or chilly powder but make sure you know how spicy they are.) : required
- oil : required amount
- soy sauce : 2 table spoon
- orange tossing sauce ( you can also make your own. Will add recipie later ) : 2 table spoons
as you can see its all based on feeling
Preparation Steps
- Take the chicken thighs and rinse it well in water
- Cut the chicken into small cubes
- Put the chicken in a bowl
- Add the paprika, salt, pepper, and all purpose flour
- If the chicken looks white, you haven’t added enough paprika
- Now Heat the pan till water evaporates
- Add oil and wait till the oil starts evaporating
- Now add the chicken, making sure to separate it before adding it to the oil
- Fry it till it’s well cooked.
- Now remove the chicken from the pan into a different bowl.
- Pour 2tbsp of soy sauce and 2tbsp of orange sauce and heat them.
- Add the cooked chicken slowly into the sauce and continue tossing them.
- add a bit of sesame seeds on top and they are ready to be served
Reading List
Reading List
I have always had the time ( and money ) to get what I wanted to read and then just read it. But nowadays reading time is getting scarce and there are so many good books it is finally time to create a reading list
- 2001 space odessy - https://en.wikipedia.org/wiki/2001:_A_Space_Odyssey_(novel)
- siddhartha - https://en.wikipedia.org/wiki/Siddhartha_(novel)
- Thank you for being late - https://en.wikipedia.org/wiki/Thank_You_for_Being_Late
Biriyani!!
This is a recipie for one of my favourite dishes ever. The hot, spicy and flavourful dish has a lot of styles and varieties in which it can be made. My favourite way of making it is as a one pot dish with chicken gravy which my family specializes in and I’ll show you exactly how to make it. I’ll also include a chicken gravy recipie, which will be my next post.
Ingredients
- Onions : 2 ct
- Tomatoes : 2 ct
- coriander : 1 bunch
- chillies : 4
- mint : 1 bunch
- Chicken : 500 g ( I prefer skinned and smaller pieces and legs, But you can get good results with skinless large pieces as well. )
- Basmati Rice : per preference
- coconut milk : 1 cup ( can also be replaced with heavy cream )
- mixed masala : get it from me ( Or you can get any biryani masala supermarkets or you can also make it by mixing and grinding a bunch of spices )
- flavouring spices : cumin, cloves, cinnamon, bay leaves.
- ginger + garlic paste
- salt + pepper
- ghee
- curd ( yoghurt if you are not from India )
- lemon juice
- water ( yes, I forgot this once )
- Rice cooker ( works best, but can be replaced with a wide pan )
Steps:
Preparation:
- To get started, we will be cleaning and marinating the chicken. Put the chicken in a bowl, add turmeric and water. Wash it in the sink with running water for 20 seconds.
- To the cleaned chimken add pepper, salt, chilli powder, curd and lemon juice and marinate it for about half an hour ( with this time, you can get the other stuff prepped. ) marinating it imbibes the flavour into the chicken flesh. If you have leg pieces, add a few slices with a sharp knife on the leg so that the flavour can get soaked up.
- Next we prepare the other requirements.
- Take the onions and slice them up into thin straight pieces.
- The tomatoes can be chopped up into blocks.
- For the mint, pull the leaves apart and keep them separated. you can chop them up and plant the stems to get more mint if you want
- the coriander can be cleaned by twisting the bottom and chopping up finely.
Procedure Now that we have everything ready, we can get started with the procedure.
- Add a bit of oil into the rice cooker and add your favourite flavouring spices into the mix. Saute them until you can smell tha aroma from the spice ( no not melange )
- Add the onions and chillies into the mix and saute until it gets slightly golden brown, add some ginger garlic paste and saute well.
- Add the tomatoes in, this should soak up the deep fried ginger garlic essence and start smelling good. Add in the chopped mint and coriander and saute.
- Now comes the fun part, add your marinated chicken in and fry them for atleast 15 minutes. The timing depends on the size of your chicken pieces. Check if the pieces are well cooked and we can proceed to the next step.
- Next we cook the rice. Take the required amount of rice and directly add it onto the cooker. Give it a good saute along with the chicken and the flavouring substances. This makes sure that the rice absorbs the essence before cooking.
- The amound of liquid should be 1 part rice : 2 parts liquid. Here you can use the coconut milk and water mixture as liquid parts and add them to the cooker. Here, we can check if the flavour of the spices is to our liking and add required amounts of salt. If it is too bland add a bit of chilli powder and if it requires more salt add the salt.
- Finally close the cooker and keep the heat at maximum. Once the whistle blows, turn the heat to simmer and let it cook in the simmer heat ( low heat ) for 10 more mins
- As a replacement all of this can also be done in a rice cooker, and I have had good results from pressure cooking this.
Let the pressure escape the cooker naturally and open for some savoury Biryani. Serve with eggs and chicken curry!
Madras Masala chicken
This is a spicy tasty peppery recipie for madras masala chicken. I love the creamy texture that accompanies the soft chicken.
Ingredients
- Onions : 2 ct
- Tomatoes : 3
- Spices (anas, cumin, clove, bay leaves, cinnamon sticks) : req
- red chillies : 3 ct
- Ginger garlic paste : 1 table spoon
- mehti seeds : required
- turmeric : req
- cashews : a few
- chilly powder : required
- salt : required
- chicken : 500 gms
Steps:
- Chop the onions into thin slices
- Chop the tomatoes into square cubes.
- Heat the pan and add gingelly oil to it.
- Add the spices and chillies to the oil and heat them till they turn aromatic.
- Now Add the onions into the pan and saute them until they turn golden brown.
- Add the ginger garlic paste and saute them over
- Add cashews and turn one side almost brown and add the chopped tomatoes.
- add enough salt and saute everything until the tomatoes turn mushy.
- Now let the mixture cool down and put it in the blender and blend until it becomes a smooth paste.
- Add oil to the pan and heat it again. Add the chicken onto the pan and heat it.
- Fry the chicken in the oil until the flesh loses its color
- Now add the paste into the pan and heat it. Add a little bit of water if you need more gravy.
- Heat it until the oil separates and remove it from the pan and serve.
Gene Machine Book
Overview
I picked up a non fiction book and finally pushed through to completion and it turned out to be a really worthwhile read.
Overall my feel about the book was that it was not too technical and focused more on the human aspect of science. How scientists interacted with each other, how they kept up with people, socialized and went on about answering unanswered questions in the universe. Kind of like a sneak peek onto the Science world. The first half gives an intro of the author, how he switched to Biology from Physics and who his early mentors and friends were.
As the middle of the book approaches, he describes about the idea of crystallizing the ribosome to use synchrotrons to identify the structure of the parts of the ribosome. There are four groups stuck in a race to find out who gets the best resolution and figures out the structure of the ribosome. At about 70% of the book, the author’s ( Venki Ramakrishnan ) team and a team from Yale simultaneously solve the structure of the ribosome. Yale team solving the 50S structure and Venki’s group solving the 30S part. But the interesting part is, the rest of the 30% of the book covers the politics involved in getting a medal and how getting the medal can derail a person’s scientific career.
He goes in depth about each and every person he encountered in the journey to explain their personality and identify their strengths and weaknesses.
My thoughts
My favourite part of the book is when the group braces themselves and starts work on the project while on the moving to Europe, not knowing even if their research would lead to something.
A few takeaways for me from this book were: ribosomes perform a lot of steps to synthesize proteins : The ribosome started out as some sort of RNA backbone that acts as both a structural part as well as taking care of coding information The scientific field is full of competition and full of smart people This becomes very clear in the way people act towards each other and try to one up the other people. The author does not hesitate to criticize or point out when someone is wrong. Usually this leads to Better outcomes for everyone involved but with sometimes you being the bad guy. It prevents problems that can happen in the future because of current disagreements. Getting a prize and solving Scientific problems is not just about being smart it’s about knowledge, knowing others and a good chunk of luck involved. But the only thing that anyone can do is keep putting in the effort and going forward.
Overall I think it is a very very nice book and anyone who is at a crossroads of careers thinking of pursuing studies or switching jobs, should definitely give this book a read. It shows how slowly some aspects of science progress and explains “good things take time”.
Scaling Elixir Applications
Fault Tolerance
Continuing with the Functional programming with elixir series, we will be diving into fault tolerance and how elixir as a language has the tools to create fault tolerant systems.
The way Elixir approaches fault tolerance is similar to how Kubernetes approaches fault tolerance. In a kubernetes cluster ( group of virtual machines ) whenever any child pod ( singular virtual machine of the group ) crashes or goes down, could be due to a multitude of reasons for eg. Due to a database connection failing, or a web api failing due to mismatched response. Kubernetes has a control plane that usually decides what to do with the node, and usually the strategy is to restart the pod and check if it works.
Similarly in elixir, there is a master process that takes care of any dead and errored processes. This master will get a :Exit signal whenever a process dies and based on the strategy the process gets recreated. This is done at the language level itself and BEAM ( the erlang VM ) itself takes care of this. This is possible as the elixir processes are isolated and don’t have any interdependence. In essence any singular part of the program that is on the process that crashes can be restarted separately without having to worry about the other parts of our code.
For example - Assume we have a process that connects to the database, reads some stuff and send out the data as an email. Here if the process fails at the database connection, the master looks at the process and will automatically spawn another process that does the same thing. This can happen multiple times without us having to worry about manually handling the error and figure out a fallback option or have a separte retry queue that does all of this. This is possible because the processes handle immutable data and don’t update a common memory.
Now the question arises, how is this different from a kubernetes cluster that essentially does this. The main difference is how the software itself is designed and thought about. Lets say we have a python program that runs on a kubernetes cluster, that faces the exact same scenario where the database is unreachable, we usually catch the exception and notify it, but the program will still continue. In elixir this scenario will stop the process and that sends a message to the master, and the master decides the best course of action In essence elixir is made for vertical scaling a system right from the program, and kubernetes is supposed to horizontally scale our system. elixir coupled with it’s distribution system can be used to scale any system
How to write fault tolerant mechanisms
Our code should not handle errors and should fail. The handling is done by the supervisor. The following code is a mock implementation of a database connection that performs some action.
defmodule DbConnector do
use GenServer
@impl true
def init(initializer) do
{:ok, initializer}
end
def start_link(state) do
GenServer.start_link(__MODULE__, state, name: :dbconnector)
end
@impl true
def handle_cast({:connect, connection_string}, _state) do
# assume the connection and the database actions happen here
{:noreply, connection_string}
end
end
Here, we are defining a process that connects to a database and can run whatever it needs to on it. Usually with any other declarative language, we will have to check if the database connects, if the output is returned and if any other error occurs. But here we have just defined the success criteria, which means for any sort of failure, we will automatically let the supervisor handle it.
In the terminal we start a new iex session with the DbConnector module imported. Now we start a
iex(1)> children = [ %{ id: DbConnector, start: {DbConnector, :start_link, [[:hello]]} } ]
[%{id: DbConnector, start: {DbConnector, :start_link, [[:hello]]}}]
# We are starting the supervisor to spawn new process for the DBConnector
# the strategy is one for one, which mean the supervisor will start a new process if one fails.
iex(2)> {:ok, pid} = Supervisor.start_link(children, strategy: :one_for_one)
{:ok, #PID<0.149.0>}
# we can check the process location with Process.whereis/1
iex(3)> db_pid = Process.whereis(:dbconnector)
#PID<0.150.0>
# we are manually killing the process here to simulate failure
iex(4)> Process.exit(db_pid, :kill)
true
# Here we can see that the process was automatically started by the supervisor and has a different pid
iex(5)> Process.whereis(:dbconnector)
#PID<0.151.0>
What all of this essentially means is that our code does’nt have to worry about handling lots of edge cases. Even in case of failure the process will automatically start and none of our other processes have to stop.
Distribution
Elixir code compiles and runs on the BEAM VM, which means it already has access to erlangs powerful distribution library. The Erlang Distribution library enables us to have different “nodes”
Each node is a separate process that runs with its own name and can communicate with other nodes by passing messages. You can also execute functions on the called node based on the configuration.
The Node.spawn_link/2 function takes in two arguments, the remote node and the name of the function
Below is an example of starting different nodes and communicating between each of them.
How to distribute your code
We start a node with user1 as the name
iex --sname user1@localhost
here we define a module as User1 which just prints its name out
iex(user1@localhost)1> defmodule Run do
...(user1@localhost)1> def say_name do
...(user1@localhost)1> IO.puts "Hi, my name is User1"
...(user1@localhost)1> end
...(user1@localhost)1> end
we start another node as user2
iex --sname user1@localhost
We are calling the defined function using Node.spawn_link function and using the node name and the say_name function, which prints the called node’s name
iex(user2@localhost)1> Node.spawn_link(:User1@localhost, fn -> Run.say_name end)
Hi, my name is User1
#PID<13823.123.0>
By effectively using the fault tolerant paradigm and distributing our code, we have full scalability and secure code running in the servers.
Functional Programming with Elixir
During my time as a professional software developer, I have always been working with object oriented languages and all codebases I have interacted with have been written with the object oriented paradigm. So when I came across the functional programming paradigm, I got curious to learn more. Reading about Haskell and Clojure portrayed functional languages as hard to grasp and not very useful. But I found out about elixir and the syntax looked promising. So I set out to learning elixir and found it surprisingly practical. It had a lot of flexibility in terms of language syntax to enable some of the rules functional programming inherently follows. So here is a comprehensive overview of what elixir is all about and some tools and ideologies I learnt.
Ideological shifts
The functional programming language introduces a few ideological shifts.
Immutable data types – In Functional languages, all data types are immutable. Once a value is created, It cannot be changed. This is best explained with maps
sample_map = %{"key1" => "val1", "key2" => "val2"}
Now we have the map named sample map with key1 and key2. In an object oriented language, the dictionary will be mutable and we can directly change the key1 to a different value. But in elixir, we will have to update the key, and that will create a fresh dictionary with the updated value
Map.put(sample_map, "key1", "update1")
%{"key1" => "update1", "key2" => "val2"}
sample_map
%{"key1" => "val1", "key2" => "val2"}
# This is assuming iex execution. More on later sections
Here the original sample_map still retains its original value and the Map.put returned a fresh dictionary with its own memory location. Object oriented programming languages usually optimise for memory and can directly update values in memory without creating copies. With improvement in storage and memory of computers each year, we don’t have to worry about memory limitations affecting performance. Immutability enables developers to effectively debug and maintain functions without having to worry about for example a helper function updating a user object’s members.
Anonymous Functions – These are functions that can be passed around as variables, without being defined.
my_fun = fn x -> x*3 end
my_fun.(1)
# 3
my_fun.(5)
# 15
Here my_fun can be passed and will be treated as a variable but can also be called with the dot syntax.
Pure Functions – Functions in a functional language are pure. A pure function always returns the same output value for a given input and doesn’t create any side effects. Side effects are basically changes to the program or environment outside the function’s scope.
For example in python
test_list = [0, 0, 0]
# impure function in python
def add_to_list(eg_list):
eg_list.append(5)
add_to_list(test_list)
print(test_list)
# prints [0, 0, 0, 5]
add_to_list(test_list)
print(test_list)
# prints [0, 0, 0, 5, 5]
add_to_list(test_list)
print(test_list)
# prints [0, 0, 0, 5, 5, 5]
Here the same function with the same input returns different outputs each time its called. Hence this function is impure
The same on elixir looks like this
# pure elixir function
def add_to_list(test_list) do
test_list ++ [5]
end
# calling this function
test_list = [0,0,0]
add_to_list(test_list)
# [0, 0, 0, 5]
add_to_list(test_list)
# [0, 0, 0, 5]
add_to_list(test_list)
# [0, 0, 0, 5]
Calling the same function n times will result in the same output.
Classy functions – Functions are treated as values and can be passed around. For example a function can be used as an argument to another function. These can lead to higher order functions.
For example, the Enum.map function which is used to map each element with a particular operation. This operation can be any other function. Here Enum.map is a higher order function as it takes in another function as its argument.
my_list = [1, 2, 3, 4, 5]
Enum.map(my_list, fn x -> x**2 end)
# [1, 4, 9, 16, 25]
Enum.map(my_list, fn x -> x/2 end)
# [0.5, 1.0, 1.5, 2.0, 2.5]
Here Enum.map takes in the anonymous function which raises an element to the power 2. Hence the Enum.map function is a higher order function. The action that Enum.map performs on the elements depends on the function passed in as the parameter.
Recursion
Recursion
Recursion
In Elixir, everything is handled with recursion. Not even just the functions, even the data types ideologically follow recursion. Some points that might seem weird but are very useful.
A function can be defined multiple times with different signatures, based on the number of arguments, type of arguments Functions defined multiple times means it is easier to write end cases for recursion and the same function can be called multiple times. For example, a factorial function can be written as
def fact(0) do
1
end
def fact(n) do
n * fact(n-1)
end
fact(5)
#120
And there we go. A factorial program without any if statements!
There isn’t a dedicated for loop like in object oriented programs. In the sense, if you want to loop 100 times, what you essentially do is generate an iterable of length 100, and go through each of them performing an action on each of them. ( In my opinion this is such an interesting idea and this is how programming should be taught to new people )
# this runs 10 times multiplying iter by 2
for n <- 1..10, do: n * 2
# [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
Every iterable data type is recursed around to access its values. In elixir, each list only contains two values. a head value and another list. Now the next list will contain its own head value and another list. to understand this take a look at this [ 1 | [ 2 | [ 3 | [ 4 | [ 5 | [ ] ] ] ] ] ]
Here the description is like this [ head | tail_list ]. ( by the way, above representation is the valid way to describe a list. the normal method of [1,2,3,4,5] is just syntactic sugar )
This means that in order to get all values of a list, you don’t loop through the elements, you recurse through the items.
def double_each([]) do
[]
end
def double_each([head | tail]) do
[head * 2 | double_each(tail)]
end
my_list = [1, 2, 3, 4, 5]
double_each(my_list)
# [2, 4, 6, 8, 10]
Pattern Matching – Each assignment statement is not really an assignment statement. In most functional languages, it is an eqality. Think of a math equation, here the equals = sign merely states that the left hand side is equal to the right hand side. Functional programming languages take this idea and extend it.
So each equals sign in elixir means that any values on the left are equal to the values on the right. This provides us the ability to match values. The important use of this is to define functions that can match certain criteria based on the arguments and to write guard classes.
[a, b, c] = [1, 2, 3]
a
#1
b
#2
c
#3
Here We have essentially equated the list on the left to the list on the right. And so, each variable a, b, and c gets pattern matched and the compiler knows that a, b and c should be that specific value.
Whew, that was a lot of new info. But what all of these enable us to do, is our codebase is now very robust and way easier to debug. Functions can be considered as black boxes that work as they are supposed to. Elixir also supports parallel processing since each function can be set to run on different cores, without having to worry about passing in data and state of data within our memory. More than that, it is a fun way of looking at programming and teaches a lot of good practices, which can be incorporated into our development flow.
I have been solving some usual programming problems with elixir for a while now and these are available here https://github.com/imnuvi/Algorithms
Resources:
Here are a couple of useful resources which helped me understand and learn Elixir
Books on elixir – https://github.com/sger/ElixirBooks?tab=readme-ov-file Elixir Succinctly book – https://www.syncfusion.com/succinctly-free-ebooks/elixir-succinctly Official elixir Hexdocs documentation of elixir packages – https://hexdocs.pm/elixir/1.12/Atom.html I will be publishing a part two of the functional programming series, where I will cover more ideological shifts and elixir quirks and part three where we will go through OTP ( Open Telecom Platform ) and parallel processing for distributed fault tolerant systems.
The Blind Watchmaker
Genome Dynamics Visualization App: Description: During my Undergraduate years, I got introduced to the concept of The Blind Watchmaker by Richard Dawkins. The concept intrigued me a lot, and I got the chance to recreate and visualize the concept with the help of programming. The Program lets the user interact with a set of organisms and select the winning organism each generation, and the subsequent organisms will evolve the desired organ with superior functionality.
Significance of the work:
The application is an educational and interactive tool, offering users a visually engaging platform to comprehend the principles of evolution. The app contributes to scientific literacy by making natural selection and adaptation accessible to a broad audience. Whether used for educational purposes, scientific exploration, or as an entertaining means of learning, the app’s ability to demonstrate evolutionary mechanisms in a user-friendly manner enhances conceptual understanding and promotes appreciation for the intricate processes shaping biological diversity. The Program uses fractals that are found everywhere in nature as the building organisms. Building the application provided invaluable experience in problem-solving, debugging, and building efficient systems.
Concept:
The concept posits that the intricate design observed in living organisms arises from incremental mutations over extended periods. Despite the unforeseeable nature of natural selection, complex and seemingly designed structures can emerge. This underscores how the appearance of design in nature can be explained through the purely mechanistic and unguided processes of evolution.
Approach:
Research: Research for this project involved a foundational exploration of the underlying principles and delivery mechanisms of the concept. Interviews with both students and professionals revealed a pervasive misunderstanding of, or misinformation about, the concept of evolution. To ensure broad accessibility, the project is designed for deployment on both web and Android platforms, targeting a diverse user base.
Layout: The layout will feature a grid populated with diverse organisms, each composed of fractals with varied parameters. These parameters encompass the size of each fractal branch, the angle between branches, and the color of each branch. This implementation diverges from the original by incorporating fractals to more accurately depict real-life structures, where fractals are inherent in structures such as lungs, blood vessels, and the arrangement of leaves in plants.
User flow: Initialization: The user begins with a random grid populated by fractal organisms, each possessing unique, randomly assigned starting parameters. Define Evolution Criteria and Selection: The user mentally defines a vague set of success criteria for evolution, such as a specific color and shape for the organisms. The user selects organisms from within the grid based on the defined evolution criteria. Selection and Offspring Generation: The chosen organism becomes the parent for the subsequent generation of offspring. With each click on a selected organism, a new generation of offspring is generated to replace the current grid. The offspring inherit parameters from the parent but undergo random mutations. The degree of mutation is determined by a mutation rate, introducing slight variations in parameters. Iterative Evolution: The process of selection, mutation, and generation of offspring is iteratively repeated for several generations. Convergence to Successful Evolution: Over successive generations, organisms that meet the defined success criteria evolve and persist, while those that do not gradually diminish. The grid transforms, retaining only organisms that have evolved into structures best suited for the given environment. Final Outcome: After a number of generations, the grid primarily consists of organisms that have successfully adapted to the defined criteria, representing the best structures capable of thriving in their environment.
Technical execution Fractal generator: This basically generates the organism given a set of parameters. Makes use of Trigonometric functions to calculate the position of the next branch. Mutation logic: This defines how much the next generation varies in relation to the parent of the previous generation. Uses a handwritten randomness logic to mutate and defines how inheritance happens.
The fractals are rendered by having a struct that defines each parameter and these define the various aspects of the fractals, which are calculated recursively at each branch after applying the mutation value.
The Website: Website is written with JS canvas for easy accessibility and deployed here https://ramprakash.blog/projects/1/ Mobile Application: The mobile application is written in Kotlin for android phones and can be downloaded here : https://play.google.com/store/apps/details?id=blog.ramprakash.mutation_map&pcampaignid=web_share
Results achieved: Helped users gain a Visual representation of the theory of evolution Got a deeper understanding of Evolution, how it can be better explained visually and other places where it can be used.
Lessons learnt: Understanding a concept in depth makes it easier to apply it in different contexts. Understood more about Javascript and Kotlin languages for developing an interactive UI Creating a framework for the interfaces before starting to program makes it easier to ideate and code better software
Links: Explanation video by me: https://youtu.be/Q3AoHzQ2dB4 The entire codebase: https://github.com/cosmoglint/the_blind_watchmaker Or here: https://cosmoglint.github.io/the_blind_watchmaker/
Future projects I would like to work on: Standardize storage and access of human genetic information such that its easier for researchers and doctors to access and make use of.
Getting started with cloud systems
Learning system design with #crio.do
I have refrained from understanding how cloud computing works, for fear of being overwhelmed by the AWS beginner guide. But I got a chance to understand it from a different source. Heres what I learnt from the system design miro experience.
SETTING UP The first step in designing is to rent a virtual machine from Amazon Web Services. Create a new AWS account and head to the launch EC2 instance page. While setting up your virtual machine, youll be asked to create a key which will be used to access your machine with a secure shell from your computer. This key needs to be kept secure and this can be done by using
chmod 400 key.pem
command which allows only the admin to access the key file. next connect to the VM with the ssh command on linux or using putty on windows. After gaining access, set up a HTTP server on your machine using Nginx, which allows you to configure and set up a fresh website.
In order to access your website a static IP (Ip that does not change every time you restart your machine) which can be done in the AWS from the elastic IP panel. This enables you to access your server from your web browser by typing the static ip address.
DIVING IN Now that you have your server up and ready, we need a domain name to go with your server ( would you rather type google.com or 8.8.4.4 ?). After visiting a domain hosting site like godaddy.com ( and painstakingly finding a domain name that suits you) The static ip address of your server can now be assigned to your domain name. But everyone cannot access your website because AWS has inbuilt firewall that blocks all ports. So create a new access group and allow all http traffic through it from any ip. Now your website can be accessed with your domain name.
ACTUAL SYSTEM DESIGN Now that we have our website ready to go, there needs to be a way to split up heavy traffic in your servers. To handle this set up a new VM the same way as before and configure it a static ip. Now in your domain name provider settings add this new ip to your domain name. This means when a person accesses your domain name, either of the two ip addresses gets served based on the current traffic (if one server is down, the other will be served).
FINAL CONTENT DELIVERY With everything set up, if your website wants to deliver humongous files or large content, a content delivery netword will reduce the time taken to serve it to a user.So set up an account with some free cdn providers. The basic idea of a cdn is creating cached version of your content in multiple parts of the world so that the content can be accessed by people from various parts without much delay.
THOUGHTS This micro experience was a fun way to explore new territories and the #IBelieveInDoing workshop was a deep and enlightening experience. Glad to have been a part of this wornderful endeavour.
Emission Volumetrics and volume shaders
These are two closely related shaders that go well with each other. Lets start with the emission. It makes an object glow with a particular colour. This is useful when the lighting used in a scene is shaped a particular way(like those halo lights streamers use). This gives the scene the specific look imagined.
If you’ve seen a rendered image and something made it look ethereal or punchy, its probably the emission shader.
The way this works with volume shaders is crazy. Volume shaders differ from normal shaders. Normal surface shaders give a look only to the surface of the object. It does not affect the size or the density of the object. Here’s where volumes come in. Volume shaders give the entire volume a particular look. It can be used to determine how much light enters the object(imagine light shone on ice).
When the density of the volune is given a small number like 0.05 to .5, this gives the entire object a slight foggy look. The anisotropy value is set to about 0.3. Anisotropy is basically getting a different look from different angles(this is such a deep topic that deserves its own post).
When another object with emission shader is placed inside the volume object, voila you get cool rays from the emission object that give the scene depth instead of just being normal lighting. This is called volumetrics where you can actually view the light direction. There is a world volume shader which shades the entire world with the particular volume.
So, it’s no surprise that most of my renders have crazy colored emissions and volumetrics.
Freaky Wireframes
Let’s talk about the wireframe modifier. Looks like just another boring modifier but honestly one of the more powerful modifiers available.
It takes a solid object and converts it into another solid mesh with the original object’s edges. The more you difficult the merrier.
The offset value determines if the mesh appears inside or outside the original object, essentially allowing you to create cool effects with a duplicated object along with the original. More cool effects if used with the boolean modifier
The vertex group provides an area in which the modifier is to be applied
Thickness factor determines the sharp or round edges for the new mesh work that is created.
Replace original replaces the original mesh with the created mesh essentially creating a new object.
That’s all there is to know about this particular modifier but not all of it’s applications. One crazy use i found was creatting veins in a leaf. The top modifier on my favourites list only after the wave modifier.
Bellman, Markov and the Q
Surfing through some hackerrank profiles, I found a guy, who made an AI chess addon that can view any chess board in a browsre page and provide a continuation for it. Which got me really interested in AI and spending money on udemy.
The concept that was the base of all the AI magic was the bellman’s equation.
It describes that the value of any state of an environment as the maximum sum of reward for performing an action and the value of the next state.
The bellman’s equation goes like so
V(s) = max(R(s,a) + ∆V(s’))
But this equation is for static environments with no probability.
For environments with a probability factor, markov equation gives an equation with consideration of randomness
V(s) = max(R(s,a) + ∆*sum(p(s,a,s’)V(s’)))
But even better is the concept of q learning. The base concept of q learning is that, instead of giving values to a state and action, we definitely the quality of an action. This has the effect of separating each state based on the actions it can take and prescribing the best action to take also considering random probability.
Q(s,a) = R(s.a) + ∆*sum (p(s,a,s’)*max (Q(s’,a’)))
This recursively gives the action based on previous action quality, thereby providing more accurate Intel and paths to traverse the environment.
The temporal difference is yhe difference between previous q value and newly calculated q value based on new information. This temporal difference is dynamic and chooses best action based on previous and current data
TD(a,s) = R(s, a) + ∆max (Q(s’, a’) – Qt-1(s, a))
And
Qt(s,a) = Qt-1(s,a) + ∆TDt(a,s)
=> Qt(s,a) = Qt-1(s,a) + @(R(s, a) + ∆max (Q(s’, a’) – Qt-1(s, a)))
Which may look complicated but simple enough and means that current Q value depends on previous Q values and the current reward thereby changing any value dynamically based on rewards acquired. If the new value is low the old value is kept as such. Rewards can be given at any state of the environment, gaining accurate control and precision over the agent
R – reward
V – value
Q – quality
P – probability of an action (or randomness in environment)
TD – temporal difference
You can always teach a new dog new tricks, if it’s willing to learn.
Domain System
The domain name system, DNS for short is one of those creative ideas that make human life easier on the internet. The system is for converting human understandable domain names into ip addresses for easy relembrance and searching of a particular ip address.
There are four important parts for a smooth domain retrieval. They are the recursive DNS retriever, the Top Level Domain nameserver, root nameserver and authoritative nameserver.
The recuesive retriever is the first one to recieve the user input ‘theserver.com’ this then queries the DNS root nameserver.
This then sends the query to a TLD nameserver which has the .com level domain.
The TLD replies with the domain nameserver consisiting of theserver.com domain name which then sends the ip address of the domain.
Finally the DNS resolver responds to the user browser by providing the ip address found, and renders the webpage that is to be shown to the user.
The crazy cool thing is how a computer figuratively understands human language does what needs to be done by itself.
Vacuums and tubes
Disassembling an old tape recorder, I found there were tiny bulb structures that didn’t seem to light up (or have tungsten for that matter). Upon research I was surprised to find that there was a time in history where silicon was just sand.
This was the period of vaccum tubes. This is a creative engineering solution for computing problems.
The tube consists of two electrodes(as usual) the cathode and anode. The cathode is heated which produces electrons due to a phenomenon called thermionic emission. The concept is that metals emit electrons when heated. These electrons reach the anode due to the positive potential at the anode. This creates a currentflow from anode to cathode(electricity flows opposite to electrons).
Thereby it essentially creates a diode (di-electrode??). Diodes conduct in one direction only. This diode was used mainly for rectification of ac to dc.
For transistors, a thurd electrode was installed in between the cathode and anode. This was a metal mesh which was given an external negative supply voltage. This negative voltage repels the electron flow. By controlling the voltage level we can essentially control the circuit current creating a triode.
Triodes are mainly used as amplifiers because they are in essence an electric switch. This triode was also used to construct logic gates.
There was even a variant with four and five electrodes, the two additional eoectrodes called screen grid and suppression grid for further control of electron flow.
The entirety of the tube is kept in vaccum to provide clear paths for the electrons.
Now that, is something to marvel about.
Problem with Binary
Confusion arose when the lights turned on when they were supposed to be off and lit the room blue.
The LED was connected to pin 18 of the gpio and given an on pulse. But nothing interesting happened. When the off signal was given, the LED started off.
Upon investigating the problem in the strange waters of the internet, there were a lot of confusing answers and I realized the fact that a basic understanding of how LEDs and gpio works was essential.
GPIO input/output pin works by sending a 1 for on pulse and a 0 for off pulse. 1 represents sourcing and 0 represents sinking current. So 1 doesn’t necessarily mean turning the connected device on. It just means a current is sourced.
If the anode of the LED is connected to the I/O port the port can provide only a 12mA current source. This means th LED doesn’t have enough current.
But if the cathode was connected to I/O instead, and the anode to the 3V supply, (more than 20 mA) full brightness can be reached but the configuration is inverted and LED turns on, when the 0 pulse is given and off when the 1 pulse is given.
The best way to adress this boggling issue is to change the configuration in the code from 1 for on, to 0 for on. Although this sounds like a workaraound, truth is, no one cares how it works and just wants to see that light glow
Problem with Binary
Therw are two protocols for internet traffic.
TCP(transmission control protocol) is the safe and secure protocol. It engages a three way handshake with the recipient. The first phase is the SYN(chronous) where it establishes and verifies connection with the neighbour. The second phase is the SYN ack(synchronous acknowledgement) where the recipient computer ensures connection. The third phase is acknowledgement when the sender computer acknowledges the SYN ack and starts sending data. This method is slow and takes a lot of bandwidth but is extremely secure. If there is a loss of data packet, TCP asks the sender to resend that particular packet
But, UDP is all about dat speed. It doesn’t even verify SYN, but keeps on sending packets without any concern for the recieving computer. The advantage is it’s high speed and bandwidth.
Personally, I prefer UDP, because loss or frame has a very low probability of occouring and ofc everyone prefers fast over secure
Blindfold and Perms
Solving the Rubik’s cube sub-one minute is cool, solving it sub five is probably overkill. But solving it blindfolded is a whole another story. It isn’t hard or anything until you reach the world of parity. Let’s get some basics straight
Lets forget orientation for this one and focus on permutation. From the permutation groups field in mathematics, the edges and corners of a rubiks cube can only be shuffled around in odd numbered groups(excluding one, because you can’t switch a single piece, duh).
The problem arises when two edges and two corners are switched. This occours in 50 percent of solves. Speaking plainly the parity inverses itself for single turn of any face of the cube.
But, don’t turn that face too fast because remembering cube positions is hard enough without having to calculate ten different transitions in blindfold solve. Common algorithms can switch only 3 edges or corners. Thats when the T perm comes in. The cool algorithm swaps edges 2-3 and corners 2-3. Its a leap akin to an ant moving into the third dimension (and thereby solving string theory).
This means that any algorithm that swaps even numbered pieces is a permutation parity solver. The other perms like J perm and F perm look more appealing than the T perm but as far as solving the parity goes, only one face rotation is enough, as long as you don’t have that blindfold on.
Hard Not Tough
I was always confident that diamonds can be broken with a hammer. But my world was shattered when a guy hit a diamond with a hammer and it made a dent on the anvil. A few seconds later the same guy broke it with a comparitively powerless hit. There was definitely something shiny here.
To understand what was going on I had to understand the difference between hardness and toughness.
Hardness is the material’s resistance towards plastic deformation
Toughness is the material’s ability to absorb energy without shattering.
Diamond is extremely hard but not tough enough. You can scratch any surface with diamond but diamond breaks when enough force is applied.
But what about the dent on the anvil? That arises from the fact that the crystal structure has various planar surfaces. Of these planes some split without much energy and others require a lot of energy. Hence,hitting a diamond on its octahedral plane beaks it with a clean cut but on other angles it doesn’t, and dents stuff.
Fun fact, due to its extremely clean cut faces, the diamond face is hydrophobic(doesn’t let water stick) and lipophilic(lets oil stick).
Now that is some crazy physics.
Select stuff the lazy way (in edit mode)
The most annoying thing i had to do in blender was selecting every single edge or corner by myself. Not a hard thing when wwhat you’re designing is small but when its got like 4 subdivision modifiers stuff becomes hard.
So, to select rows of edges or corners that are not even linked but are on the same line, use ctrl + alt + left click
To select alternates from anything you’ve got selected go to the select panel and click checker deselct
Then to select every other linked edge select the edge loops option in select menu.
To select similar stuff, use the select similar option(surprise! surprise!)
This is a great way to select any orientation or edge piece of a heavily subdivided plane on your model
I wish i could remember this, but writing it down seems to etch it to the skull.
Stuff That Leaves Forever
There are certain things that will always come back to haunt you for forgetting them.Such things are quite interesting and are from too niche of a field to be found with a simple search. it seems there are things to be found out everyday. so this is a collection of what I have loved and left my mind blown. Mostly engineering breakthroughs or a creative way to edit stuff in blender and some shortcuts for editing software. this is also an endeavour in improving my memory.