0% found this document useful (0 votes)
7 views

04 Algorithms

This document discusses using JavaScript for programming and web development. It introduces JavaScript and how it is commonly used to add interactivity to web pages. It then provides examples of basic HTML pages with JavaScript code to prompt for a user's name and display it. Finally, it demonstrates how to build a simple backend program in Python that works with the JavaScript code to search a word list and return the words before and after the given name.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

04 Algorithms

This document discusses using JavaScript for programming and web development. It introduces JavaScript and how it is commonly used to add interactivity to web pages. It then provides examples of basic HTML pages with JavaScript code to prompt for a user's name and display it. Finally, it demonstrates how to build a simple backend program in Python that works with the JavaScript code to search a word list and return the words before and after the given name.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 47

Algorithms and Javascript

Chris Gregg, based on slides by Eric Roberts


CS 208E
October 1, 2021
A Quick Introduction to JavaScript
• It is impossible to learn about programming without writing
programs. In his book, Eric Roberts decided—after trying
several other possibilities—to use JavaScript as the
programming language.
• One of the advantages of JavaScript is that it is by far the most
common language for creating interactive content on the web.
That means that it will certainly stick around.
• Another advantage is that JavaScript can be simplified into a
language that is easy to learn and use without ever violating
the rules of the language. You simply banish the messy parts
of JavaScript and focus on the parts that are well designed.
Javascript and HTML
• Although it is the "programming language that runs the World
Wide Web," Javascript is not the foundation of the Web -- that
would be the markup language, HTML.
• Conceived in 1980 and implemented in 1991 by Sir Tim
Berners-Lee (Knighted by Queen Elizabeth in 2004, and 2016
Turning Award Winner), HTML can be used to interpret and
compose text, images, and other material for web pages.
• It is the building block for web pages, and is based on "tags"
such as <p> (paragraph) and <img /> (image) which are
used to interpret the page.
• We need a little bit of HTML to start writing in Javascript, but
it is a big standard with many interesting and subtle parts to it.
A Basic Web Page
We are going to put a web page onto your own
Stanford web space. Log into myth via ssh (see one of
the videos https://tinyurl.com/4pnuxpsj if you don't
know how to do that) and type the following:

$ cd WW
$ mkdir playground ; cd playgroun
$ vim index.html

You can replace "vim" with "emacs" or "nano," if you


prefer a different editor. If you've never used a Unix
editor, use "nano". If a web server finds an index.html
file in a directory, it will load it as a web page.
W

A Basic Web Page


Here is a basic web page:

<!DOCTYPE html
<body onload="init()"

<h1>Welcome!</h1

<p>Hello, Random Person!</p

</body>

Save this page, and then go to the following web page,


with your name in the place of YourSUNet (don't
forget the tilde ~):

https://stanford.edu/~YourSUNet/playground/
>

>

>

>

A Basic Boring Web Page


Here is a basic boring web page:

<!DOCTYPE html
<body onload="init()"

<h1>Welcome!</h1

<p>Hello, Random Person!</p

</body>

Let's make it more interesting by adding Javascript.


>

>

>

>

Our First Bit of Javascript


<!DOCTYPE html
<head
<script
function init()
const name = window.prompt("What is your name?")
name_span = document.getElementById("entered_name")
name_span.innerHTML = name

</script
</head

<body onload="init()"

<h1>Welcome!</h1

<p>Hello, <span id="entered_name">Random Person</span>!</p

</body>
}

>

>

>

>

>

>

>

>

Let's Write a Backend


So far, we've written frontend code that is entirely run in your
browser. I.e., your browser reads in the index.html file
(which includes some Javascript), and the browser controls
all the logic.

Most web pages also include a backend, which can store data
and run programs on the server where the web page is
located. The frontend makes a request to the backend
(possibly with some data), and a program is run on the
backend and returns data to the frontend.

