Saturday, December 5, 2015

Scaring off Boston drivers!


I have never driven as many times as I drove today. I wouldn’t have dared before. I guess the Maine trip did boost my confidence in driving in general. I did make mistakes today for which I apologize to all Boston drivers! I hope that you didn’t have to curse too much!

I felt much more comfortable driving on Storrow drive and Memorial drive today than before. The hardest bit was when I crossed the Charles river over Elliot bridge. That intersection is horrible. The lanes are not easy to follow, especially at night and I apologize to the taxi driver whom I almost cut off. I was extremely frightened and angry that I could not figure out which lane to go to. This is why I always look at my route 3-4 times on Google Maps before I go anywhere. I prefer knowing where I am going next. There are other scary places like Assembly square and the intersection of Fellsway street and Mystic Valley parkway in Medford that I completely hate. Who the heck creates a 5 lane intersection? It is the most annoying thing to encounter! You have to figure out which lane to go and switch lanes accordingly in a very short time in fast traffic. :(

Among highways, I-95 is comfy to drive on as it has local crowd. Never driven on I-90 so can’t say anything about that. I-93 is scary. It has inter-state traffic and people are aggressive. You get tailgated if you're not going fast in the slow lane. Smaller routes like route 2 and route 9 are more relaxing to drive on. Highway driving is of course much easier than city driving in general.

Today, while driving, I just wanted to leave the car and come home. I usually avoid driving as much as possible. I seriously hate making scary mistakes while driving. It's not the kind of stress I want to deal with. But I was grateful that I had to drive. It gave me a chance to practice. Thank you David and Clarissa for giving me a reason to drive. In the end, the best policy is to take a leap and deal with the fear!

Wednesday, November 11, 2015

Creating a Node.js web application from scratch Part 2


This is a continuation of the blog post entry Creating a Node.js web application from scratch Part 1. In that previous article, I told you how to create a simple Node.js application and how to do the routing. Now, let's work more on the front-end.

Step 3 - Add Jade Views

Now, you will add Jade views to your application. Jade is an HTML templating library that helps you create HTML views with minimal effort. First you need to tell our application where to find the Jade views. By convention, Jade templates are created in the views directory. And that's what you tell your application code in app.js.


Next, let's add the index.jade file. Jade is capable of parsing HTML tags. So you can use plain HTML in a Jade file.


This means that you need to tell your routing code in index.js to render index.jade for the root path. 


Next, you need to add the Jade library as a dependency for your app.


Now you can run npm install to install the new dependency, then npm start to start the app and test the result.


Step 4 - Make It Pretty!

Now, it's time to make your app look fancy! You need to tell the application where to find the stylesheets. Stylesheets, Javascript files, static HTML files - i.e. all static content goes in the public directory by convention. So, tell your application to use the /public directory to look for static files.


Next, add the style.css file. This just paints the application background gray.


For kicks, update the Jade file to use actual Jade templating code. As you can see, the link tag is used to include the stylesheet.



Now, restart your application and hit http://localhost:3000 to test out the result.



And there you go! It's gray! And we're using a real Jade template. This is just the beginning. You can do many many things with your application - connect it to the database, create end-to-end use-case flows and what not. But with these blog entries, hopefully you've successfully launched your endeavors!

Happy coding! Cheers! 

Creating a Node.js web application from scratch Part 1



My team member, David and I submitted a web application for the Blumixathon. This was David's very first web application. He had many questions. To make things easier, I created step by step screenshots of the bare bones beginnings of our app and used them to explain the process to him. Like David, others could benefit from the step by step explaination.

We created our web application using Node.js, Express.js, Async, Jade, HTML, CSS, Bootstrap, Javascript, Cloudant NoSQL DB etc. 

So here is the step by step explaination.

Step 1 - Create Basic App

This code sample shows a very simple application server written using Express.js. The application server, when started, listens for HTTP requests at port 3000. When you access the application using a browser, it shoudl return the message 'Hello Prachi'.



You also need to write a package.json file. This is the configuration file for your Node.js application. It allows you to configure details such as the application name, version, description, how to start the application, the Node.js libraries that your application uses, the Node.js engine to use and so on.


First, run npm install to install the dependencies that your application needs. Next, run npm start to start the application.


Hitting the URL http://localhost:3000 in a browser, shows you the very first resopnse from your application.


Step 2 - Move Routing to Routes Directory

The next step is to move the routing to index.js and use the Express.js Router. Instead of telling your server what to do when a request for a certain path comes in, you tell your server where to find that information, i.e. index.js. Generally, the convention is to keep the routing files in the routes folder



At the moment, you only have one route. But you can add more as needed. To verify that the routing is working correctly and requests are being handled by Express.js, change the response message for the root path to 'Hello David!'.


Restart your application from command line and here's the result.



In the next blog post entry, I will show you how to add Jade views and CSS to your Node.js web application. Note that these blogs are meant to help you create a very basic web application - only the very basic requirements. For complex requirements, please refer to formal Node.js documentation.

Wednesday, November 4, 2015

Is flexbility really necessary?


An annoying feature in Git Scm is the ability to execute a task in multiple ways. For example, you can create a new branch using either of the two commands:

i. git branch <new-branch-name>
ii. git checkout -b <new-branch-name>

The second option gets executed more frequently as it involves creating a new branch and checking it out as well. The first option only creates a new branch.

Another similar example is the git pull command. The git pull command is equal to a git fetch + git merge. While this provides more flexibility, it often means that git pull gets executed more frequently than fetch + merge. 


It would be interesting to see examples of cases where one only needs to fetch changes, but not merge them or when one just needs to create a branch without checking it out.

Tuesday, November 3, 2015

Understanding Pylint Warnings


I have been fixing pylint errors for a new codebase and trying to understand what the pylint errors, warnings, refactor-suggestions and so on mean. If you run pylint for your Python programs, you might’ve encountered one of the following warnings:

Dangerous default value [] as argument
Dangerous default value {} as argument

I found an article that gave a simple example to explain why. I read their explanation and tried their examples.

>>> def foo(x=[]):
...         x.append(1)
...         print x
>>> foo()
[1]
>>> foo()
[1,1]
>>> foo()
[1,1,1]


>>> def foo(x=None):
...        if x is None:
...            x = []
...        x.append(1)
...        print x
>>> foo()
[1]
>>> foo()
[1]
>>> foo()
[1]

I still couldn’t understand what it meant. I re-read the explanation. And then it hit me. There are 2 factors responsible for this behavior:

  1. Python has mutable and immutable data types. Dictionaries, lists, sets, etc are mutable. Strings, floats, integers, booleans etc are immutable.
  2. Default arguments are instantiated as objects during function definition time

If you invoke a function without any argument when its default argument value is immutable, the default value itself does not get updated within the function. It’s immutable. And the same immutable value is used as a default argument every time you invoke the function without any argument.

If you invoke a function without any argument when the default argument value is mutable, the default value does get updated within the function as it is mutable and can be changed and the same default object is used every time you invoke the function without any argument.



Thursday, April 16, 2015

My favorite Kindle Unlimited books

SPOILER ALERT: Contains book spoilers. Please do not read the book descriptions if you have not read the books before. You don't want to kill the suspense.

I read a lot of fiction. So when Amazon launched Kindle Unlimited, I immediately got the subscription. You can download upto ten Kindle Unlimited ebooks at a time. Some of them are big favorites of mine and I have not returned them. I don't want to forget their names as I want to be able to read them whenever I want randomly. And as I said before, I read a lot of fiction. So I may forget their names even if I remember the storyline.

Today, I got an idea. I'll blog my favorites. This way I can return them and stop feeling guilty. :)

So here goes:

1. Breakthrough and Leap by Michael C. Grumley: Breakthrough is a sci-fi/thriller. Marine Biologist, Alison Shaw has found a way to talk to Dolphins. John Clay works in the investigations department of the U.S. Navy and is trying to figure out why a ship's position changed by 15 miles unexpectedly. When he and his partner, Cesare use a probe, the probe is lost, but not before the video records a strange ring. John takes help from Alison's dolphins to figure out the mystery... which turns out to be a worm hole created by aliens who are trying to syphon off our water to their planet. In the second book, Leap, Clay and Cesare are trying to figure out why a Russian sub is parked in Brazilian waters and why a Chinese warship has landed in Guyana? Turns out to be more sci-fi, more alien intervention and more adventures. :)
2. Departure by A.G. Riddle: This is a very inspiring book. It's focus is on 4 individuals who get pulled into the future by their future selves who have made mankind make major scientific leaps. Their future selves want them to change the past to avoid an impending war... makes me think of the possibility of parallel universes. It's super cool!
3. End of Secrets by Ryan Quinn: This felt a lot like an artistic piece of work.... felt like a war between the good and the bad. The rich and successful playboy Rafael Bolivar, has an idealistic view of how things should be just like a painter. Him and a bunch of artists, who keep on disappearing one by one. And the villain is... ONE corp who's secretly trying to gather every piece of information about every human. CIA agent Kera Mersal is working undercover as a reporter for an undercover agency to figure out why and how the artists are disappearing. Turns out that her boss and organization have gone rogue and are in league with the villains. The book creates a lot of suspense and nail biting moments as you're trying to find out the truth. What's going to happen? There's blood involved. And of course the unanswered question... what about the future? So what if the revolution succeeds? Will that change things in the long term? We can't win the eternal war against our inner demons forever. There is a good chance that Gnos.is might loose popularity over time. The truth is harsh and we are not emotionally equipped to deal with it all the time. Sometimes, an illusion can be our saving grace.
4. Guardians of Stone, Fountain of Secrets, The Lost Chalice  by Anita Clenney: These 3 books form the 'Relic Seekers series'. Kendall is a gifted relic seeker who can sense emotions, events, people, fact, information etc about any object by touching it. She is supermodel material, but not very social. And she's got two sexy colleagues. Her boss Nathan is a billionaire who has a huge relic collection and also happens to be her long lost childhood friend Adam. He just doesn't remember it. And he's got superpowers of his own which he keeps of thinking of as a curse. Jake is a security expert and takes his responsibility to protect Kendall seriously. And he can't keep flirting with her either. Together, Kendall, Nathan and Jake go on magical adventures to find and protect the powerful historical relics - the Spear of Destiny, the Fountain of Youth and the Holy Grail. They're being helped by the Prottetori who have been protecting four historical relics among many other treasures forever. And the villain is... the Reaper who used to be part of the Protettori but betrayed his brotherhood and who also turns out to be Jake's dad. FYI the Protettori folks have been around for hundreds of years cause they keep on drinking from the Fountain of Youth. I wonder how the Reaper stayed alive all this time considering that he didn't even know where the Fountain of Youth was being protected until the very end of the second book. And did I tell you that Kendall, keeps on having visions of King Arthur, Guinevere and Lancelot in which she looks awful lot like Guinevere, Jake looks exactly like Lancelot and Nathan appears to be King Arthur. Sometimes Jake and once even Nathan share her visions. Kendall suspects that the three of them are re-incarnations of the two knights and their lady. No wonder she feels such a deep bond with both of them. And no wonder Jake and Nathan keep on worrying about each other even though they drive Kendall crazy with their constant bickering. If there's a fourth book ever, it will be about the Tree of Life which is the fourth relic. That should be fun. If you liked Lara Croft movies, then you will love this series.
5. Cyberstorm by Matthew Mather: This is another ultra cool book. It tries to show us a New Yorker's experiences when the country's entire infrastructure is broken down by foreign entities by breaking down the network and by creating a Cyberstorm. People are fighting for food and water. There's no power or heat and a huge storm's hit New York. The book shows us how dependent we are on these systems for our survival.

