Post

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).

\[{ r_n = \dfrac{4}{1+\dfrac{1^2}{3+\dfrac{2^2}{5+\dfrac{3^2}{\ddots+\dfrac{n^2}{2n-1}}}}} }\] \[{r_n = 2 \cdot {\frac {2}{\sqrt {2}}}\cdot {\frac {2}{\sqrt {2+{\sqrt {2}}}}}\cdot {\frac {2}{\sqrt {2+{\sqrt {2+{\sqrt {2}}}}}}} \cdots \frac{2}{\overbrace{\sqrt{2+\sqrt{\cdots{\sqrt{2+{\sqrt{2+\sqrt{2+0}}}}}}}}^{n\ 2\text{'s}}} }\]

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. Desktop View 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 Pseudocode of Polynomial Division 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
  • 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 their unsigned counterparts
  • float, 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 :).

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”. Programming Cartoon 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 of a*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

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

Books

Computer Science Books for Fun 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
This post is licensed under CC BY 4.0 by the author.