Problem Set 8 : CS50 Shuttle

Hello everyone! Welcome back! This is cs50! How’s the C$50 Finance? It was fun, right? Hehe..
Umm.. well, today I’m going to write about Problem Set 8. OMG, the last!!! OK, so what it is all about? It is all about JavaScript and third-party APIs.

As always, take your time to read :

Getting Started

Per the instruction, if you don’t have Chrome installed on your computer (not inside of the appliance), download and install the latest version of Chrome from
Then using Chrome, download and install the Google Earth Plug-in from Note that the plug-in requires Mac OS or Windows unfortunately. Once the plug-in installed, you may need to reload that page or restart your browser, but you should see a 3D Earth embedded the page. If unable to get Google-Earth plug-in, you may skip this problem set.
Best to minimize the number of programs and windows you have open while working on this problem set. The Google Earth Plug-in likes to consume CPU cycles and RAM. In fact, if you ever feel your computer slowing down, you might want to quit some programs or even reboot (after saving your work).
Next, start up your appliance, open a terminal window and execute :


To ensure that your appliance is up-to-date!
Like Problem Set 7, this problem set comes with some distribution code that you’ll need to download before getting started. Go ahead and execute :

cd ~/vhosts/localhost/public

Then execute :


In order to download zip file of this problem set’s distro. Then execute :


You should see that you now have a file called in your ~/vhosts/localhost/public directory. Unzip it by execute :


Then :


You should see that you now also have a directory called pset8. You’re now welcome to delete the ZIP file with the below :

rm –f

If you next execute :

cd pset8

Followed by


You should see that pset8 contains index.html and four directories (css, fonts, and img, and js). Ensure that all files inside of the pset8 (and its descendants) are world readable by executing :

find . – type f | xargs chmod 644

So that the appliance’s web server will be able to access your work. Then ensure that all directories inside pset8 are world-executable by executing the below :

find . – type d | xargs chmod 711

Finally, ensure that few other directories are still world-executable by executing the below :

chmod 711 ~
chmod 711 ~/vhosts
chmod 711 ~/vhosts/localhost
chmod 711 ~/vhosts/localhost/public 

If you opt to create files or any other directories for this problem set, keep in mind that :
• any files should probably be readable and writable by you but only readable by anyone else (i.e 644).
• and any directories should world-executable (i.e 711).

Unlike Problem Set 7, your code for Problem Set 8 will indeed live in a virtual host (aka vhosts) called localhost rather than one called, e.g., pset8. Using localhost will make it easier to access your code from Chrome on your own computer (outside of the appliance).

Now head to the URL below using a browser on your own computer (outside of the CS50 Appliance), where w.x.y.z is your appliance’s IP address (which should be displayed in the appliance’s bottom-right corner), and each of w, x, y, and z is thus a number between 0 and 255:


You should see University Hall! If not, do double-check that you’ve not missed or mistyped a step.

Incidentally, anytime you’d like to print some debugging information to the Console tab of Chrome’s Debugging Tools during this problem set, a la printf in C, know that you can include a line like

console.log("hello, world");

in your JavaScript code. So long as Chrome’s Console is open, you’ll see that text. Just be sure to remove any such lines before submitting your work. Do keep an eye on that Console during development, too, as syntax errors and more tend to appear there in red. Alternatively, you can include a line like

alert("hello, world");

in your JavaScript code to display messages to yourself, but the pop-up that results tends to be more annoying, especially if you accidentally call alert in a loop!

Your mission of this problem set is to implement your own shuttle service that picks up passengers all over campus and drops them off at their houses. Your shuttle equipped with an engine, a steering wheel, and some seats. Assuming that you’re still at http://w.x.y.z/pset8 looking at University Hall, here’s how to drive the keyboard:

Move Forward  W
Move Backward S
Turn Left     
Turn Right    
Side Left     A
Side Right    D
Look Downward 
Look Upward  

Oops! Where did I go? I think I’ve lost my way… 😉

cs50 shuttle

OK, now open up index.html first and read over the HTML code inside :


Look at the div announcement :


Then, let’s take a peek at css/service.css :

 * service.css
 * Computer Science 50
 * Problem Set 8
 * Global stylesheet.
 height: 100%;

 font-family: sans-serif;
 height: 100%;
 margin: 0;

 font-size: smaller;
 margin: 5px;
 text-align: center;

Then, open up building.js, you should see the below :

 * buildings.js
 * Computer Science 50
 * Problem Set 8
 * Buildings on campus.

 root: "04558",
 name: "1 Bow Street",
 address: "1238 Massachusetts Ave",
 lat: 42.372341075,
 lng: -71.116148412

Now, turn to passengers.js sneak peek :

 username: "abuchholtzau",
 name: "Allison Buchholtz-Au",
 house: "Adams House"

Then you’ll want to check houses.js. You can see the coordinates which are the official coordinates for the passengers destinations.

var HOUSES = 
 "Adams House": {lat: 42.37189, lng: -71.11639},

If you’d like to look up where some building is on campus, feel free to search for it at

Ok, let’s take a peek at js/shuttle.js. You don’t need to understand this file entirely, but know that inside of a Shuttle there are two properties : position, which encapsulates a shuttle’s position(including latitude and longitude)