And now I can return those books and get different ones!  ;)

Friday, April 3, 2015

NGINX you rock!

I have been learning NGINX for some time. The more I learn it, the happier, I get. I love that these guys are focused on the actual problem that needs to be solved - a good product that tries to solve the important user requirements well instead of trying to do everything. Their philosophy is reflected in the documentation and is very inspiring. They're humble. This hit me while reading NGINX: If Is Evil. Just read the sentences. They're blunt. The authors accept that there is a problem. No schmoozing! Just genuineness!

Saturday, March 14, 2015

I choose to live

What do you do when you feel yourself inching towards a viral infection or the flu? Or what do you do when you wake up one morning to a sore throat, congested nose and a flat voicebox? You fight... because of you don't, then you get caught in the grip of a runny nose, sticky hands, headaches, feeling hot and cold, painful ears, painful lung and a sluggish brain... in short a couple of days of pure misery. You're not completely down, but you are not completely alive either. You have to think harder to come to conclusions. You avoid going out cause it's cold. You isolate yourself from friends to avoid spreading the sickness. All you can think of all day is your warm cosy bed... but your bed has all the germs from last night which totally ruins the rosy picture you want. Your table is sticky. Your keyboard is sticky. It's a mess.... so yeah you fight.... and here are a  few pointers...
1. Drink lukewarm water till you get well. Don't boil it and don't drink it cold. Drink it lukewarm. Hot water is painful on your tongue and tastes horrible. It will make you want to puke and you will try to gulp down cold water instead. Which will be a relief for five seconds before you notice it's coldness hitting your raw painful throat. It will make the throat infection worse and you more miserable. Don't drink it no matter how much you have to push yourself to turn on the gas and warm up some water.
2. Use soft tissue paper. Regular paper towels are harsh and will give you rashes. The best thing is to buy a bag of toilet paper dedicated for your nose. Toilet paper is soft. Buying a bag means you won't have to worry about running out of tissue paper. And you won't use the same rag repeatedly on your nose which will just keep you in touch with the germs and hence sick. Using the same rag repeatedly also causes  you not to blow your nose enough which will cause the phlegm to accumulate in your head and chest. This will give you a headache and breathing problems. It will keep you sick for a longer period. Use tissue paper. Whenever you feel phlegm in your nose, blow your nose, and throw away the used tissue. If you use toilet paper, less will be wasted as you will tear only that much which is needed to blow your nose once. If you feel phlegm in your throat, go to the bathroom sink, look up at the ceiling. The phlegm will rise up your throat and into your mouth. Spit it out. Keep your nose and throat clean. It keeps your airway clear. Best, keep a carry bag in your room to throw away the used tissue. Once it's full, close it and dispose it. Put and new carry bag in your room.
3. Gargle every day. Boil a glass of water, mix a pinch of salt in it and gargle every day. This is to kill the germs in your throat and cure the infection. A doctor once told me that it cures 50% of the disease. You need to do this during the period when your throat is painful and sore. When the infection starts getting cured, your throat will get itchy and you will want to cough like an old person. Don't cough. Buy halls with honey flavor to sooth the itching and keep it in your mouth.
4. Keep your room clean. Wash your sheets regularly. Wipe your keyboard, table and other surfaces with CLOROX wipes or Dettol. Do your laundry every day. Open your windows for some time every day to get rid of the dank air.
5. If you went to the doctor, and got medicines, take them regularly on time without fail. Ask the doctor to give you a night dose that will make you sleep. If you are not well rested, then you will be sluggish and will not take good care of yourself which means a slower recovery. Nyquil might not always be enough. Also make sure to get a morning dose that doesn't make you sleepy. You want to be awake during the day. Else you won't do your regular work properly or take good care of yourself which again leads to slow recovery.
6. I also drink hot ginger tea to help my throat. If you can't do that,  that's okay. Just take the medicines.
7. Taking steam will also help fight the throat infection and help you heal faster. Do it once per day.
This must feel like waging a war. And you are waging a war... against a virus that will suspend your brain functions so that you are in a haze. You are just surviving. I'd rather be alert, awake and energized every moment of my life so that I can think and feel every moment. I choose to live... to really live. What about you?

