Harvard CS50 Week 1 Lecture 1 – C with Pset 1

Demanding, but definitely doable. Social, but educational. A focused topic, but broadly applicable skills. CS50 is the quintessential Harvard (and Yale!) course.” – Harvard CS50


What better way to learn about computer science than from Harvard’s popular Introduction to Computer Science course – CS50. The course has become very popular in the last decade thanks to the incredible teachings by Professor David J. Malan. Students around the world have become big fans of his work and many of them are greatly inspired to study the deeper workings of computer science such as web development, cryptography, and artificial intelligence. As someone who has only studied iOS development, not understanding the basics of Computer Science has been limiting my abilities in software design and development.


I was lucky enough to attend CS50 in person at Harvard University in Fall 2017. In this blog, I will briefly talk about each lecture and how I approached each problem set. For the guidelines and problem set specifications, please visit cs50.tv. 


To be eligible for a verified certificate from edX, you must receive a satisfactory score of at least 70% on each of the 9 problem sets and submit a final project that draws upon the course’s lessons. If you are interested in getting started, visit cs50.edx.org. You will not regret it! Let’s get started.


Lecture 1: C

Welcome to Lecture 1, where we dive into writing the code rather than coding graphically with Scratch. We are introduced a programming language called C and those who have a background in programming may wonder why we’re learning C, a rather low-level language and much more complex than others we use today in the tech industry, take Python or Swift as examples. As David mentioned in the beginning of the course, CS50 will not be teaching you how to program in a specific language, but it will teach us how to think algorithmically and using programming languages as a tool to problem solve. 


By learning C as the course’s primary language, we are learning the language of computers. It is a language that is closest to a computer’s hardware before assembly language and it allows us to appreciate higher level languages such as Python and Swift and to not take them for granted. But why listen to me explain this? Read about it from the professor himself here: https://www.quora.com/Why-does-CS50-at-Harvard-use-C-as-its-primary-language


We explored conditionals and data types and how we implement them using C. After we write what is called “Source code” (code that uses data types and conditional statements to give instructions to computers), we will be using a compiler called clang (which stands for C language) to convert what we wrote to what machines will understand, called Machine Code. This is because machines will only understand 0s and 1s! They don’t even understand source code, let alone pseudocode, therefore we need to go from: Source code -> Compiler -> Machine code.


Let’s get into the web-based IDE (Integrated Development Environment) where will we write the source code, called CS50 IDE. This is where we will write and submit our problem sets. We will compile our code here by using the terminal, which is a CLI (Command Line Interface), then we will run our code. We are given a “tour” around the IDE and how we will be working in the IDE and how to submit the problem sets.


Pset 1: C

Your agenda for this pset is:

1. Watch Lecture 1 on C

2. Get familiar with CS50 IDE and C with hello.c

3. Understand how to prompt the user for information with water.c

4. Become comfortable using loops inside loops with mario.c

5. Work with many different data types and operators with greedy.c and credit.c


One thing to keep in mind is edX platform currently only has the problem sets from Harvard’s Fall term of 2016, but I am currently attending Fall 2017, therefore some problem sets will be different. However, practice makes perfect so I will be showing every single problem sets from 2016 and 2017, including the optional ones where CS50 just wants one of two problems.


Find all my solutions here: 

https://github.com/alwongg/Harvard-CS50/tree/master/Pset1


1. Hello.c


The first ever problem from CS50! It is a tradition in computer science where programmers would learn how to print a simple “Hello World” and this is exactly that. 


2. Water.c


Here, we prompt the user for how many minutes they spend in the shower and store it in an int variable. Multiply that number by 12 to convert a minute’s worth of water is equivalent to 12 bottles of water. After that, we print out how many bottles of water they used in respect to how many minutes they were in the shower. This problem was fairly simple and did not take too much time. I became more comfortable asking users for specific information, changing the value in the variable then printing the information out to the console.


3. Mario.c – Less comfortable


This is where we are offered to submit one of two options for the Mario problem. One where we print out only the right side of a pyramid and the more advanced problem where we need to print out both sides of the pyramid. The first problem where we print one side of the pyramid took quite a while since you have to modify the conditions within the if statement and it wasn’t something I was comfortable with. 