You can request "CGI access" from Stanford for your web
space, and you can then put runnable files (Python, PERL,
PHP, compiled C, Bash, etc.) in the cgi-bin directory,
which sits alongside your WWW directory.
A simple backend program
Let's write our backend in Python. We need to first create the
appropriate directory in our cgi-bin directory, and copy
over a word list. Then we can create the python program:

mkdir ~/cgi-bin/playgroun
cd ~/cgi-bin/playgroun
cp /usr/share/dict/words .
vim ~/cgi-bin/playground/search-words.cgi

The server will only run files that end in .cgi


d

A simple backend program


Here is the program (you can copy/paste from here):
https://web.stanford.edu/~cgregg/playground/search-words.cgi
#!/usr/bin/env pytho

import os, cgi, cgitb, jso


cgitb.enable() # for debuggin

DICT_FILE = "words

print("Content-type:application/javascript\n"

form = form = cgi.FieldStorage(


if form.has_key("firstname") and form["firstname"].value != ""
firstname = form["firstname"].value.lower(
with open(DICT_FILE) as f
words = [x[:-1] for x in f.readlines() if x[0].islower()

# find the two words surrounding nam


prev = '

for idx, word in enumerate(words)


if word == firstname
continu
if word > firstname
if idx > 0
print(json.dumps({'prev': prev, 'next': word})
brea
else
print(json.dumps({'prev': '', 'next': word})
brea
prev = wor

else
print(json.dumps({'prev': '', 'next': ''}))
:

'

"

A simple backend program


Next, you need to make your python program executable.
Then, we'll change our html file:
chmod +x search-words.cg
vim ../../WWW/playground/index.html

A simple backend program


Next, you need to make your python program executable.
Then, we'll change our html file (copy from here).
https://web.stanford.edu/~cgregg/playground/index.html.txt
<!DOCTYPE html
<head
<script
function init()
const name = window.prompt("What is your first name?")
name_span = document.getElementById("entered_name")
name_span.innerHTML = name
search_words(name)

function search_words(name)
fetch('../cgi-bin/playground/search-words.cgi?firstname=' + name
.then(response => response.json()
.then(data =>
console.log(data
prev_word = document.getElementById("prev_word")
next_word = document.getElementById("next_word")
prev_word.innerText = data.prev
next_word.innerText = data.next
})

</script
</head

<body onload="init()"

<h1>Welcome!</h1

<p>Hello, <span id="entered_name">Random Person</span>!</p


<p>Your name is preceded by <b><span id="prev_word">...</span></b> in the dictionary, an
<b><span id="next_word">...</span></b> comes after it.</p

</body>
}

>

>

>

>

>

>

>

>

>

Expressions in JavaScript
• As in most languages, computation in JavaScript is specified
in the form of an expression, which usually consists of terms
joined together by operators.
• Each term must be one of the following:
– A constant (such as 3.14159265 or "hello, world")
– A variable name (such as n1, n2, or total)
– A function call that returns a value (such as sqrt)
– An expression enclosed in parentheses

• You can test this in a browser directly by using the Developer mode:
• In Google Chrome:
• View->Developer->Javascript Console.
• In Apple Safari:
• Go to Safari->Preferences and then the advanced tab, and click "Show
Develop menu in the menu bar." Then, Develop->Show Javascript
Console.
Expressions in JavaScript
• As in most languages, computation in JavaScript is specified
in the form of an expression, which usually consists of terms
joined together by operators.
• Each term must be one of the following:
– A constant (such as 3.14159265 or "hello, world")
– A variable name (such as n1, n2, or total)
– A function call that returns a value (such as sqrt)
– An expression enclosed in parentheses

• You can test this in a browser directly by using the Developer mode:
• In Google Chrome:
• View->Developer->Javascript Console.
• In Apple Safari:
• Go to Safari->Preferences and then the advanced tab, and click "Show
Develop menu in the menu bar." Then, Develop->Show Javascript
Console.
Variables
• The simplest terms that appear in expressions are numeric
constants and variables. A variable is a placeholder for a value
that can be updated as the program runs.
• A variable in JavaScript is most easily envisioned as a box
capable of storing a value.
answer
42

• Each variable has the following attributes:


– A name, which enables you to tell different variables apart.
– A value, which represents the current contents of the variable.
• The name of a variable is fixed. The value changes whenever
you assign a new value to the variable.
Variable Declarations
• It is good practice to declare a variable before you use it. The
declaration sets the name of the variable and the initial value.
• The general form of a variable declaration is
let name = value;

where name is the name of the variable and value is an


expression specifying the initial value.
• Most declarations appear as statements in the body of a
function definition. Variables declared in this way are called
local variables and are accessible only inside that function.
• Variables may also be declared outside of any function, in
which case they are global variables. The only global
variables used in the book are constants written in upper case.
Operators and Operands
• Like most languages, JavaScript specifies computation using
arithmetic expressions that closely resemble expressions in
mathematics.
• The most common operators in JavaScript are the ones that
specify arithmetic computation:
+ Addition * Multiplication
– Subtraction / Division
% Remainder

• An operators usually appears between two subexpressions,


which are called its operands. Operators that take two
operands are called binary operators.
• The - operator can also appear as a unary operator, as in the
expression -x, which denotes the negative of x.
The Remainder Operator
• The only arithmetic operator that has no direct mathematical
counterpart is %, which applies only to integer operands and
computes the remainder when the first divided by the second:
14 % 5 returns 4
14 % 7 returns 0
7 % 14 returns 7

• The result of the % operator make intuitive sense only if both


operands are positive. The examples in the book do not
depend on knowing how % works with negative numbers.
• The remainder operator turns out to be useful in a surprising
number of programming applications and turns up in several
of the algorithms in Chapter 2.
Statement Types in JavaScript
• Statements in JavaScript fall into three basic types:
– Simple statements
– Compound statements
– Control statements
• Simple statements are formed by adding a semicolon to the
end of an expression, which is typically an assignment or a
function call.
• Compound statements (also called blocks) are sequences of
statements enclosed in curly braces.
• Control statements fall into two categories:
– Conditional statements that specify some kind of test
– Iterative statements that specify repetition
Boolean Expressions
• JavaScript defines two types of operators that work with
Boolean data: relational operators and logical operators.
• There are six relational operators that compare values of other
types and produce a true/false result:
= == Equals !== Not equals
< Less than <= Less than or equal to
> Greater than >= Greater than or equal to

For example, the expression n <= 10 has the value true if n is


less than or equal to 10 and the value false otherwise.
• There are also three logical operators:
&& Logical AND p && q means both p and q
|| Logical OR p || q means either p or q (or both)
! Logical NOT !p means the opposite of p
Notes on the Boolean Operators
• Remember that JavaScript uses = for assignment. To test
whether two values are equal, you must use the = = = operator.
• It is not legal in JavaScript to use more than one relational
operator in a single comparison. To express the idea embodied
in the mathematical expression
0 ≤ x ≤ 9
you need to make both comparisons explicit, as in
0 <= x && x <= 9
• The || operator means either or both, which is not always
clear in the English interpretation of or.
• Be careful when you combine the ! operator with && and ||
because the interpretation often differs from informal English.
Short-Circuit Evaluation
• JavaScript evaluates the && and || operators using a strategy
called short-circuit mode in which it evaluates the right
operand only if it needs to do so.
• For example, if n is 0, the right operand of && in
n !== 0 && x % n === 0

is not evaluated at all because n !== 0 is false. Because the


expression
false && anything
is always false, the rest of the expression no longer matters.
• One of the advantages of short-circuit evaluation is that you
can use && and || to prevent execution errors. If n were 0 in
the earlier example, evaluating x % n would cause a “division
by zero” error.
The if Statement
The simplest of the control statements is the if statement, which
occurs in two forms. You use the first form whenever you need to
perform an operation only if a particular condition is true:

if (condition) {
statements to be executed if the condition is true
}

You use the second form whenever you want to choose between
two alternative paths, one for cases in which a condition is true
and a second for cases in which that condition is false:
if (condition) {
statements to be executed if the condition is true
} else {
statements to be executed if the condition is false
}
The while Statement
The while statement is the simplest of JavaScript’s iterative
control statements and has the following form:

while ( condition ) {
statements to be repeated
}

When JavaScript encounters a while statement, it begins by


evaluating the condition in parentheses.
If the value of condition is true, JavaScript executes the
statements in the body of the loop.
At the end of each cycle, JavaScript reevaluates condition to see
whether its value has changed. If condition evaluates to false,
JavaScript exits from the loop and continues with the statement
following the closing brace at the end of the while body.
The for Statement
The for statement in JavaScript is a particularly powerful tool for
specifying the control structure of a loop independently from the
operations the loop body performs. The syntax looks like this:

for ( init ; test ; step ) {


statements to be repeated
}

JavaScript evaluates a for statement as follows:


1. Evaluate init, which typically declares a control variable.
2. Evaluate test and exit from the loop if the value is false.
3. Execute the statements in the body of the loop.
4. Evaluate step, which usually updates the control variable.
5. Return to step 2 to begin the next loop cycle.
Comparing for and while
The for statement
for ( init ; test ; step ) {
statements to be repeated
}

is functionally equivalent to the following code using while:

init;
while ( test ) {
statements to be repeated
step;
}

The advantage of the for statement is that everything you need to


know to understand how many times the loop will run is explicitly
included in the header line.
Exercise: Reading for Statements
Describe the effect of each of the following for statements:
1. for (let i = 1; i <= 10; i++)

This statement executes the loop body ten times, with the control
variable i taking on each successive value between 1 and 10.

2. for (let i = 0; i < N; i++)

This statement executes the loop body N times, with i counting from
0 to N - 1. This version is the standard Repeat-N-Times idiom.

3. for (let n = 99; n >= 1; n = n - 2)

This statement counts backward from 99 to 1 by twos.

4. for (let x = 1; x <= 1024; x = x * 2)

This statement executes the loop body with the variable x taking on
successive powers of two from 1 up to 1024.
Writing Functions
• The general form of a function definition is

function name(parameter list) {


statements in the function body
}

where name is the name of the function, and parameter list is


a list of variables used to hold the values of each argument.
• You can return a value from a function by including a return
statement, which is usually written as

return expression;

where expression is an expression that specifies the value you


want to return.
Functions Involving Control Statements
• The body of a function can contain statements of any type,
including control statements. As an example, the following
function uses an if statement to find the larger of two values:
function max(x, y) {
if (x > y) {
return x;
} else {
return y;
}
}

• As this example makes clear, return statements can be used


at any point in the function and may appear more than once.
The factorial Function
• The factorial of a number n (which is usually written as n! in
mathematics) is defined to be the product of the integers from
1 up to n. Thus, 5! is equal to 120, which is 1 x 2 x 3 x 4 x 5.
• The following function definition uses a for loop to compute
the factorial function:

function fact(n) {
let result = 1;
for (var i = 1; i <= n; i++) {
result = result * i;
}
return result;
}
Functions and Algorithms
• Functions are critical to programming because they provide a
structure in which to express algorithms.
• Algorithms for solving a particular problem can vary widely in
their efficiency. It makes sense to think carefully when you
are choosing an algorithm because making a bad choice can be
extremely costly.
• The next few slides illustrate this principle by implementing
two algorithms for computing the greatest common divisor of
the integers x and y, which is defined to be the largest integer
that divides evenly into both.
The Brute-Force Approach
• One strategy for computing the greatest common divisor is to
count backwards from the smaller value until you find one that
divides evenly into both. The code looks like this:
function gcd(x, y) {
let guess = x;
while (x % guess !== 0 || y % guess !== 0) {
guess--;
}
return guess;
}

• This algorithm must terminate for positive values of x and y


because the value of guess will eventually reach 1. At that
point, guess must be the greatest common divisor.
• Trying every possibility is called a brute-force strategy.
Euclid’s Algorithm
• If you use the brute-force approach to compute the greatest
common divisor of 1000005 and 1000000, the program will
take a million steps to tell you the answer is 5.
• You can get the answer much more quickly if you use a better
algorithm. The Greek mathematician Euclid of Alexandria
described a more efficient algorithm 23 centuries ago, which
looks like this:

function gcd(x, y) {
while (x % y !== 0) {
let r = x % y;
x = y;
y = r;
}
return y;
}
How Euclid’s Algorithm Works
• If you use Euclid’s algorithm on 1000005 and 1000000, you
get the correct answer in just two steps, which is much better
than the million steps required by brute force.
• Euclid’s great insight was that the greatest common divisor of
x and y must also be the greatest common divisor of y and the
remainder of x divided by y. He was, moreover, able to prove
this proposition in Book VII of his Elements.
• It is easy to see how Euclid’s algorithm works if you think
about the problem geometrically, as Euclid did. The next slide
works through the steps in the calculation when x is 78 and y
is 33.
An Illustration of Euclid’s Algorithm
Step 1: Compute the remainder of 78 divided by 33:
x 78
y 33 33 12

Step 2: Compute the remainder of 33 divided by 12:


x 33
y 12 12 9

Step 3: Compute the remainder of 12 divided by 9:


x 12
y 9 3

Step 4: Compute the remainder of 9 divided by 3:


x 9
y 3 3 3 Because there is no remainder, the answer is 3:
Aside: Callback Functions in Javascript
• As Javascript was designed for the web, it was built with the
ability to have asynchronous behavior, primarily so that the
web page interface would always be response. For example,
let's say you had a triply-nested loop that was printing to the
web page:
function stop() {
count.stop = true; // triggered by button press
}

function count() {
count.stop = false;
const iterations = 100;
const counter = document.getElementById("counter");
counter.innerHTML = "";

for (let i=0; i < iterations; i++) {


for (let j=0; j < iterations; j++) {
for (let k=0; k < iterations; k++) {
counter.innerHTML = i + "," + j + "," + k;
if (count.stop) {
return;
}
}
}
}
}
Aside: Callback Functions in Javascript
• The problem with this code is that the browser becomes
completely unresponsive, which is not good for the user!

function stop() {
count.stop = true; // triggered by button press
}

function count() {
count.stop = false;
const iterations = 100;
const counter = document.getElementById("counter");
counter.innerHTML = "";

for (let i=0; i < iterations; i++) {


for (let j=0; j < iterations; j++) {
for (let k=0; k < iterations; k++) {
counter.innerHTML = i + "," + j + "," + k;
if (count.stop) {
return;
}
}
}
}
}
Aside: Callback Functions in Javascript
• What we can do is to re-write the function so that things
happen asynchronously, meaning that your function shares
control with the graphical engine, and the website remains
responsive:
function count() {
count.stop = false;
const iterations = 100;
const counter = document.getElementById("counter");
counter.innerHTML = "";
let i = 0, j = 0, k = 0;
const loopFunc = setInterval(function() {
if (count.stop) {
clearInterval(loopFunc);
return;
}
counter.innerHTML = i + "," + j + "," + k;
k++;
if (k == iterations) {
j++;
k = 0;
}
if (j == iterations) {
i++;
j = 0;
}
if (i == iterations) {
clearInterval(loopFunc);
}
}, 0.1);
}
Aside: Callback Functions in Javascript
• This utilizes an interval timer to call the inner function
(defined "anonymously") every 0.1 seconds. The web browser
remains responsive, and the screen updates regularly:
function count() {
count.stop = false;
const iterations = 100;
const counter = document.getElementById("counter");
counter.innerHTML = "";
let i = 0, j = 0, k = 0;
const loopFunc = setInterval(function() {
if (count.stop) {
clearInterval(loopFunc);
return;
}
counter.innerHTML = i + "," + j + "," + k;
k++;
if (k == iterations) {
j++;
k = 0;
}
if (j == iterations) {
i++;
j = 0;
}
if (i == iterations) {
clearInterval(loopFunc);
}
}, 0.1);
}
Important Algorithms in Computing
• If you asked one hundred mathematicians and computer
scientists what the most important algorithms are in
computing, you would get one hundred different answers.
• However, there are some standout algorithms that you should
know about, and some which you should go and program
yourself. We will talk about a few now.
https://medium.com/@_marcos_otero/the-real-10-algorithms-
that-dominate-our-world-e95fa9f16c04
http://www.koutschan.de/misc/algorithms.php
https://www.businessinsider.com/the-5-most-important-
algorithms-in-tech-2013-10
https://en.wikipedia.org/wiki/List_of_algorithms
https://en.wikipedia.org/wiki/Timeline_of_algorithms
https://cs.uwaterloo.ca/~shallit/Courses/134/history.html
Sorting Algorithms
• Sorting is a critical task that computers can do, and it has been
well studied and investigated.
• Sorting speed is fundamentally limited to have a
computational complexity of O(n log n), which basically
means that in the worst case, a sorting algorithm must traverse
all of the numbers that you are sorting a logarithmic amount of
times. For example: if you have 16 integers you want to sort,
the algorithm will evaluate and compare each of those 16
integers log216, or four times, for a total of 16 * 4 = 64
comparisons. If you have one million integers, you will
compare 1M * log2(1M) ≈ 20 million comparisons.
• There are many cool online visualizations for sorting:
https://www.youtube.com/watch?v=kPRA0W1kECg
https://www.toptal.com/developers/sorting-algorithms
https://www.cs.usfca.edu/~galles/visualization/ComparisonSort.html
The Fast Fourier Transform
• The Fourier Transform is a function
that takes a function of time and
breaks it into the frequencies that
make it up.
• For example, a perfect sine wave has
a single frequency, and therefore the
Fourier Transform of the wave would
be a single value at the frequency of
the wave:
• The Discrete Fourier Transform is not trivial to calculate, but
in 1965 James Cooley and John Tukey published the Fast
Fourier Transform (FFT), which revolutionized digital signal
processing, and the FFT is used all over the place.
• For example: The Shazam application for determining what
song is playing is based on the FFT (and on hashing): http://
coding-geek.com/how-shazam-works/
RSA and Public/Private Key Cryptography
• When you complete an online purchase, or when you go to a
secure website, part of the process uses public-key
cryptography to do the job. We will discuss cryptography later
in the course, but the RSA algorithm is fundamental to
efficient secure communications, as used on the Internet.

• http://logos.cs.uic.edu/340%20Notes/rsa.html
• https://www.youtube.com/watch?v=b57zGAkNKIc
Data Compression Algorithms
• If you’ve ever seen an image on the Internet, or ever listened
to an .mp3, or ever watched Netflix, you’ve benefited from
data compression.
• Compression can be either lossless or lossy — a lossless
compression algorithm (such as the .zip file format, or the .png
format, or Huffman encoding, which you may have practiced
in CS 106B), allows exact decompression. A lossy
compression algorithm (e.g., .jpg, or .mp3, or Netflix movies)
removes some data, but in a way that is (hopefully)
imperceptible to the viewer, or listener (for example).
• An .mp3 is lossy, in that frequencies that you cannot hear from
the original are removed to save space. There has been great
debate over whether audiophiles can perceive the difference
between a raw audio file with all the data and .mp3 files.
Pseudo-random Number Generation

• It is impossible to programmatically generate random


numbers, yet we need to use random numbers in many
applications, such as cryptography, hashing, video games, AI,
finance modeling, etc.
• There are ways to collect random data to produce truly random
numbers, but it is slow and not easy to do. Often, we can get
away with producing pseudo-random numbers algorithmically
in such a way that it is extremely difficult to tell that the data
is not truly random.
The End

You might also like