Wednesday, March 4, 2015

I don't want guitar calluses

While going to the Chinese Parade, I was telling Tess about how my fingers hurt during Guitar practice. She said, "Oh yeah, you will get Guitar calluses." My mouth fell open. "What are Guitar calluses?" I asked. Tess responded, "Eventually you develop calluses from playing Guitar and your fingers become numb. You loose sensitivity." And I was like, "But I don't want to loose sensitivity in my fingers. I like my fingers the way they are." I immediately pulled out my phone and googled Guitar calluses. Most people said, "Live with it. It is the way it is. There's no way to avoid getting them." A few random posts suggested ways to lesson the calluses. And then I found a post from a person saying that he has been using a well fitted golf glove while playing Guitar and has never gotten calluses. So I googled Sports shops in the Chinatown area. After watching the parade, we walked to a couple of them and found golf gloves in City Sports. The gloves definitely dimmed the pain during practice, however, they increased the surface area of contact per finger. It was making me hit multiple strings at the same time. In the end, I just tossed the gloves off and practiced without them. I still don't want the calluses. Hopefully I will figure out a way soon.

Monday, March 2, 2015

Celebrating the Year of the Goat

Tess and I went to Chinatown area yesterday to watch the Chinese Parade that is held one week after the Chinese New Year. The procession started with a banner and boys walking with colorful flags.
They were followed by 3 dragons going from shop to shop and dancing. The dragons were followed by a motor-powered cart carrying the instrument players.  The purpose of the parade is to bless shops good luck for the coming year. The dragons would dance in front of each shop and sometimes even go in. Then firecrackers were burst in front of the shop and the dragons would move to the next one. I also saw a man wearing a costume although I couldn't understand his role.



