CS101 Tips
Beginner's guide to kickstarting programming: CS 101 and beyond!
This blog is aimed towards students undertaking the CS101 (Computer Programming and Utilisation) course at IIT Bombay. But, it is helpful for anyone eager to commence their C++ programming journey.
Introduction
The CS101 course is unique among first-year courses because it accommodates a broad spectrum of participants, from seasoned programmers to those unfamiliar with computers. While we can’t easily bridge the knowledge gap, this presents a chance for beginners to kick off their learning journey the right way, and that’s precisely what this blog is here for. Feel free to incorporate these tips into your programming routine.
The Roadblocks
Contrast with other disciplines
Let us consider other introductory courses such as Physics, Chemistry, Biology, or Mathematics. The key features that set programming apart are:
- Unfamiliarity
- Students lack the same level of familiarity with programming as they do with other courses that they have been studying and developing an intuition for over the years.
- Versatility
- Programming at the basic level focusses on using simple syntax to solve a range of intricate problems, while other courses typically emphasise learning increasingly complex concepts.
In fact, programming bears a strong resemblance to natural languages. As a fixed set of words (syntax) can create any narrative (program).
To give an illustration, consider a repeat
operation, which executes a block of code a predetermined number of times. You would be surprised to know that a single use of this seemingly simple operation can evaluate the following mathematical expressions (of course, we will require a few variables to keep track of values).
Addressing such problems requires a new way of thinking, which I will highlight in a subsequent section. Thereafter, you can apply these insights and discover that coding them is, indeed, straightforward.
In case you’re curious, both of these expressions converge to \(\pi\) as \(n\rightarrow\infty\)
Steep Learning Curve
While the idea of making your computer do the work for you is exciting, the same can not be said about the learning process.
The installation process and usage of terminals, compilers, and code editors might feel overwhelming for beginners. Students may give up after failing to comprehend these steps that they are not supposed to understand in the first place.
But it doesn’t stop there, at one end, there is the syntax of a language, and at the other end, there is an endless stream of unknown errors that one encounters if the syntax is used incorrectly.
This entire procedure requires getting used to, with patience being the key.
Simplecpp
Motivation
To simplify the learning process, IITB promotes the use of Simplecpp1 which introduces programming concepts gradually, focussing on the fun side of programming instead of over-emphasising language syntax.
In fact, you have already seen such example with the repeat
statement discussed in the previous section.
Graphics
Simplecpp takes an interesting approach by introducing programming concepts using Turtle Graphics. There is a turtle on a canvas and the user can control the turtle’s motion using simple commands. As the turtle moves, it leaves behind a path that allows the user to draw some cool graphics, like the one below. The Hilbert Curve of order 5, check out the Simplecpp gallery for more animations
Installation
Refer to the official Simplecpp webpage or videos for os-specific installation details.
The students can also try a custom-made novice version of Code::Blocks IDE (instruction manual) where the Simplecpp package is already integrated. Still, it is recommended to transition to a command-line-based workflow after gaining familiarity.
Alright, enough of chit-chat. Let’s dive into actual tips.
The 5Cs of Programming
These are the steps that I feel would help any beginner to approach a given programming problem correctly. Of course, you will develop your own techniques as you gain experience.
Careful
You should carefully go through the problem statement. Read the entire thing; a problem statement contains not only the problem but also many subtle details, such as
- Input Format
- The data that you need to take as an input.
- Keep in mind the ordering of values.
- Even if your approach is correct, the program will fail if you take the input incorrectly.
- Output Format
- The data that you need to output.
- Ensure there are no additional characters printed beyond the specified requirements.
- If printing floating-point numbers, take note of the required decimal places or considerations for rounding.
- Constraints
- The range of values each variable in the problem can take.
- This is particularly useful for choosing appropriate data types.
- Be aware of ‘corner’ cases that may arise for some variable values allowed in the constraint.
- While not an immediate concern, as the course progresses, you will need not only correct but also ‘efficient’ approaches.
Check
It is important that you check your understanding of the problem using solved examples and practice test cases.
Upon reading the problem, some folks might dive straight into formulating an approach or even start coding without much thought. It becomes apparent only later that their test cases aren’t passing because they got the problem all mixed up, resulting in wasted time.
The practice test cases contain Sample Inputs and their corresponding outputs called Sample Outputs.
For given examples and manageable inputs, you should manually calculate the outputs and match them with the given outputs. This will ensure that you have spent enough time on the problem to get the hang of it.
Compose
Once you have figured out how to solve the problem, you should compose the programming approach on laptop paper. Yes, you read that correctly.
Of course, I am not suggesting you jot down the entire code on paper; instead, work with a ‘pseudocode’.
A pseudocode is an informal outline of code that doesn’t rely much on syntax; rather, its purpose is to capture the flow of the program. An example is provided below.
Pseudocode of Polynomial Division, \(\operatorname{LT}(f)\) denotes the leading term of the polynomial \(f\)
While a pseudocode can not be directly executed, an experienced programmer will be able to understand the essence of the pseudocode and then translate it into an executable program.
Consolidate
Now, consolidate your approach by finalising data types and verifying their correctness on test cases by performing dry runs.
Finalise Data Types
- Always assign data types to variables according to the data they hold. Look at the constraints and your approach to figure out the range of values each variable can take.
Examples- If a variable is always an integer, then it should be assigned an
int
data type - If a variable can take large values, then consider using ‘longer’ counterparts of respective data types
- If a variable is always an integer, then it should be assigned an
- Whenever feasible, prioritise using integer data types over floating-point data types, which can be imprecise due to floating-point errors. Some problems may initially seem to require floating-point numbers, but with careful consideration, you might find solutions using integers.
As an exercise, let’s try solving the equivalent fraction problem with only integers. Here, you are given four integers \(a, b, c, d\), and you have to determine whether the fraction \(\cfrac{a}{b}\) is equivalent to \(\cfrac{c}{d}\).
It is evident that \(\cfrac{a}{b}\) is equivalent to \(\cfrac{c}{d}\) if and only if \(a\cdot d = b\cdot c\)
However, a keen observer will notice that for large values of \(a\) and \(d\), \(a\cdot d\) can ‘overflow’.
After some thinking, you might realise that a better equivalent condition is “\(a = c\) and \(b = d\)” provided both the fractions are in reduced form. That’s our solution!
Now, use type conversion to compute expressions containing variables of different data types. This also makes your program unambiguous.
Some data types to keep in mind
char
bool
short int
,int
,long int
,long long int
and theirunsigned
counterpartsfloat
,double
,long double
Perform Dry Run
A dry run is a manual simulation of the program used.
Performing a dry run is one of the most crucial steps in debugging, yet unfortunately, many beginners overlook its importance.
Follow the below steps to identify any mistakes in your approach
- Select a test case
- Manually trace the value of variables in the code (or use
cout
to output these variable values). - Check if the values of variables match with their expected values.
- If any variable values don’t match at any point, your program is incorrect; consider debugging or rewriting it.
- If all variable values match consistently, Hurray! Your program is correct ‘for the current test case’. Now, repeat the same procedure for a different test case :).
- Manually trace the value of variables in the code (or use
Code it up
Finally coding! If you have followed the above steps perfectly, then we are most likely done.
All that’s left is to follow some good programming practices :).
Otherwise, you will have to backtrack through these steps to identify the issue(s).
I have listed some common errors that students make below to help you in debugging.
Debugging
What Can Go Wrong?
Well, recall Murphy’s Law: “Anything that can go wrong will go wrong”. Courtesy: StackOverflow
Some Common Errors
Familiarise yourself with common syntactical errors by reviewing this article.
Based on my (and my tutees) experiences with Simplecpp, I am outlining potential reasons for unexpected behaviours below. I hope this helps.
Compilation Errors
- Missing
- semicolons
- curly braces
- multiplication symbol (
ab
instead ofa*b
)
- Variables defined out of
scope
.
No output
- Uninitialised variables
- Division by zero
- Infinite Loop?
- Accessing out-of-range indexes
Wrong output
- Integer overflow
- Logical error
Test case passing locally but not online
-
pow
function (for older C++ versions such as Simplecpp)
when the involved variables are integers, consider trying out binary exponentiation instead - Uninitialised variables
- Accessing out-of-range indexes
This occurs when the program has undefined behaviour. Depending on compilers, the output may vary, or you might even encounter an error. The official documentation provides a detailed explanation and more such examples.
Best Programming Practices
Trust me, after a year, you will struggle to understand your own code. If you want your code to be helpful in the future, consider following these practices.
This article delves into the first three practices in detail. The last two practices would be too much for the small programs we write in CS101 but do try to follow the first three.
Naming Conventions
Use explanatory names and consistent naming schemes for variables, functions, classes, etc. You may use any of snake_case
, PascalCase
or camelCase
or devise your own crazy conventions, but make sure different elements of your code are distinguishable.
Indentation
Indenting greatly improves code readability, especially in C++, where determining scope
is important.
Comments
A short comment goes a long way in helping your future self, especially for complicated code snippets where the approach is not obvious.
Error Handling
This is best explained by an example.
Suppose you have a function gcd(a,b)
to calculate the greatest common divisor of two numbers \(a\) and \(b\). What happens when both \(a\) and \(b\) are zero? The answer is ‘undefined’, but without proper error handling, the code might end up in an infinite loop or attempt to divide by zero. Therefore, the code should show an error when it receives incorrect inputs, and this can be accomplished using the assert
statement.
Documentation
A well-documented code explicitly includes the following, either somewhere in the same file (preferably at the top) or in a separate README.md
file.
- functionality of the program
- instructions on usage
- input requirements
- output specifications
Refer to the documentation for this image grid tool2 to get a better idea of the last two practices.
Practice Programming
Offline Problem Set
Kudos to you for making it this far into the blog. However, there is no secret to improvement other than more practice.
Below is a problem set3 that I have worked on over the years. Problems range from using our familiar repeat
statement to recursion.
I have created these problems with the intention that you’ll learn something new from each of them while having fun. Each section builds on the next, so try to solve the problems using only the topics mentioned in that section and the previous ones.
Give it a go! I highly recommend the last two sections to anyone interested in understanding how programming interconnects with other fields.
I also showcase interesting solutions from students here. If you have solved a problem and would like to be featured, feel free to reach out to me.
Online Judge
There are also numerous websites where you can practice coding; however, these problems are generally more challenging than the ones above, as they may demand knowledge beyond CS101.
Most of these sites have tutorials, practice problems and contests, but I have only described their most popular feature.
CSES Problem Set | A concise yet impactful set of problems |
AtCoder | For ad-hoc and mathematical problems |
Codeforces | Short contests |
CodeChef | Long contests |
LeetCode | Coding interview problems |
HackerRank | Popular test platform for companies |
SPOJ | Extensive problem bank |
USACO | |
Project Euler | For math enthusiasts |
More Resources
Articles
C++ Documentation | The Bible |
In-depth Tutorials | Surprisingly good |
Algorithms for Competitive Programming | Essential for solving coding problems online, not for this course |
Playlists
An Introduction to Programming through C++ by Abhiram G. Ranade | NPTEL Course using the Simplecpp approach |
C++ Full Course by Apna College | Videos in Hindi; only a select few from this extensive playlist are relevant |
C++ by The Cherno (Courtesy: Tirthankar Mazumder) | Learn C++ the ‘correct’ way |
Videos
Select videos that are both fun and helpful
Floating Point Numbers | Computerphile | |
Why Computers are Bad at Algebra | Floating point numbers but more technical | Infinite Series |
Binary, Hanoi and Sierpinski: part 1, part 2 | Get comfortable with the concept of binary numbers | 3Blue1Brown |
5 Simple Steps for Solving Any Recursive Problem | Reducible | |
What Is Big O Notation? | Always handy to know about | Reducible |
The Discovery That Transformed Pi | A story about calculating \(\pi\) | Veritasium |
Great Impractical Ideas in CS: PowerPoint Programming | A must-watch | Tom Wildenhain |
The Most Difficult Program to Compute? | Computerphile |
Computer Science for Fun
YouTube Channels
Tom Scott | Known for his series ‘The Basics’ |
Computerphile | Just computers and computer stuff |
Reducible | Covers some big, important ideas in computer science |
The Coding Train | Tackles interesting ‘simple’ problems involving graphics, kinda like my problem set :D |
WilliamFiset | The data structures guy |
3Blue1Brown | The math guy who occasionally codes |
Stand-up Maths | The recreational math guy who occasionally codes |
Mathologer | The visual math guy who occasionally codes |
CppCon | The conference for the entire C++ community, from novices to experts |
Videos
Some select videos that explore computer science concepts in other domains
Application Programming Interface | This Video Has _ Views | Tom Scott |
Pseudorandom numbers | Random Numbers with LFSR | Computerphile |
Cryptography | Cracking the Cipher Challenge | Simon Singh (GOTO 2016) |
Error Correction | But what are Hamming codes? | 3Blue1Brown |
Information Theory | Huffman Codes | Reducible |
Signal Processing | The Fast Fourier Transform (FFT) | Reducible |
Image Processing | The Unreasonable Effectiveness of JPEG | Reducible |
Computer Graphics | Building Collision Simulations | Reducible |
Books
Computer Science Books for Fun
A Brief History Of Computing | Gerard O’Regan |
Code: The Hidden Language of Computer Hardware and Software | Charles Petzold |
Hackers Delight | Henry S. Warren |
Nine Algorithms That Changed The Future: Ingenious Ideas That Drive Today’s Computers | John MacCormick |
Algorithmic Adventures: From Knowledge to Magic | Juraj Hromkovic |
Guide to Competitive Programming: Learning and Improving Algorithms Through Contests | Antti Laaksonen |
The Code Book: How to Make It, Break It, Hack It, Crack It | Simon Singh |