// shuttle's position
 this.position = {
 altitude: 0,
 heading: config.heading,
 latitude: config.latitude,
 longitude: config.longitude

and states which encapsulates a shuttle’s various states.

// shuttle's states
 this.states = {
 flyingUpward: false,
 flyingDownward: false,
 movingBackward: false,
 movingForward: false,
 slidingLeftward: false,

OK, now pay your attention at js/service.js when you’ll most do your work here. You may modify any of this problem set’s files except for js/math3d.jd, js/building.js, js/houses.js, and js/passengers.js.

Anyway, inside of js/service.js you should do the below:

  1. Pickup chart
  2. Dropoff
  3. Extra features


It’s time start picking the passengers up. Recall from index.html that when the button labeled Pick Up clicked, the function called pickup is js/service.js is called. How to do it? Well, it’s part of challenge. Implement pickup as follows :

  • If the button is clicked when and the shuttle is within 15.0 meters of a passenger and at least one seat is empty, the passenger should be given a seat on a shuttle and removed from both 2D and 3D earth.
  • If the shuttle is not within 15.0 meters of any passenger, make an announcement to the effect.
  • If the shuttle is within range of some passengers but no seats are free, make an announcmement to that effect (and don’t pick up the passenger).
    By the way you’ll want to read :
    Google Maps JavaScript API v3
    Google Earth API

Hints to get you started on picks-up :
1. To calculate the shuttle’s distance, “d“, from some point (lat, lng), you’ll probably  want something like :

var d = shuttle.distance(lat, lng);

2. To remove a placemark, “p“, from 3D earth, you’ll probably want something like

var features = earth.getFeatures();

3. To remove marker, m, from the 2D map, you’ll probably want something like :


4. Then, you’ll want to update shuttle.seats to give the passenger a seat, be sure not to add extra seats.

Incidentally, be sure not to pick up any freshmen (i.e anyone whose home isn’t in js/houses.js).
Take a look at the pseudocode below to get you done the pickup function.

Pseudocode :

1. detect passenger(s) in range –> loop through all passengers
2. add passenger(s) to shuttle
3. remove placemark from the 3D Earth
4. remove marker from 2D map
5. display passenger(s) in shuttle


Now, implement drop-offs! Recall from js/building.js, that each passenger live in a house. And recall from index.html, that, when the button labelled Drop Off is clicked, the function called dropoff in js/service.js is called. Implement drop-offs as follow :

  • If the button is clicked when the shuttle is within 30.0 meters of an aon-board passenger’s house, that passenger should be dropped of by emptying their seat.
  • If the shuttle is not within 30.0 meters of any passenger’s house, you should make an announcement to that effect. You should make an announcement.
  • No need to re-plant a placemark or marker for dropped-off passangers. Be sure not to make them change seats just because some other seat is now empty.

Take a look at the pseudocode below to get you done the pickup function.
Pseudocode :
1. check if in range of any houses –> loop through houses
2. remove passengers from shuttle


Per the spec: you’ll need to implement any three of the features as the spec says.

Once you’re done with that, you’ve completed CS50 Shuttle! Congrats! 😉
This was Problem Set 8. Your last!

Problem Set 7 : C$50 Finance

Hello world! Welcome back! This is CS50! Congratulations you’ve done the introduction of programming in C. Now, we will have new languages. This problem set teaches you how to teach yourself about, HTML, CSS, PHP and SQL. As always, you’ll want to read the below.
Recommended Reading :


What is HTML actually? HTML (Hyper Text Markup Language) is the language where we use for webpage. But it doesn’t a language actually, because it doesn’t allows to express logic like for-loops, while-loops, conditions and alike rather is indeed a markup language that allows to specify what the webpage should look like, structurally and statically. And it does show by way what we called text. Let’s dive in the simple example for a webpage that print “Hello, World!”.
Open up gedit and let’s make a file called hello.html and save it into public directory that is indeed inside of localhost directory that is indeed inside of vhosts directory and this is is indeed inside of jharvard appliance :

 <!DOCTYPE html>

       Hello, World!


It turns out that HTML is not the only language that you can use for webpage. Well, you’ll want to use CSS (Cascading Style Sheet) as well. CSS allows you the specify much more precisely the aestethics of webpage include layouts, sizes, colors, fonts and much more. I made a css file in a separate window, not inside the html window because it is more readable and effective. For instance let’s take a look an example below :

 /* Header */
.large-header {
 position: relative;
 width: 100%;
 background: #333;
 overflow: hidden;
 background-size: cover;
 background-position: center center;
 z-index: 1;
 -webkit-filter: opacity(60%);

.demo-0 .large-header {
 background-image: url('../img/pset0-bg.jpg');
 background-position: center bottom;

.main-title {
 position: absolute;
 margin: 0;
 padding: 0;
 color: #ffffff;
 text-align: center;
 top: 50%;
 left: 50%;
 -webkit-transform: translate3d(-50%,-50%,0);
 transform: translate3d(-50%,-50%,0);


PHP stands for PHP Hypertext Processor or PHP Hyepertext Processor Hyrtext Processor and we’ll stop there.. PHP is a recursive acronym. So, let’s write “Hello, World!” in PHP which a bit different that the “Hello, World!” in C that we’ve come to know and love. So, instead of creating a file called hello.c we’ll create hello.php. All of the PHP code will be contain between :



If we have any PHP code that is located outside of this border, it won’t execute. We can have many PHP blocks as we want inside the single php file. In PHP, there is no need a “main” function. Instead, our PHP code will be run in order to appears in our PHP file. Both C and PHP have “printf” function for outputting data. But in PHP, we don’t need “#include” any headers file like “<stdio.h>” that is because in PHP we won’t be compiling our code. Unlike C, PHP is interpreted rather than compiled language that means the PHP code we write will be run through a special program called in interpreter which will turn and execute our code. So, to run our PHP code, we’ll send it along to the PHP interpreter which will handle execution rather than compiling it to the machine code. So let’s see interpreter in action. Well, open up the terminal and run the PHP command followed by the path to the PHP file we’d like to run.

jharvard@appliance (~/vhosts/localhost/html): php hello.php 
Hello, world!

And there we go! That’s the output of our PHP program. We didn’t need to compile the file at all instead we had another program the PHP interpreter execute the source code that we wrote. PHP could do much more than simply “printf”. The syntax for constructs like if-else, while, for, switch, is the same in PHP and C. Just like C, each of this constructs use a braces { } to demarcate the body and just like in C, every line we write must end with a semicolon ;. However, variables are handled a bit differently in PHP. First, all of the variables we write have to use dollar sign $. Second, the PHP is loosely typed language. Which means you don’t need to explicitly list the type of the variable when you create it. So, where in C you say :

int x = 5; 
char y = 'a';

in PHP we can simply say:

$x = 5; 
$y = 'a'; 

The same apply to a functions rather than saying

int f() {....}

in PHP we can write :

function f () {....} 

So we don’t need to explicitly specify the return type of the function f. Functions in PHP also don’t have to return the same type everytime they execute. For example, we used “return false” on an error or another type if its succeed. This also make generic functions. Well, in C we use pointers for arrays in strings, we won’t use the pointers in PHP instead both arrays and strings are built in types in PHP. To create an array in PHP we could use :

$a = array(1,2,3);
 or we can use 
$a = [1,2,3];

We can indexed into this array using the same syntax that we’re use to from C. So, get the first element we’ll say :


PHP also have an associative array. And it just like a hashtable data structure that we’ve already seen in C. They mapped a key into a value. Example :

$staff = [
 "instructor" => "david",
 "tf" => "rob"

So here I have an associative array with two keys ‘instructor’ and ‘tf’. The => is use to separate the KEY and the corresponding VALUE. So, the value of $staff[“tf”] is a string “Rob”.
Or we’ll want to use :

$staff = [
 "instructor" => "david",
 "tfs" => [

So now, the value of “tfs” is an ARRAY. That means the value inside in one associative array can be a different types. PHP arrays also do not having a fixed length. So, we can add or remove elements from an array. See for more.

We’re about using PHP for web-development. PHP is a scripting language that can be use to implement a website on a web server. A web server is essentially a machine dedicated to providing content that can be access via the internet. So, when you navigate your way to, the code in the file called home.php which lives on the facebook web server somewhere will be executed on that server. So, this code is likely generate some output which entirely sent from the server to your web browser. We’ll be using the CS50 appliance as web server. Well, we navigate to URL like http://localhost/hello.php we’ve configured the appliance via an application called Apache HTTP server to look for file called hello.php inside of home/jharvard/vhosts/localhost/html by default. If that file exists, then Apache will use the PHP interpreter to execute the PHP code in hello.php. If that file doesn’t exist, then Apache will throw it ‘Not Found’ error or 404 error which you’ll probably seen while browsing a web. So, let’s take a look at hello.php. We can see here that hello.php generates a single line of output.

printf("Hello, world!\n");

When we ran hello.php at the command line below :

jharvard@appliance (~/vhosts/localhost/html): php hello.php 

That output will printed in the terminal. See below :

jharvard@appliance (~/vhosts/localhost/html): php hello.php
 Hello, world!

Now when we access the file via the URL in the web browser, its output will be send to a web browser. So, heading to URL http://localhost/hello.php on your web browser, we can see it will print “Hello World!” on our web browser.


Se-quel or SQL isn’t a programming language but instead, it’s a language that provides a standard set of commands to retrieve and manipulate data from a variety of database management systems. For the purpose of CS50, we’ll go over four basic commands : SELECT, INSERT, UPDATE, and DELETE. Furthermore, we’ll utilize a database web interface called phpMyAdmin.

Getting Started

Well, we’re going to do a web-development in this problem set. Like problem set6, this problem set comes with distribution code that you’ll need to download before getting started. Let’s get you started! Per instruction ( Now open up your appliance, then open up the terminal window and execute the below :

cd ~/vhosts

In order to navigate your way to ~/vhosts directory. Then execute :


in order to download the ZIP file. If you then execute :


you should see that you now have a file called in your ~/vhosts directory. Unzip the file by execute :


if you again execute :


you should see that you now have a file called pset7. You’re now welcome to delete the file called by execute :

rm -f

next, execute :

cd ~pset7

followed by


you should see the pset7 contains three subdirectories : includes, public, and templates.

  • Next, ensure a few directories are world-executable by executing
    chmod a+x ~
    chmod a+x ~/vhosts
    chmod a+x ~/vhosts/pset7
    chmod a+x ~/vhosts/pset7/public

    so that the appliance’s web server (and you, from a browser) will be able to access your work. Then, navigate your way to ~/vhosts/pset7/public by executing the below.

    cd ~/vhosts/pset7/public

    If you execute


    you should see that public contains four subdirectories and three files. Ensure that the former are word-executable by executing the below.

    chmod a+x css fonts img js

    Finally, ensure that the files within those directories are world-readable by executing the below.

    chmod a+r css/* fonts/* img/* js/*

    If unfamiliar, * is a “wildcard character,” so css/*, for instance, simply means “all files within the css directory.”

    For security’s sake, don’t make ~/vhosts/pset7/includes or ~/vhosts/pset7/templates world-executable (or their contents world-readable), as they shouldn’t be accessible to the whole world (only to your PHP code, as you’ll soon see).

  • Even though your code for this problem set will live in ~/vhosts/pset7, let’s ensure that it’s nonetheless backed up via Dropbox, assuming you set up Dropbox inside of the appliance. In a terminal window, execute

    ln -s ~/vhosts/pset7 ~/Dropbox

    in order to create a “symbolic link” (i.e., alias or shortcut) to your ~/vhosts/pset7 directory within your ~/Dropbox directory so that Dropbox knows to start backing it up.

  • So why did we put pset7 inside of a directory called vhosts? Well, the appliance is configured to serve “virtual hosts” (i.e., websites) out of the latter. Specifically, if you visit, say, http://pset7/ using Chrome inside of the appliance, the appliance is configured to look in ~/vhosts/pset7/public for that website’s web-accessible files. But for that to work, we also need to associate the appliance’s own IP address with pset7 so that it “resolves” via DNS to it. Rather than set up a whole DNS server to do that, we can actually edit a file called hosts in a directory called etc. Let’s do that.

    In a terminal window, execute

    sudo gedit /etc/hosts

    in order to run gedit as the appliance’s “superuser” (aka “root”) so that you can edit what’s otherwise a read-only file. Carefully add this line at the bottom of that file, which will associate pset7 with the appliance’s “loopback” address (which won’t ever change): pset7

    Then save the file and quit gedit. Then enjoy

    If you encounter a Gtk-WARNING with gedit, try restarting the appliance, as via Menu > Log Out > Restart (or via VMware’s own Restart option), then try again; the warning appears to be a bug in Fedora (the appliance’s operating system).

  • Alright, time for a test! Open up Chrome inside of the appliance and visit http://pset7/ then you should see below.

cs50 finance

Now, head to http://pset7/phpMyAdmin using Chrome inside the appliance to access phpMyAdmin, a Web-based tool with which you can manage MySQL databases. (MySQL is a free, open-source database that lots of sites use). If you then, see the below and login as John Harvard (name jharvard and password crimson).


You should then find yourself at phpMyAdmin’s main page.

php main page

Then, go ahead and visit using Chrome inside the appliance, and then open the file in gedit, as by clicking its name in Chrome’s bottom left corner. You should ultimately see a whole bunch of SQL within pset7.sql. Then highlight it and copy it by select Edit > Copy (or just hit ctrl-c).


Then, return to phpMyAdmin and click phpMyAdmin’s SQL tab, and paste everything you copied in that page’s big text box.


Then, click Go. You should see a green banner proclaiming Your SQL query has been executed successfully.

Okay, heads-up. Just to remind you that anytime you create a new file directory in ~/vhosts/pset7 or some subdirectory therein for this problem set, you’ll want to set its permissions with chmod. Thus far, we’ve relied on a+r and a+x, now we can use which more precise control over permissions.

For any PHP file, file, that you create, execute :

chmod 600 file

that is accessible only by you (and the appliance’s webserver).

For any non-PHP file, file, that you create (or upload), execute :

chmod 644 file

it’s accessible via browser.

And for any directory, directory, that you create, execute :

chmod 711 directory

that its contents are accessible via a browser.

You’re about to implement C$50 Finance, a Web-based tool with which you can manage portofolios of stocks. It will also let you buy and sell stocks! If you’re not quite sure what it means to buy and sell stocks, you’ll want to surf on over for tutorial. Then head to for teaser. Then typed symbol DVN.V you’ll see the table like below.


Now, open up index.php on gedit. Know that index.php is the file that’s loaded by default when you visit a URL like http://pset7/ .


 // configuration
 $positions = [];
 $rows = query("SELECT symbol, shares FROM usertable WHERE id = ?", $_SESSION["id"]); 
 foreach ($rows as $row)
 $stock = lookup($row["symbol"]);
 if ($stock !== false)
 $positions[] = [
 "name" => $stock["name"],
 "price" => $stock["price"],
 "shares" => $stock["shares"],
 "symbol" => $row["symbol"],

 // render portfolio
 render("portfolio.php", ["positions" => $positions, "title" => "Portfolio"]);


Turns out, that there’s not any HTML at all, index.php require config.php (inside the directory called includes) and then calls render ( a function that implemented in file called function.php and inside the directory called includes). And it turns out that index.php is considered a “controller”. Its purpose in life is to control the behaviour of  your website when the user visits http://pset7/. By the way, you’ll create another “controllers” inside of ~/vhosts/pset7/public. More on those later.

Next, open up config.php in gedit. You should see the below.


 * config.php
 * Computer Science 50
 * Problem Set 7
 * Configures pages.

 // display errors, warnings, and notices
 ini_set("display_errors", true);

 // requirements

 // enable sessions

 // require authentication for most pages
 if (!preg_match("{(?:login|logout|register)\.php$}", $_SERVER["PHP_SELF"]))
 if (empty($_SESSION["id"]))


Okay, so config.php calls session_start in order to enable $_SESSION a superglobal variable via which we’ll remember that a user logged in. Next, config.php calls $_SESSION is  an associative array in which you can store any data to which you’d like to have access for the duration of some user’s visit.

For instance, now, take your time to open up another files inside of each directories inside ~/vhosts/pset7/. You’ll want to navigate your way to ~/vhosts/pset7/templates and open up “portfolio.php” and another files. If you then, navigate your way to ~/vhosts/pset7/includes and open up “contstans.php” and “functions.php”. Then, you should find out what’s going on there.

Now, let’s  make it simple. I assume you’ve read over the spec In this problem set, you’ll developt a website, for instance it is all about buy and sell stocks. It will indeed using databases for each elements of it, like INSERT-ing, SELECT-ing, DELETE-ing, and then UPDATE-ing. And this is all about how do you create them? Well, you’ll want to use SQL to do it. Let’s tackle it! Before we go for some examples, I just wanna make sure that you have to implement each of those below :

  1. register.php
  2. quote.php
  3. portfolio.php
  4. sell.php
  5. buy.php
  6. history.php

Okay, so let’s talk about an example, I used a query from login.php, it is inside of ~/vhosts/pset7/public. Notice too that login.php “remembers” that a user is logged in by storing his or her unique ID inside of $_SESSION. Take a look at below :

// remember that user's now logged in by storing user's ID in session
 $_SESSION["id"] = $row["id"];

Then, take a look at the line below :

query("SELECT * FROM users WHERE username = ?", $_POST["username"]);

Read through its line carefully, taking note of how it queries the appliance’s MySQL using that query function. That function essentially simplifies use of PDO (PHP Data Object), see for more details, it is a library with which you can query MySQL (and other) databases.

Ok, now suppose that President Skroob tries to log into C$50 Finance by inputting his username and password. That line of code will ultimately execute the SQL statement below :

SELECT * FROM users WHERE username='skroob'

But, unlike SELECTs, some SQL queries like DELETE, UPDATE, and INSERT don’t actually return rows, so that query returns might sometimes be empty.


It’s time to code now! First, we’ll tackle register.php. In terminal window execute :


then, you’ll want to execute :

cp login_form.php register_form.php

Open up register_form.php with gedit and change the value of action attribute from login.php to register.php. Add an additional field of type password to the HTML form called confirmation. So, that users are prompted to input their choice of passwords twice (to discourage mistake).

Then, using gedit, create a new file called “register.php” with contents below, but don’t forget to save it in ~/vhosts/pset7/public.


// configuration

// if form was submitted

// else render form
render("register_form.php", ["title" => "Register"]);

Pseudocode of TODO above :

  • If $_POST[“username”] or $_POST[“password”] is empty or if $_POST[“password”] does not equal $_POST[“confirmation”] , you’ll want to inform registrants of their error.
  • To insert new user, you might want to call :
query("INSERT INTO users (username, hash, cash) VALUES(?, ?, 10000.0)", $_POST["username"], crypt($_POST["password"]));
  • Query will return false if your INSERT fails (as can happen if, say, username already exists). Be sure to check for false with === and not ==.
  • If, though, your INSERT succeeds, know that you can find out which id was assigned to that user with code like below :
$rows = query("SELECT LAST_INSERT_ID() AS id");
$id = $rows[0]["id"];
  • If registration succeeds, you might as well log the new user in (as by “remembering” that id in $_SESSION), there after redirecting to index.php
    If done with register.php. Test it by heading to http://pset7/register.php using Chrome inside the appliance and try to register a new username. If you reach index.php, you done good! Be sure that html is valid via .

(gambar register.php)


Now, let’s empower user to look up quotes for individual stocks. You’ll want to create a new controller called quotes.php inside the ~/vhosts/pset7/public plus two templates, the first of which to display an HTML form via which you can submit a stock’s symbol, the second of which displays, minimally, a stock’s lates price (if passed, via render, an appropriate value).How to look up a stock’s latest price? You’ll want to call lookup function in function.php, see below :

$stock = lookup($_POST["symbol"]);

Pseudocode :

  • Display form
    Display from allows the user to input the given stock symbol that they want to lookup. You’ll want to create a quote template (the form for stok lookup) for example : quote_form.php and save inside ~/vhosts/pset7/template. And don’t forget to add the form input that allows the uses to input symbol that they want to look up. Next, the form action is to send those informations to controller (i.e quote.php) that lies in the ~/vhosts/pset7/public.s
  • Retrieve stock quote
    The function “lookup” passing in the string of the symbol that will return an associative array.for example :
$s = lookup("AAPL");

Return an associative array :
– Symbol
– Name
– Price

  • Display stock quote
    We’re already have a controller called quote.php and a template called quote_form.php. Then how to display the stock quote? Well, you’ll want to create another template let’s say quote.php and save it inside the ~/vhosts/pset7/template. That will have the behaviours like below :
    – At minimum, display quote
    – Ensure the stock symbol is valid, else “apologize” as usual.
    – print(“Price: “ . $s[“price”]); but we need to format to 2 to 4 decimal places, if not sure try to read number_format functionality.

Be sure that html is valid via .


Portfolio means “collection of stocks (i.e shares company). At present, your database has no way of keeping track of user’s portfolios. How many different stocks might a user own? Better to maintain that data in a new table together so that we don’t impose limits on users’ portfolios. What sort of information need we keep in this new table in order to ‘remember’ users’ portfolios? Well, you’ll want to add a table with three fields ID, SYMBOL, and SHARES sounds pretty good. To create ne table click on pset7 in phpMyAdmin’s top left corner and click Create table as you see below, then click Go :


Next, define each of your fields (id, symbol, and shares), realize that ID should not be defined as primary key in this table. And, you shouldn’t let some id and shares to appear together in more than one row. But, you should define a “joint primary key” by selecting an Index of PRIMARY for both id and symbol. That way, INSERT will fail if you try to insert more than one row.

Be sure that html is valid via .

Pseudocode :
For portfolio, you’ll want to display all of the stocks that the user has.
1. Make a portfolio table
2. Display the portfolio table


It’s time to implement sell with a controller called sell.php and some number of templates. I leave you to design of this feature to you. Know that you can delete rows from your tables with code like below :

DELETE FROM tbl WHERE id = 7 AND symbol = 'DVN.V'

What about the users’ balance? Your user is going to want the proceeds of all sales. So selling a stock will updating not only your table for users’ portfolios but users as well. Determine it by yourself. Example : let’s say the amount is ($400) with SQL like below it will take care of the deposit.

UPDATE users SET cash = cash + 400 WHERE id = 7


  • You’ll want to display form that allows the user (i.e the stock’s owner) to get stock to sell. So, create a new template for it. But they can only sell the stock that they own. So, with code like :
SELECT * FROM portfolio WHERE id = 7
  • Remove stock (that you’ve sold) from the portfolio, with code like :
DELETE FROM portfolio WHERE id = 7 AND symbol = "AAPL"
  • Updating cash where the stock is sold at its current price. So, look back at “lookup” function.

Implement ability to buy with controller called buy.php and some number of templates. See for inspirations. You’ll need to to ensure that a user cannot spend more cash than he or she has on hand. You’ll want to make sure that users can only buy whole of shares of stocks. You’ll want to call :

preg_match("/^\d+$/", $_POST["shares"])

see for details. Be sure that html is valid via .

Pseudocode :

  • You’ll want to display form for the user to get the stocks, and number of shares. Well, the form is going to be an HTML form that will ask for symbol and number of shares.
  • You’ll want to add stock to the portfolio. We’ll first check whether the users can afford the stock, for example :
SELECT cash FROM users WHERE id = 7

Now, they want to buy more at the same stock, then you’ll want to allow them to update the given row in the portfolio,

INSERT INTO portfolio (id, symbol, shares) VALUES(7, 'DVN.V', 10) ON DUPLICATE KEY UPDATE shares = shares + VALUES(shares)
  • Then, you’ll want to update cash. A user’s cash is stored in users table. Then you’ll need to :
UPDATE users SET cash = cash – 9999 WHERE id =7


So your users can now buy and sell stocks and even check their portfolio’s value. But they have no way of viewing their history of transactions.
Enhance your implementations for buying and selling in such a way that you start logging transactions, recording for each:

• Whether a stock was bought or sold.
• The symbol bought or sold.
• The number of shares bought or sold.
• The price of a share at the time of transaction.
• The date and time of the transaction

Then, by way of a controller called, say, history.php and some number of templates, enable users to peruse their own history of transactions, formatted as you see fit.

Be sure that html is valid via .

Pseudocode :

  • You’ll need to add history table
  • For every purchase and sale :

– Add a row to history
– Store the timestamp of transactions: you’ll want to use NOW() either CURRENT_TIMESTAMP functions.


Glance back at index.php now and, if not there already, make that it somehow links to, at least, buy.php , history.php , logout.php , quote.php , and sell.php (or their equivalents) so that each is only one click away from a user’s portfolio!

And now the icing on the cake. Only one feature to go, but you get to choose. Implement at least one (1) of the features below. You may interpret each of the below as you see fit; we leave all design decisions to you :

– Empower users (who’re already logged in) to change their passwords.
– Empower users who’ve forgotten their password to reset it (as by having them register with an email address so that you can email them a link via which to do so).
– Email users “receipts” anytime they buy or sell stocks.
– Empower users to deposit additional funds.

Be sure that html is valid via .
For tips on how to send email programmatically, see

With that, you’ve completed C$50 Finance.

This was Problem Set 7.

Problem Set 6 : Dictionary

Hello fellow coder! Welcome back to CS50! So, this is the beginning of make your own data structure and optimize your code’s (real-world) running time. What is the problem actually? Well, this problem set is about to make a “Spell-checker”. Like problem set 5, it will comes with the distribution code. How is the spell checker works? Well, we’re going to find out later. This was the hardest problem set that I ever done to be honest.

Now, let’s get started!
Per the instruction open up the terminal window, and execute :


To make sure your appliance is up-to-date.Then, execute :


In order to navigate your way to ~/Dropbox directory. Then, execute :


To download a ZIP of this problem set’s disro. Next, execute :


You could see the file called in your ~/Dropbox directory. Then, you’ll want to unzip the file by executing the below :


Then execute :


To ensure that you have a directory called pset6. If you then want to delete the zip file by execute :

rm -f

To remove the file. Next execute :

cd pset6

Now let’s open what’s inside the pset6 directory by execute :


Then you should the the directory contains the below :

dictionary.c dictionary.h Makefile questions.txt speller.c

Now, let’s get started!

First, let’s be friends with “running time“. On input size of n, an algorithm with a running time of n is asymptotically equivalent in term big O, to an algorithm with a running time of 2n. In the real world, though, the fact of the matter is that the latter feels twice as slow as the former.
The challenge of this problem set is to implement the fastest spell-checker you can! By “fastest”, though, we’re talking actual, real-world, noticeable seconds-none of that asymptotic stuff this time.
Take your time to take a look at dictionary.h on gedit. In this file you should see the cs50’s staff declared a dictionary’s functionality.

They declared the prototype of four functions, take a note of what each should do. Anyway, you’ll want to implement 4 functions to complete this problem set, and they are : check, load, size and unload. The prototypes inside the dictionary.h are :

// maximum length for a word
// (e.g., pneumonoultramicroscopicsilicovolcanoconiosis)
#define LENGTH 45
 * Returns true if word is in dictionary else false.
bool check(const char* word);

 * Loads dictionary into memory. Returns true if successful else false.
bool load(const char* dictionary);

 * Returns number of words in dictionary if loaded else 0 if not yet loaded.
unsigned int size(void);

 * Unloads dictionary from memory. Returns true if successful else false.
bool unload(void);

#endif // DICTIONARY_H

Okay, next open up speller.c with gedit. And try to understand it. You won’t need to change anything in this file.

 * speller.c
 * Computer Science 50
 * Problem Set 6
 * Implements a spell-checker.

#include <ctype.h>
#include <stdio.h>
#include <sys/resource.h>
#include <sys/time.h>

#include "dictionary.h"
#undef calculate
#undef getrusage

// default dictionary
#define DICTIONARY "/home/cs50/pset6/dictionaries/large"

// prototype
double calculate(const struct rusage* b, const struct rusage* a);

int main(int argc, char* argv[])
    // check for correct number of args
    if (argc != 2 && argc != 3)
        printf("Usage: speller [dictionary] text\n");
        return 1;

    // structs for timing data
    struct rusage before, after;

    // benchmarks
    double ti_load = 0.0, ti_check = 0.0, ti_size = 0.0, ti_unload = 0.0;

    // determine dictionary to use
    char* dictionary = (argc == 3) ? argv[1] : DICTIONARY;

    // load dictionary
    getrusage(RUSAGE_SELF, &before);
    bool loaded = load(dictionary);
    getrusage(RUSAGE_SELF, &after);

    // abort if dictionary not loaded
    if (!loaded)
        printf("Could not load %s.\n", dictionary);
        return 1;

    // calculate time to load dictionary
    ti_load = calculate(&before, &after);

    // try to open text
    char* text = (argc == 3) ? argv[2] : argv[1];
    FILE* fp = fopen(text, "r");
    if (fp == NULL)
        printf("Could not open %s.\n", text);
        return 1;

    // prepare to report misspellings
    printf("\nMISSPELLED WORDS\n\n");

    // prepare to spell-check
    int index = 0, misspellings = 0, words = 0;
    char word[LENGTH+1];

    // spell-check each word in text
    for (int c = fgetc(fp); c != EOF; c = fgetc(fp))
        // allow only alphabetical characters and apostrophes
        if (isalpha(c) || (c == '\'' && index > 0))
            // append character to word
            word[index] = c;

            // ignore alphabetical strings too long to be words
            if (index > LENGTH)
                // consume remainder of alphabetical string
                while ((c = fgetc(fp)) != EOF && isalpha(c));

                // prepare for new word
                index = 0;

        // ignore words with numbers (like MS Word can)
        else if (isdigit(c))
            // consume remainder of alphanumeric string
            while ((c = fgetc(fp)) != EOF && isalnum(c));

            // prepare for new word
            index = 0;

        // we must have found a whole word
        else if (index > 0)
            // terminate current word
            word[index] = '';

            // update counter

            // check word's spelling
            getrusage(RUSAGE_SELF, &before);
            bool misspelled = !check(word);
            getrusage(RUSAGE_SELF, &after);

            // update benchmark
            ti_check += calculate(&before, &after);

            // print word if misspelled
            if (misspelled)
                printf("%s\n", word);

            // prepare for next word
            index = 0;

    // check whether there was an error
    if (ferror(fp))
        printf("Error reading %s.\n", text);
        return 1;

    // close text

    // determine dictionary's size
    getrusage(RUSAGE_SELF, &before);
    unsigned int n = size();
    getrusage(RUSAGE_SELF, &after);

    // calculate time to determine dictionary's size
    ti_size = calculate(&before, &after);

    // unload dictionary
    getrusage(RUSAGE_SELF, &before);
    bool unloaded = unload();
    getrusage(RUSAGE_SELF, &after);

    // abort if dictionary not unloaded
    if (!unloaded)
        printf("Could not unload %s.\n", dictionary);
        return 1;

    // calculate time to unload dictionary
    ti_unload = calculate(&before, &after);

    // report benchmarks
    printf("\nWORDS MISSPELLED:     %d\n", misspellings);
    printf("WORDS IN DICTIONARY:  %d\n", n);
    printf("WORDS IN TEXT:        %d\n", words);
    printf("TIME IN load:         %.2f\n", ti_load);
    printf("TIME IN check:        %.2f\n", ti_check);
    printf("TIME IN size:         %.2f\n", ti_size);
    printf("TIME IN unload:       %.2f\n", ti_unload);
    printf("TIME IN TOTAL:        %.2f\n\n", 
     ti_load + ti_check + ti_size + ti_unload);

    // that's all folks
    return 0;

 * Returns number of seconds between b and a.
double calculate(const struct rusage* b, const struct rusage* a)
    if (b == NULL || a == NULL)
        return 0.0;
        return ((((a->ru_utime.tv_sec * 1000000 + a->ru_utime.tv_usec) -
                 (b->ru_utime.tv_sec * 1000000 + b->ru_utime.tv_usec)) +
                ((a->ru_stime.tv_sec * 1000000 + a->ru_stime.tv_usec) -
                 (b->ru_stime.tv_sec * 1000000 + b->ru_stime.tv_usec)))
                / 1000000.0);

Alright, next challenge is to implement load, check, size and unload as efficiently as possible. Now, open up dictionary.c on gedit. But, before you dive in, be sure to read the specifications.

OK, I assume you have read the specs, now let’s get you started! What do we need to do in dictionary.c ? In the dictionary.c, we have the helper function LOAD, which is loads the dictionary. Then, function CHECK, to checks if a given word is in dictionary. Function SIZE, returns the number of words in the dictionary. And function UNLOAD to frees the dictionary from memory .

Implement LOAD
A spell-checker will call LOAD function on the dictionary text file. For each word in the dictionary text file, LOAD function will store those words in the dictionary data structure. You can use either HASHTABLE or TRIE. But before we’re about dealing with linked list aswell, since the linked list is the buckets. In linked list, each node has a value, as well as a pointer to the next node. Dealing with linked list, is very important do not lose any links. And the last node points to NULL. How do we define it in C?

Linked list :

typedef struct node
   char word[LENGTH+1];
   struct node * next;

And there we have linked list. It just one linked list. But hashtable is an whole array in linked list. We have the same structure like before. But if we wanna go with an actual hashtable, we’re gonna make node pointer array , here for example size of 500.

typedef struct node
 char word[LENGTH+1];
 struct node* next;
node* hashtable[500]

Then, you’ll want to malloc the node for every new word that you have.

node* new_node = malloc(sizeof(node));
fscanf(file, "%s", new_node → word)

Where new_node -> word is the destination of that word.

Now, we’ll want to hash that word. That’s why we gonna call the HASH Function. Well, hash function takes a string and returns an index, in this case the index has to be less than the number of buckets. And the hash function has to be deterministic, that means, the same value needs to map to the same bucket every time. So, new_node → word has the word from dictionary. Then, hashing new_node → word will give us the index of the bucket of the hashtable. And it will insert that in the specific linked list.

Now, how about TRIE ?
Well, in TRIE function every node contains an array of node* s. One for every letter in alphabet + ”\’. And each element in the array points to another node. The structure is:

typedef struct node
   bool is_word;
   struct node* children[27];
node* root;

OK now, let’s implement the LOAD function with TRIE in the pseudocode below :

for every dictionary word, iterate thru the trie
each element in children corresponds to a different letter.
check the value at children[i]
  if NULL , malloc the node, have children[i] point to it
  if not NULL, move to the new node and continue
if at the end of word, set is_word to true

Implement CHECK

Speller.c will call CHECK function on every word in the inputted text file and printing all miss-spelled words. CHECK function must operate case-insensitivity. And assume the strings will only alphabetical and/ or apostrophes.

Let’s look at how you might CHECK with HASHTABLE :

if the word exist, it can be found in the hashtable
which bucket would the word be in?
search in that linked list by using strcmp

Now, let’s look at how you might CHECK with TRIE :

for each letter in input word
  go to corresponding element in children
  if NULL, word is misspelled
  if not NULL, move to next letter
  once at the end of input file
  check if is_word is true

Implement SIZE
Speller.c will also call SIZE function to determine of words in the dictionary. Just returns number of words in dictionary if loaded else 0 if not yet loaded.

Implement UNLOAD
And the last, speller.c will call UNLOAD function to free up memory.
Here’s how you might UNLOAD with hashtable :

for every element in hashtable
for every node in the linked list, you’ll want to free that node.

Freeing linked list :

node* cursor = head;
while(cursor != NULL)
    node *temporary = cursor;
    cursor = cursor->next;

Then, how about using TRIE ?

unload from bottom to top
travel to the lowest possible node
 free all pointers in children
 backtrack upwards, freeing all elements in each children array until you hit root node
recursion will coming handy

To make sure you’ve properly freed everything that you’ve malloced you can use VALGRIND. Running valgrind, will run your program how many bytes of memory you’re using and make sure that you’ve freed them all .

valgrind --leak-check=full ./speller ~cs50/pset6/texts/austinpowers.txt

Once you’ve done with dictionary.c, then compile and run your program as always. Then, check how fast your “spell-checker” works  by compare it with the staff’s. If it is done, you’ll want to check your correctness with check50.

Be sure to answer the following questions inside the questions.txt on gedit.

0. What is pneumonoultramicroscopicsilicovolcanoconiosis ?
1. According to its man page, what does getrusage do?
2. Per that same man page, how many members are in a variable of type struct rusage ?
3. Why do you think we pass before and after by reference (instead of by value) to calculate , even though we’re not changing their contents?
4. Explain as precisely as possible, in a paragraph or more, how main goes about reading words from a file. In other words, convince us that you indeed understand how that function’s for loop works.
5. Why do you think we used fgetc to read each word’s characters one at a time rather than use fscanf with a format string like “%s” to read whole words at a time? Put another way, what problems might arise by relying on fscanf alone?
6. Why do you think we declared the parameters for check and load as const ?

This was Problem Set 6.

Problem Set 5 : Forensics

Hello guys! Welcome back. This is CS50! We’re going to start a Problem Set 5. In this problem set, you’ll get more comfortable with data structures, hexadecimal, and pointers. Also, acquaint you with file I/O. As always, before we get started you will want to read these :

Recommended Reading :
But, the Wikipedia articles are a bit dense, so feel free to skip it.

Recommended watching :
File I/O :
Structs :
Valgrind :

Getting Started

Welcome back!
As always, you’ll need to read a long the specification.
Open you appliance, then open up the terminal window and execute


To make sure your appliance is up-to-date.
Like Problem Set 3 and 4. This problem set comes with the distribution code that you’ll need to download before getting started. Go ahead, and execute :

cd ~/Dropbox

In order to navigate your way to ~/Dropbox. Next, execute :


In order to download a ZIP (i.e., compressed version) of this problem set’s distro.If you then execute :


you should see that you now also have a pset5 directory. You’re now welcome to delete the ZIP file with the below :

rm -f

Now dive into that pset5 directory by executing the below :

cd pset5

Now execute :


And you should see that the directory contains the below :

bmp/ jpg/ questions.txt

How fun! There are two subdirectories and a file. Who know what’s inside ? Let’s get started.
Have you ever seen Windows XP’s default wallpaper (think the rolling hills and blue skies) ? Then, you’ve seen BMP. If you ever looked at webpage you’ve probably seen GIF. If you’ve ever looked at digital photo you’ve probably seen JPEG. And, if you’ve ever taken a screenshot of Mac, you’ve seen PNG. Read up a bit of GIF, JPEG, BMP and PNG file formats, then open up questions.txt on gedit. Be sure you can answer these questions :

0. How many different colors does each format support?
1. Which of these formats supports animation?
2. What’s the difference between lossy and lossless compression?
3. Which of these formats is lossy-compressed?

Read up at the MIT’s article :
And try to answer these questions on ~/Dropbox/pset5/questions.txt.

4. What happens, technically speaking, when a file is deleted on a FAT file system?
5. What can someone like you do to ensure (with high probability) that files you delete cannot be recovered?

Anyway, you have to do 3 parts in this problem set and they are :

  • whodunit.c
  • resize.c
  • recover.c



We’re going to find out. In this game clue, you might be given a little red image. And the image is very red and spotty. Your job is to revealed the hidden message among this file’s red noise is a drawing whodunit.


In whodunit, you are given a Bitmap image that was very spotty and red. And run the whodunit program to reveal the hidden message. So, let’s break this problem.

1. Open the file
2. Update header info
3. Read clue scanline, pixel by pixel
4. Change pixel color as necessary
5. Write into verdict scanline, pixel by pixel

First, you’ll want to open the file, the clue that you’ve given. And also create a verdict bitmap file. And then you’ll want to update the bitmap header info for the verdict outfile. More on that later. And then, you’ll wan to read into the clue, scanline pixel by pixel, change pixel color as necessary and write into verdict scanline pixel by pixel. How do we start it? Luckily, we have a copy.c in the distribution code and this is going to prove quite useful to us. Here is the sneak peak of copy.c

And, then read infile and update the outfile’s header

Then, read each pixel

read each pixel
And then, write the pixel into the outfile:

fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);

So, your first step might be to run the following command in the terminal:

cp copy.c whodunit.c

This would create a copy from a copy.c named whodunit.c

Pseudocode for whodunit.c :
1. Open the file (still same like copy.c , so no need to change anything)
2. Update header info (still same)
3. Read clue scanline, pixel by pixel (still same)
4. Change pixel color as necessary
5. Write into verdict scanline, pixel by pixel
Ok, I’ll walk you thru it.

1. Opening files :

FILE* inptr = fopen("foo.bmp", "r");

Opens foo.bmp for reading that represented by “r“.

 FILE* outptr = fopen("bar.bmp", "w"); 

Opens bar.bmp for writing that represented by “w“.

Next step, we’re going to update header info. What’s the header info ? Well, first we have to know what the bitmap is.

Open up the bmp.h on gedit.
What does the structure of BITMAPFILEHEADER contain ? The BITMAPFILEHEADER structure contains information about the type, size, and layout of a file that contains a DIB [device-independent bitmap].


Then, what does the structure of BITMAPINFOHEADER contain ? The BITMAPINFOHEADER structure contains information about the dimensions and color format of a DIB [device-independent bitmap].

Header :

  • biSizeImage : is the total size of image (in bytes) and include pixel and padding. More on those later.
  • biWidth : is the width of image (in pixels) , this doesn’t incude padding.
  • biHeight : is the height of image (in pixels).

There are 2 structs on Header : BITMAPFILEHEADER and BITMAPINFOHEADER.

So, how do we update the header info? We first want to see is anything changing in the clue (the infile) to the verdict (the outfile).
2. Updating Header Info :

  • New bmp → new header info
  • Is anything changing ? Well, no actually. Because we’re going to changing the color.
    File size (not changing).
    Image size (not changing).
    Width (not changing).
    Height (not changing).

So, you’re right for now by just copy it. Next, how do we read every pixel ?
3. Reading file :

fread(&data, size, number, inptr);

&data : is a pointer to a struct which will contain the bytes you’re reading.
size : size of each elements to read , here the function sizeof will coming handy.
number : is a number of each elements to read.
inptr : FILE* to read from
Then, let’s change the color as we need :

As you can see, inside of the rgb structure, there are rgbtBlue, which is the amount of blue, rgbtRed which is the amount of red, and rgbtGreen which is the amount of green.

4. Changing pixel color :
Each color represented by 3 bytes :

  • amount of blue
  • amount of red
  • amount of green
    ff0000 blue
    ffffff → white

So, can you change the color to green ? You will want to call RGBTRIPLE (a struct to represent pixel). By using dot (.) operator.
See example below :

triple.rgbtBlue = 0x00;
triple.rgbtGreen = 0xff;
triple.rgbtRed= 0x00;

With that, it gives me a green pixel. Next, what if I want to check the value of something?
See example below :
If you’d like check the value of blue. You may execute :

if (triple.rgbtBlue == 0xff)
   printf("I’m feeling blue!");

For whodunit, let me suggest you to use “remove all RED” method. But still, there are a couple of ways to solve this problem. Ok, so now assume we’ve changed the pixel color. The next step is write into the verdict scanline.

5. Writing into verdict scanline, pixel by pixel :

Again you’ll want to take a look copy.c and see how to writing files.

fwrite(&data, size, number, outptr);

&data : is a pointer to a struct which will contain the bytes you’re reading from.
outptr : FILE* to write to.

But, you also have to determine the padding. What is padding? Well, every RGBt pixel is 3 bytes long. But, the scanline for bitmap image has to be multiple of 4 bytes. If the number of pixels isn’t multiple of 4, we need “padding”. Padding is just the represented of zero. So, how do we read and write this ? Well, you can’t actually “fread” padding but you can calculate it.

Padding :

  • Padding isn’t a RGBTRIPLE so we can’t fread padding.
  • The clue and the verdict have the same width, so the padding is the same!
padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

Now, we have the padding formula. Then, how can we write it? Using “fputc”.

fputc (chr, outptr);

chr : char to write
outptr : FILE* to write to.

fputc(0x00, outptr);

Then, you’ll want to move file position indicator. Now, you’ll want to use “fseek”.

fseek(inptr, amount, from);

inptr : FILE* to seek in.
amount : number of bytes to move cursor.
from : relates to reference points.

  • SEEK_CUR : (current position in file).
  • SEEK_SET : (beginning of file).
  • SEEK_END : (end of file).

So, we’ll want to use fseek to skip over the padding of infile. So, once you open verdict, you can see who’s the creator of this problem. You’re done whodunit!


Alright, next challenge! Implement now in resize.c a program called resize that resizes 24-bit uncrompressed BMPs by a factor of n. Your program should accept exactly three-command line arguments, per the below usage, whereby the first(n) must be a positive integer less than or equal to 100, the second the name of the file to be resized, and the third name of resized version to be written.

Usage : ./resize infile outfile

With a program like this, we could have created large.bmp out of small.bmp by resizing the latter by a factor of 4 (i.e multiplying both its width and its height by 4), per the below :

./resize 4 small.bmp large.bmp

You’re welcome to get started by copying (yet again) copy.c and naming the copy resize.c. But spend some time thinking about what it means to resize a BMP.


  1. Open file
  2. Update header info for outfile
  3. Read each scanline pixel by pixel
  4. Resize horizontally
  5. Remember padding!
  6. Resize vertically
  • Opening file

You know how to do that! It’s still same and also you’re welcome to get copying again copy.c by execute :

cp copy.c resize.c
  • Updating header info for outfile

Because we have new BMP we also have to update the header info. What’s changing ? File size, image size, width and height are have to change. Try to look at the header info (again) :
Header :

  • biSizeImage : is the total size of image (in bytes) and include pixel and padding.
  • biWidth : is the width of image (in pixels) , this doesn’t include padding.
  • biHeight : is the height of image (in pixels).
  • There are 2 structs on Header : BITMAPFILEHEADER and BITMAPINFOHEADER
  • Reading scanline pixel by pixel

Again, you’ll wan to call file I/O function “fread”. Look at below (again) :

fread(&data, size, number, inptr);

&data : is a pointer to a struct which will contain the bytes you’re reading.
size : size of each elements to read , here the function sizeof will coming handy.
number : is a number of each elements to read.
inptr : FILE* to read from.

  • Resizing horizontally

If I could assume a pixel as a block . How do we resize it horizontally ? well, let’s assume :

n = 2

Then, the block should be two times of the current width. OK, this time you’ll want to use “fwrite” function.

fwrite(&data, size, number, outptr);

&data : is a pointer to a struct which will contain the bytes you’re reading from.
outptr : FILE* to write to.
Can you figure out how? I leave you to determine it by yourself.

  •  Remember padding.

Do you remember how ? If don’t please take a look at the previous explanation about padding on whodunit.

  • Resize Vertically

Several ways to do this :

  1. “Rewrite” methods :
    • Remember all of the pixels in a array
    • And Write as many as needed


2. “Re-copy” methods :
• Go back to the start of the original row
• Repeat the horizontal resizing.

So, we’ll understand resize.c is all about :
1. Each pixel repeated n times
2. Every row repeated n times
With that you’ll have a Bitmap large image! If you’d like to check the correctness of your program with check50, you may execute the below.

check50 2014/x/pset5/resize bmp.h resize.c

If you’re done with it, be sure you can answer the following questions in ~/Dropbox/pset5/questions.txt.

6. What’s stdint.h ?
7. What’s the point of using uint8_t , uint32_t , int32_t , and uint16_t in a program?
8. How many bytes is a BYTE , a DWORD , a LONG , and a WORD , respectively? (Assume a 32-bit architecture like the CS50 Appliance.)
9. What (in ASCII, decimal, or hexadecimal) must the first two bytes of any BMP file be? (Leading bytes used to identify file formats(with high probability) are generally called “magic numbers.)”
10. What’s the difference between bfSize and biSize ?
11. What does it mean if biHeight is negative?

12. What field in BITMAPINFOHEADER specifies the BMP’s color depth (i.12. e., bits per pixel)?
13. Why might fopen return NULL in copy.c:37 ?
14. Why is the third argument to fread always 1 in our code?
15. What value does copy.c:70 assign padding if bi.biWidth is 3 ?
16. What does fseek do?
17. What is SEEK_CUR ?

 CSI (Computer Science Investigation)

Alright, so let’s pull up all your new skill into the last. Take a look at

Long story shorts, in this problem you have to recover 50 photos that’ve been deleted. Fortunately, in the Computer world “deleted” tends not to mean “deleted” so much as “forgotten”. Let’s make a file called recover.c inside the ~/Dropbox/pset5/jpg a program that will recover all photos.

What is the format for photos? Well, it should be a JPEG. You’ll know that JPEGs are more complicated than BMPs but luckily JPEGs have signatures patterns of bytes. Specially, the first four bytes of most JPEGs are either :

0xff 0xd8 0xff 0xe0
0xff 0xd8 0xff 0xe1

For simplicity, you should hard code ”card.raw” in your program, your program need not accept any command-line arguments. When executed, your program should recover every one of JPEGs from “card.raw“. Your program should number the files its outputs by naming each ###.jpg where ### is three-digits decimal number from 000 on up (you’ll want to call sprintf function). How to check whether your program is correct? Well, just simply double-click and take a look! If the photo are appears, your operation was likely a success!
Okay, let’s get started.

1. Open memory card file
2. Find the beginning of JPG
3. Open a new JPG
4. Write 512 bytes until new JPG is found
5. Detect end of file

  • Opening memory card file

You know how to solve this already! Don’t forget to use File I/O function.

  • Find the beginning of JPG

Well, just like a BMP, JPEG is also just a sequence of bytes. As you’ve read above, the signatures of JPEGs are either :

0xff 0xd8 0xff 0xe0
0xff 0xd8 0xff 0xe1

And, it’s stored side by side in the memory card. How can do we read the 512 bytes? Well, let’s go back to “fread” struct.

fread(&data, size, number, inptr);

&data : buffer.
We have to read 512 bytes at the time. Can you figure out how? You’ll want to define BUFFER and storing it by 512.

  • Opening a new JPG

Since you’ve reached the first JPG, then how do we open it? Let’s make the new JPG. The file name of JPG is ###.jpg the ### is going to be number format. So, the first jpeg you’ve found is 000.jpg and so forth. So keep track!

Then, how do you actually make the jpg? You’ll want to call “sprintf” function. It’s a bit similar with“printf”. But, in this case, “sprintf” will print the file out in the current directory and not in the terminal.

sprint(title, "%d.jpg", 2);

title : char array to store the resultant string
%d.jpg : will give you name like 2.jpg.. so, how do you make it to be 002.jpg?

  • Write 512 bytes until new JPG is found

Remember “fwrite

  • Detect end of file

Ok, so it’s a bit confusing now. Let me get you the pseudocode for recover.c.
Pseudocode :

open card file
    while eof check
         fread first 512 bytes
         if signature is JPEG
              check if outptr != null
              close output file
              update file name counter
            create new filename
            open file
            write the current 512 bytes to the outfile
         else if signature is not JPG && outptr != null
            fwrite current 512 bytes to outfile
close any remaining file

With that you’ve recovered all of the photos! Congratulations! If you’d like to check your correctness of your program with check50, you may execute the below :

check50 2014/x/pset5/recover recover.c

And you’re done!

This was Problem Set 5.

Problem Set 4 : Breakout

Challenge for this problem set is to implement a game. The game is Breakout. Problem Set 3 was also a game, but its graphical user interface (GUI) wasn’t exactly a GUI, it was textual user interface, since we essentially simulated graphic with printf. Let’s give Breakout actual GUI by building atop the Stanford Portable Library (SPL), which is similar spirit with CS50 library but include an API (application programming interface) for GUI programming and more.

Unfortunately, I have no pseudocode for this problem set since you have all you need in the Stanford cslib package.

Take your time to look at the specifications and have fun!

If you’re done with it. You’ll see you’ve made a game. Because this game expects a human to play, no check50 for this one!

Be sure you’re inside the Problem Set 4’s directory by execute :

cd ~/Dropbox/pset4

You’ll see :

jharvard@appliance (~/Dropbox/pset4):

Then, execute :

jharvard@appliance (~/Dropbox/pset4): ./breakout

And, viola!


You’re ready to play!

This was Problem Set 4.

Problem Set 3 : Game Of Fifteen

Be sure to check the previous post before getting started to read this.

Alright! Welcome back. This is CS50! So, recall in the past days we’ve been spending a quite bit of time on C, on programming, on syntax. And, it’s quite normal if you still struggling about Problem Set 2, to banging your head again on the wall. It’s cryptic-error messages and bugs that you can’t quite chase down. So, if that any consolation hang in there for now. If you can solve it then, can you guess what the string actually says when I typed “ X Lvne Noh! “? Fantastic!

Today, though, we begin to transition to higher level which is more complex but actually it can help you more comfortable in programming and how we can go about optimizing and efficiency of our algorithm and generally solving more interesting problem. How can we go coding effectively by using running time. This problem set will introduce you to larger programs with multiple source files. Accustom you to reading someone else’s code, empowering you with Makefiles, and implement a party favor.

You’ll be more comfortable with :

  • Array(s)
  • Searching algorithm
  • Sorting algorithm
  • gdb

And anyway, you have to do 2 parts of this problem set :

  1. find
  2. fifteen

Recommend Watching :
Lecturer :
Binary search :
Linear search :
Bubble sort resources :
Insertion sort :
Selection sort :
Recommend Reading :
Page 17 of

Phew, so many videos! And so many pages to read! If you’re done with it, be sure you can anwer these questions when it comes to submit this problem set’s form!

1. Why does binary search require that an array be sorted?
2. Why is bubble sort in O(n) ?
3. Why is insertion sort in Ω(n)?
4. What’s the worst-case running time of merge sort?
5. In no more than 3 sentences, how does selection sort works?

Getting Started.

For problem set 3, you’ll instead download “distribution code”(otherwise known as “distro”), written by cs50 team, and add you own line of code to it. You’ll first need to read and understand their code, though, this problem set is as much about learning to read someone else’s code as it is about writing your own!

Let’s get you started. Go ahead and open up terminal window. Then execute :


To make sure your appliance is up-to-date. Then execute

cd ~/Dropbox

Followed by


to download a ZIP of this problem set’s distro into your appliance (with command-line program wget). You should see a bunch of output followed by:

‘’ saved

Ultimately confirm that you’ve download by executing :


Then, run


To unzip file. If you run ls again, you should see that you have newly unzipped directory called pset3 as well. Proceed to execute :

cd pset3

Followed by


And you should find see that the directory contains two “subdirectories” :

fifteen find

Searching Algorithm

Searching algorithm is “ an algorithm for finding an item with specified properties among a collection of items. The items may be stored individually as records in a database; or may be elements of a search space defined by a mathematical formula or procedure, such as the roots of an equation with integer variables; or a combination of the two”


A Sorting algorithm is “an algorithm that puts elements of a list in a certain order. The most-used orders are numerical order and lexicographical order. Efficient sorting is important for optimizing the use of other algorithms (such as search and merge algorithms) which require input data to be in sorted lists; it is also often useful for canonicalizing data and for producing human-readable output”

Okay, let’s dive into the first of those subdirectories.

Open up the terminal and execute :

cd ~/Dropbox/pset3/find

You should see below :

helpers.c helpers.h Makefile find.c generate.c 

Phew, that’s a lot of files! Take a look at each file. And try to undersand what do they mean.

And again, please read the spec first!

Let’s begin the first problem “find”.


  • Prompt for numbers to fill the haystack
  • Searches the haystack for a needle
    – call sorts and searches, function defined in helper.c
    helpers.c was the helper function in Problem Set 3. You’ll need to complete the fully function on it.


  1. Search
  2. Sort

Open up the terminal and execute :

cd ~/Dropbox/pset3/find

To make sure you are in a right subdirectory. Then, open up gedit and open helpers.c.
Not sure where to begin?
Anyway,you’ll want to implement a searching and sorting algorithm.


  1. Return true if value is found at haystack
  2. Return false if values is not found at haystack

Linear search : you can do better!
• O(n) → slow
• Can search any list
Binary search :
• O(log n) → fast
• Can only search sorted list
Binary search pseudocode :

bool search(int value, int values[], int n)
 while length of the list > 0
    look at the middle of list
    if number found, return true
    else if number higher, search left
    else if number lower, search right
 return false


Sort the values[] array

void sort(int values[], int n)

Selection sort pseudocode :

for i = 0 to n-1
  for j = i + 1 to n
    find index of minimum value
  swap array[min] and array[i]

Bubble sorts pseudocode :

- iterate over the list
- compare adjacent elements
- swap elements that are in the wrong order
- largest elements will ‘bubble’ till the end
- the list is sorted once no elements have been swapped

And, you’re done the first problem! Conguratulations!

The Game Begins

Now the second problem is a Game Of Fifteen puzzle played on a square, two-dimensional board with numbered tiles that slide. The goal of this puzzle is to arrange the board’s tiles from smallest to largest, left to right, top to bottom, with an empty space in board’s bottom-right corner as in the below :


You should make your “move” (i.e that borders the board’s empty space)with sliding any tile from smallest to largest, left to right, top to bottom. Although the configuration of board above depicts the game is already won. You should not make any move diagonally or forcibly removed from the board. If, however and only if the board contain odd number (i.e the height and weight of board are even), the position of number 1 and 2 must be swapped. It solvable if the configuration as see below :


Navigate your way to :


And take a look at fifteen.c with gedit.
Read over the code and comments in fifteen.c and be sure you can answer the questions below before proceeding further.

  1. Besides 4 x 4 (which are game of fifteen’s dimension), what other dimension does the framework allow ?
  2. With what sort of data structure is the game’s board represented?
  3. What function do you apparently need to implement?

You’ll want to take “baby steps” to implement this game. Four things that you’ll need to implements are :

  1. Init
  2. Draw
  3. Move
  4. Won
15 14 13 12
11 10 9  8
7  6  5  4
3  1  2  _

Recall that the positions of tiles numbered 1 and 2 should only start swapped as they are in 4 x 4 as example above. But they do not swapped in 3 x 3 example below :

8  7  6
5  4  3
2  1  _


void init(void)

Initializes the game’s board with tiles numbered 1 through d*d – 1 (i.e., fills board with values but does not actually print them), whereby board[i][j] represents row i and column j.

Board represented by 2D dimensional array.


Init pseudocode :

board should contain the starting state
   • board[i][j] represents the elements at row[i] col[j]
Starts in descending order
   • if the number tiles odd, swap 2 and 1


void draw(void)

Prints the board in its current state. Then, print the blank space before single-digit #s using :

printf("%2d", board[i][j]);

Draw pseudocode :

for each row
  for each value in row
     print value and space
  print new line


bool move(int tile)

If tile borders empty space, moves tile and returns true, else returns false.

Move pseudocode :

Accept the number of tile to move
  Not its positions!
  Search for the tile’s position.
Remember where the blank tile is now


bool won(void)

Returns true if game is won (i.e., board is in winning configuration), else false. Game is won when tiles are in increasing order.

1  2  3
4  5  6
7  8  _

Won pseudocode :

  • Iterate over board and check the values
  • If any values in incorrect, return false

Viola, you’ve finished Game Of Fifteen. To test your implementation of fifteen, you can certainly try playing it.(No check50 for this one). Know that program to quit by hitting ctrl-c. To test your program with, say, the first of those inputs, execute the below.

./fifteen 3 < ~cs50/pset3/3x3.txt

Now, you’re done with both Find and Game Of Fifteen!

This was Problem Set 3.

Problem Set 2 : Crypto

Hello, world! Congratulations, you’ve completed problem set 1! Now, we’re getting started into Problem Set 2. What was the problem? In this problem set, you’ll study about Cryptography , which was very challenging and exciting at the same . You will be among the “more comfortable” if you can complete this pset. Anyway, you have to complete 2 parts in it :

  1. Caesar Cipher
  2. Vigenere Cipher

Then we’re gonna talk about “What is Cryptography?“ (

“Why did we do this?” Well, it’s very useful. Say, if you want to send a message to your crush but you don’t want others see what exactly you said. So we can keep secret from each other what the message actually says by using Cryptography. Since, the actual string will be covered by the key which can make the primary text hiding. For example : “Can I have your number ? “ you can use 11 as the secret key, and it will say “Nly T slgp jzfc yfxmpc ?” instead of above. Who knows what you said then? But, how’s work ? That’s simple. Ok, I used 11 for the key, the letter “C” inside of the word “Can” was changed by “N” which was 11 letters away from “C”. Can you figure out the next letters? It’s really fun!

The parts of Cryptography are :

  1. Key (secret position a non- negative integers) see :
  2. Ciphertext (Encrypted message) see :
  3. Plaintext (Unencrypted message) see :

By the way, an ASCII characters are very useful in order to do this pset.


(image :

Alright, here we go!

Open up the terminal inside of the appliance then execute :


To make sure that your appliance is up-to date.

Next, execute :

mkdir ~/Dropbox/pset2

This was a command for make new directory called “pset2” inside of “Dropbox”.

Then, execute :

cd ~/Dropbox/pset2

To make sure that you move yourself into that directory. Your prompt now should be like :

jharvard@appliance (~/Dropbox/pset2) : 

  1. Caesar cipher.

Have you watched short videos ? If haven’t , be sure to watch it first ( it will be helpful. Recall from the video’s short that Caesar’s cipher encrypts (i.e scrambles in a reversible way) messages by rotating each letter by “k” positions, wrapping around “z” to “A” as needed ( in other words, if “p” is some plaintext (i.e unencrypted message), “pi” is the i-th character in “p”, and “k” is the secret key (i.e non negative integer), then each letter “ci” in the ciphertext “c” is computed as :

ci = (pi + k) % 26

ci = i-th letter of ciphertext.

pi = i-th letter of plaintext.

k = the key.

%26 = remainder after dividing by 26.

This formula perhaps makes the cipher seem more complicated than it is, but it’s really nice way of expressing the algorithm precisely and concisely.

Anyhow, your goal is to write caesar.c, a program that encrypts message by using Caesar Cipher.

Where to begin?

  • This program needs to accept a command-line argument, “k” so this time you’ll want to declare main with :
int main(int argc, string argv[])

The “argv” is an array of strings. Keep in mind that arrays are zero-indexed. To access the next letter, you use syntax like argv[1]. With that you can access for each letter with the code like :

string k = argv[1];
  • Your program must a single command line-argument. If your program is executed without any command line argument, your program should yell at the user and return value of 1 :
return 1;
  • The users must type an integer at the prompt, that doesn’t mean their input will be stored as an int. It will stored as a string. You’ll need to convert that string to an actual int. As luck, we would have a function atoi exists for exactly that purposes. Here’s how you might use :
int k = atoi(argv[1]);

But don’t forget to add the library #include <stdlib.h> because atoi is declared there.

  • OK, so once you’ve got “k” stored as an int. You’ll need to ask the user for some plaintext. GetString() can help you with that.
  • You can iterate over the characters in a string, printing each one at the time, with code like below :
for (int i = 0, n = strlen(p); i < n ; i++)
     printf("%c", p[i]);

Incidentally, you’ll want to add another header file #include in order to use strlen

Here you go with the pseudocode !

Pseudocode :

  1. Get the key
  2. Get the plaintext
  3. Encipher
  4. Print Ciphertext

If you’re done with that. So we can automate some tests of your code, your program must behave per the below. Assumed that the underline text is what some user has typed.

jharvard@appliance (~/Dropbox/pset2) : ./caesar 13
Be sure to drink your Ovaltine!
Or fher gb qevax lbhe Binygvar!

If you’d like to check the correctness of your program with check50, you may execute the below:

check50 2014/x/pset2/caesar caesar.c

Congrats! You’ve completed Caesar!

  1. Vigenere cipher.

This last cipher of this problem set was hardly secure. Be sure to watch Vigenere’s short there was more sophisticated algorithm out there. It’s French

Vigenere’s cipher improves upon Caesar’s by encrypting messages using a sequence of keys, in other word, if “p” is a plaintext and “k” is a keyword, then each letter “ci” in the ciphertext “c” is computed as :

ci = (pi + kj) % 26

ci = i-th letter of ciphertext.

pi = i-th letter of plaintext.

kj = j-th letter of the key.

%26 = remainder after dividing by 26.

Note this cipher’s use of “kj” as opposed to just “k”. And recall that. If “k” is shorther than “p”, then the letter in “k” must reused cyclically as many times as it takes to encrypt “p”.

Your next challenge is to write in vigenere.c, a program that encrypts messages using Vigenere’s cipher.

Pseudocode :

Get the key

  • 2nd command line argument : argv[1]
  • Must be alphabetical : isalpha

Get plaintext

  • GetString()


  • Advance the next letter in keyword only if the character is a plaintext letter
  • isalpha
  • Preserve case
  • isupper, islower
  • Keep track of :
  • Position in plaintext
  • Position in keyword

In two separate variables.

Print ciphertext

With that, you’ll complete Vigenere cipher. So we can automate some tests of your code, your program must behave per the below :

jharvard@appliance (~/Dropbox/pset2): ./vigenere bacon 
Meet me at the park at eleven am 
Negh zf av huf pcfx bt gzrwep oz

If you’d like to check the correctness of your program with check50, you may execute the below:

check50 2014/x/pset2/vigenere vigenere.c

And, viola! You’ve completed Caesar and Vigenere cipher! Congratulations!

This was Problem Set 2.