To understand the ceremony better, I read up about it online. It was an interesting read. When the dragons visit a shop, the shopkeepers offer dragons oranges and a cabbage to consume to please them. The dragons accept the offerings, smash the cabbage in front of the shop to bring good luck for the shop and throw the oranges in the crowd. Whoever catches an orange is said to have a lucky year ahead. The firecrackers are meant to chase the bad spirits away.




The dragons also climbed on top of each other in the middle of the road. Small children gathered around them to watch the spectacle. It was a refreshing experience to see tradition in the midst of urbanness.

Sunday, March 1, 2015

Stackoverflow... I finally get you

Stackoverflow and all its sisters are very frustrating to use. You have to earn the right to do anything except posting questions and answers. Yesterday I was discussing this with a colleague, Chris and he enlightened me why.

I was unhappy that I had to earn the right to add comments in order to ask follow up questions. Given a specific question and its answers (of which one is the accepted answer), I might have questions about the answers themselves. Or the answers could apply to the person who posed the question, but not to my situation. It is hard to provide an accurate and universal answer especially for any Engineering related question as Engineering problems tend to be complex. I could have questions about the question itself too. Some people tend not to be specific. Chris said that Stackoverflow discourages discussions. They want high quality questions and answers. An answer is considered high quality if it is accepted by the person who asked the question. Upvotes also help increase its credibility. Another reason to make people earn the right to comment is to avoid silly comments like '+1' and 'Thanks'. And to ensure that people are being fair while upvoting/downvoting questions and/or answers, the right to do so also has to be earned. You earn these privileges by increasing your reputation. And how do you increase your reputation? Simple, answer as many questions as possible and ask good questions. Your reputation increases with the upvotes you get for your questions and answers and decreases if you get any downvotes. The downside is the competition. Everyone wants a high reputation. So people answer questions aggressively. Chris said that he's frustrated every time he tries to answer a question and someone else answers that question just seconds before his answer. If the other answer gets accepted, then it's a waste of effort to have answered the question. The accepted answer tends to get upvotes.