First, we need to prompt the user for how high they want the pyramid to be and it must be between 0 and 23 inclusive. Because you’re giving them rules to follow, you will use a do while loop to prompt the user. Once you get this height value, draw the pyramid with for loops. In general, for loops in C requires you to have an initialization, a condition, and an incrementation. The first for loop will be responsible for looping through the height variable to print out each row. Then within the first for loop, you want to do something within each iteration which is to print spaces and the hashes to represent the blocks. You will have 2 separate for loops within the first for loop, the first one will print out spaces since your pyramid is ascending. Because it is ascending, you will be printing more spaces first then decreasing the number of spaces as you go through your iterations. This is why you iterate through while space is less than height – row – 1 then your second for loop is printing hashes and you will print them while the hash is less than row + 2 since you will always start off with 2 blocks. After you go through those iterations, print to the next line and continue the iterations. 


4. Mario.c – More comfortable


If you are coming straight to the more comfortable problem of Mario.c, it will be a challenge! But since I started with the less comfortable version, implement the second side of the pyramid was a lot easier. You are basically using the same code from the less comfortable version then making some minor tweaks to achieve the second half of the pyramid. Instead of two for loops within the parent for loop, you are using 4 of them. First loop prints your spaces, second loop prints your hashes for the blocks, third loop prints the 2 constant spaces then the last loop will print out the right half of the pyramid, which is simpler since you do not have to print spaces.


5. Greedy.c – Less comfortable


Less comfortable version for dealing with money. In greedy.c, you will basically create a program that prompts a user for how much money in dollars they should get back from the cashier. The cashier (program) will have to figure out the least amount of coins it should return to the customer, which is why it’s called greedy. The coins available are only quarters, dimes, nickels and pennies. This problem is good for practicing with creating and using variables and also doing modulo math. Let’s get greedy!


For this problem, we already know 3 unchanged values: quarters having the value 25, dime 10, nickel 5 and penny 1. One thing I learned to do in this problem is to use what is called a “preprocessor directive” which is a Macro declaration that allows you to specify a name (in this case: QUARTER, DIME, NICKEL) and its associated text (25, 10, 5 respectively) using #define to store the cents values. By using preprocessors, it’ll be faster to execute since the compiler won’t need to allocate memory for them. 


Next step, declare your variables. When you prompt your user, the user will enter the amount they are owed in a float in dollars, for example, $1.46. Let’s work with this number from here on out for greedy.c. We are given the input in dollars, and it’ll be a lot harder to work with when our values are in cents. So we first need to convert the given amount into cents by multiplying it by 100, rounding it then casting it as an integer, since it was a float data type before. 


Now, we need to know how many quarters, dimes, nickels, and pennies we need in total to give back to the user while giving them the least amount of coins. We do this by prioritizing the biggest value, in this case, quarters. So let’s take the cents amount, which is 146, then find out how many quarters we need then store that in a variable. To do this, divide the cents amount by 25. This will give us 5 quarters but now we need the leftover amount to continue the process for the dimes, nickels, and pennies. We need to use modulo math to get the remainder and it in the leftover variable. Repeat until we’re done with nickels and the remainder after that will be the pennies, this way, we won’t have to create a whole new variable to store the pennies count. 


Sum the total amount of coins and we will get 8 coins to be returned to the user (5 quarters, 2 dimes, 1 penny). Overall, a much more challenging problem to solve and does require you to think carefully about how to store these values and how to use them.


6. Credit.c – More comfortable


The more comfortable version of dealing with money. Because we submitted greedy.c, we didn’t have to submit this problem but more practice doesn’t hurt. This problem really took the most time, about 8 hours! But this is also a very interesting problem and also learned quite a bit about credit cards in general. Here, we learn about Luhn’s algorithm, an algorithm that verifies if a credit card is valid or not.


Prompt the user for a credit card number and check if it passes as a valid number using Luhn’s algorithm. First, we iterate through the numbers from right to left. For how the algorithm works to verify the number, check out the guidelines from pset1 credit. The hardest part for me was to figure out how to iterate through from right to left and doing something with every other value. To accomplish this, we can use a boolean value to skip every other digit that is set to false or true, by doing this, you can have control on what you want to do with every other value. Next tricky part was to sum the digits of the products and not the whole number. We can use a while loop to shave off the last number to sum every digit. After that, it’s only a matter of using conditional statements to check if the number is an American Express, MasterCard or a Visa. One trick here is using the pow() function so you can easily divide the numbers to check the first two numbers of the card number to identify the company since, for example, American express starts with 34 or 37.


Lecture 1 done! An introduction to the C programming language. We basically took what we learned from Scratch and translated many of the logic and syntax to the C language. We talked about compilers and the command-line interface to know how they work and what they do. And we ended the lecture understanding more about imprecision and bits in computers. 

Leave a comment