Chris said that despite all of this, it is still possible to have discussions on a topic. Stackoverflow and all its Stackexchange sister sites have meta communities just meant for discussions. That is exciting news for me because I want to be free to ask as many questions as necessary to understand concepts. He said that another way to deal with follow up questions is to ask another question and describe it clearly enough to distinguish it from the initial question. He explained that this also improves the Search Engine Optimization for that particular topic as users would get all 20 questions related to it and any one of them could apply to their situation. Comparatively, it's harder to find things if related questions are hidden in follow up comments to a question. 

After a long discussion with Chris, I understood Stackoverflow much better. They want to have responsible users - people who contribute by answering other people's questions, not just by asking questions. Their vision is a high-quality reference on every topic created and maintained by the same people who use it.

Friday, February 27, 2015

Prof... how do I get there?

Today I watched Larry Smith's TED Talk (https://www.ted.com/speakers/larry_smith). Larry Smith is an Economics professor who helps his students pursue their passion. In the talk, he said that we are afraid to pursue our passion. We are afraid to look stupid and find any excuse to avoid doing what we really love to do. He said that a person might have 10 interests out of which one could be their true passion. He said that we must explore new things of interest continuously until we find our true destiny. Otherwise our talent is being wasted.

The trouble is everyone says that. Find your passion. Do what you love to do. Life is simple etc etc. Nobody ever explains how to get there. For example, while exploring those ten areas of interest, how will I know that I have really explored them? I could write a program and say that hey I explored programming and loved it. How does it really feel to be passionate about something? Once I read somewhere that passion is fuelled by success. The more successful you are at something, the more passionate you become about it. But success is dependent on so many factors that there's no guarantee that what I am passionate about today will be something that I will be passionate about tomorrow. I could be a great programmer today because I am capable of facing the challenges put forth in my plate. What if I face something that I fail at? Will I stop being passionate about programming? With the huge variety of advice we get on passion (it is such an overused word...), how do we know the direction in which to chart our course of action? How does it feel to be on that journey? How does one know that one is going in the right direction? Using the right techniques? Does it bring contentment? Or does it mean being comfortable outside your comfort zone all the time? I would love to talk to people who've found what they're passionate about and are living their dreams. After watching Prof. Larry's TED talk, I wanted to talk to him because he helps his students. I want his opinion on the how.


What do I want out of my life?

Yes I want to find my passion. And once I find it, I want to live it. But irrespective of whether I find it or not, I want to know that I really lived. And I will feel that way only if I know that I completely immersed myself in everything that I do. If I am selling Bananas, then I want to know everything about selling Bananas. I want to know that I did everything I could to the best of my abilities while doing so. In the end, I want to know that I was my best whether I liked what I was doing or not. I want success to be a habit for me. Uptil this point, I have had that feeling of satisfaction for very short bursts of time only. So for the most part, I am not really living. I just exist. My current goal is to fix that. Personally, I feel that that will lead my to my passion. Cause in that case, I will be in a positive state of mind. And happiness is contagious. It makes more of itself. Leads us to make better decisions.

Trivia Quiz!

Today, I went to Newtowne Grille at Porter square with Tess and her colleague kaylee after work. The food was decent w.r.t. the price. We had to stand in the beginning as the place was completely packed. The big attraction was the Trivia quiz. Every table got a questionnaire. The Trivia master was announcing questions. Each team had to provide their answers and team name on a piece of paper and submit it after every question. Most of the questions were about American movies, songs, US geography, history and politics. And I don't know much about any of that. Luckily Tess knows a lot about movies and songs. And to some extent Kaylee too. The only question I knew the answer to was 'Who was the first African-American woman to win an Oscar for a Female Actress in 2002?' The answer was Halle Berry. Although I couldn't recall his name, I knew that the first man to fly in space was a Russian (Yuri Gagarin) because the first man to walk on the moon was an American (Neil Armstrong) and that happened because Americans had to beat the Russians who went into space before them. We had a few lucky guesses. For example Helium is the lightest Noble gas and Aioli is a sauce made using Mayonnaise, Garlic and Olive oil. We also had a few close misses. For example, we were not sure whether or not Lake Michigan was the largest Great Lake totally inside the U.S.. And it is completely inside the U.S. However, our answer was Lake Erie which turned out to be wrong. Overall we had a good time discovering intersting tidbits.


P.S.: It was against the rules to use a google the answers.

Wednesday, February 25, 2015

HTTPS in NGINX

Been reading about NGINX. When you install and run NGINX, its operation is controlled by a configuration file called nginx.conf. This file has a tree like structure that defines contexts with the help of directives. The http context is a misnomer. It leads you to think that HTTP connection settings are governed by the directives defined in it. But guess what, it can also be used to control HTTPS connections. You just have to specify HTTPS directives in it.

http {
server {
listen 80;
listen 443 ssl;
server_name www.helloworldexample.com;
ssl_certificate www.helloworldexample.com.crt;
ssl_certificate_key www.helloworldexample.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
...
}
}

Using this configuration for the http context will enable your NGINX server to handle both HTTP and HTTPS requests.

Tuesday, February 24, 2015

Passing a Boolean in JQuery

Yesterday, while updating a UI to include a boolean flag controlled by a checkbox, I got stuck. The flag was being persisted, but was not being rendered correctly when fetched from memory. I printed the fetched value in a DIV element. It was printed correctly. Then it hit me. It was a String, and not a Boolean. Upon further investigation, I found out that the value was being persisted as a String and not a Boolean. The JQuery Ajax POST request was sending it as a String. I simply fixed the situation by converting it to a Boolean value before persisting. :)

Saturday, February 7, 2015

Why shampoo bottles need to be smaller than conditioner bottles!

Have you ever run out of conditioner even though you have a half empty bottle of shampoo? I used two bottles of conditioner for my last shampoo bottle, which is still not empty. It still has enough for 2-3 washes. Which makes me think... why do shampoo companies make the conditioner and shampoo bottles in the same size? Surely they realize that people need more conditioner than shampoo. Shampoo is soap... it makes hair clean, but also saps it of moisture. I use a very small amount that cleanses. Comparatively, more amount of conditioner is needed to moisturise hair. Not copious amounts, but definitely more than shampoo. And when your conditioner runs out.. you buy some more knowing that you will have to go back again to get shampoo at a later date cause it's not over yet. It gets trickier if you want to try the latest moisture renewing conditioner from Organix with Argan oil. Companies design these products so you have to use the counterpart shampoo with the conditioner to get the best results. So you keep buying the same conditioner until your shampoo finishes... But then you might run out of shampoo and still have conditioner left in the end... and it becomes a cycle. You're stuck! What a mess!

More revelations... How much conditioner does that bottle really hold?

I was so frustrated that I might have to buy a third bottle of conditioner for the same bottle of shampoo that I decided not to buy one until the shampoo finished... so I've been putting water in the conditioner bottle, shaking it and using whatever comes out. I was surprised to notice that everytime, I get enough conditioning foam for my hair. This means that I've been wasting conditioner all this time by throwing away conditioner bottles without properly using all the conditioner in them. This has another depressing implication. Once the shampoo bottle is empty, if I put water in it and shake it, then I will probably get enough shampoo for 2 or 3 more washes. Urrrgh... I just want to throw it away!