Visuals

Calvin (Deutschbein)

5 April 2023

Announcements

  • Registration window opens on 4/10.
    • .js day
    • New "reading" and response for next Monday.
  • Today we'll show some control flow and hacking tricks.
  • Homework for Monday.
    • Read (watch) “We Need To Fix Black Hair in Video Games”.
    • Write an HTML/CSS response paper. 500 words / ~3k chars / ~10-20 theses.
    • Include an event listener on your page, potentially with a canvas element. It can be unrelated.
  • Discussion section Monday

Registration opens 4/10 (Monday)

Plan to meet with your advisor to unlock course registration.

  • If you do not have an in-program advisor, add me ASAP.
    • Email registrar@willamette.edu.
    • Copy me.
    • Say which major(s) you want to declare.
    • I will approve then check your student progress on SAGE.
  • As a rule, plan on meeting your advisor in person.
    • My advisees may do the advising meeting via email at student discretion.
    • I can do in-person before or after this class, and by Zoom TThF, but not this ThF.

Requirements:

These are required for one and recommended for both. Take in this order:

  • CS requirements
    • CS-151 @ MWF 8:00/9:10/10:50
    • CS-152 @ TTh 9:40
    • MATH-251 @ MWF 1:10
    • CS-351 @ TTh 8:00 (May not be at 8 AM in '24-'25)
  • DATA requirements other than CS-151
    • MATH-138 @ MWF 9:10/10:50 (for DATA-152 credit)
    • DATA-151 @ MWF 2:50 / TTh 9:40/1:10
    • MATH-280 @ MWF 12:00
    • DATA-351 @ MWF 10:50 (BAD for MS DS, GOOD for BS CS)

Risks:

You are in danger if:

  • CS:
    • You want to graduate Sp24 and haven't taken CS152 and MATH251 - Talk to Prof. Cheng ASAP.
  • DATA:
    • You MS DS but average fewer than 17 credit-hours per semester
    • You want to MS DS in Fa24 and aren't ready for MATH 280 - Talk to Prof. Otto ASAP.
    • You want to graduate Sp24 and aren't ready for MATH 280 - Talk to Prof. Otto ASAP.

We have some options we can exercise in these cases. You can talk to me as well.

  • As a rule, you are never more than 4 semesters from major completion.

Fun courses:

We have some fun offerings next term:

  • In program:
    • CS-299 Top: Human Computer Interaction @ MW 2:50
    • CS-475 Machine Learning With Python @ TTh1:10
      • Needs CS 370, counts toward DATA-252 requirement for BS DS.
    • MATH-376 Top: Graph Theory @ MWF1:10
  • Of general interest, situationally for elective credit:
    • ENVS-250 Geographic Information Systems, TTh1:10, NatSci/SocSci HAS LAB
    • CCM-261 Media, Technology, and Society, TTh9:40, ArtHum
    • PHIL-140 Symbolic Logic, MWF1:10
    • PHEAL-214 Public Health Epidemiology, MWF9:10, SocSci

Graduation Requirement Engineering:

Besides a major, you have general education and credit hour requirements to graduate:

  • Credit Hour Engineering:
    • IDS-240 Science Communication and Outreach, Th8:00/7:00, WE:SL (2 Credits)
    • LW-275 PRIVACY LAW (2 Credits)
  • General Education Engineering:
    • BIOL-342 Biostatistics*, TTh9:40, NatSci Distro PREREQ
    • GCS-105 MW2:50/TTh2:50 ArtHum/SocSci/PDE/WE:CV
    • WGS-245 TTh 9:40, ArtHum/SocSci
    • ECON-132, MWF10:50/12:00/2:50, SocSci distro

Building a Good Schedule

Here is my algorithm.

  1. Schedule all major-required courses
    • Tie-break by scheduling pressure
    • CS-351, MATH-280, DATA-351 are offered ANNUALLY and have prereqs.
    • CS-152 is a requirement for CS-261 and CS-271 in Sp24.
  2. Schedule elective requirements and graduation requirements by preference.
    • Prioritize classes offered irregularly, e.g. Top: HCI, Top: Graphs, Biostats
  3. Reach a minimum of 17 (!!!) credits to avoid "bad" outcomes
    • IDS-240 and LW-275 are 2 credit courses to pad up to 18
    • Use X-suffixed classes, like MATH 102X, to exceed 18 for extra safety.

In general, I approve via email any 4-course schedule with 1+ major requirement and 3+ graduation requirement courses.

Script elements

<!DOCTYPE html>
<html>
  <body>
    <p id="showEle">1</p>  
    <script>
      let val = 1 ;
      const showVar = document.getElementById("showEle") ;
      document.addEventListener('click', update);
      function update() 
      {
        val = 2 * val ;
        showVar.innerText = val.toString() ;
      }
    </script>
  </body>
</html>

Review Question 1

Consider the following JavaScript excerpt from within the HTML document.

document.addEventListener('click', update);

What is document?

  1. A user-defined .js variable (e.g. a let)
  2. A user-defined HTML element (e.g. a

    )
  3. A built-in .js keyword (like alert() or function)
  4. A built-in HTML keyword (like

    or <body></body>)

Review Question 2

Consider the following JavaScript excerpt from within the HTML document.

document.addEventListener('click', update);

The method addEventListener is a method. What is a method?

  1. A synonym for function or procedure.
  2. A synonym for function and procedure.
  3. A special term in object-oriented programming.
  4. A special term for built-in functions and/or procedures and/or subroutines.

Review Question 3

Consider the following JavaScript excerpt from within the HTML document.

      function update() 
      {
        val = 2 * val ;
        showVar.innerText = val.toString() ;
      }

The function update is a .js function by construction. It is also which of the following:

  1. A method.
  2. A variable.
  3. A constant.
  4. A function in the sense of programming language theory rather than in the sense of .js keywords.

Consider:

<!DOCTYPE html>
<html>
  <body>
    <p id="showEle">1</p>  
    <script>
      let val = 1 ;
      const showVar = document.getElementById("showEle") ;
      function update() 
      {
        val = 2 * val ;
        showVar.innerText = val.toString() ;
      }
      const myFunc = update ;
      document.addEventListener('click', myFunc);
    </script>
  </body>
</html>

Review Question 4

Consider the following JavaScript excerpt from within the HTML document.

const myFunc = update ;

What is happening in this line?

  1. A new function, myFunc, is created that is the same as the function update.
  2. A new constant, myFunc, is created that is the same as the constant update.
  3. myFunc is a constant, and update is a function, so this is an error.
  4. Update is a variable with a value that is a function, and myFunc is different variable with the same value.

Review Question 5

Consider the following JavaScript function from within the HTML document.

function downdate() 
{
  val = 0.5 * val ;
  showVar.innerText = val.toString() ;
}
update = downdate ;

Consider the line update = downdate ;

  1. This reassigns the function variable update to hold the same value as downdate.
  2. This is an error, because variables declared as functions are constants.
  3. This is an error, because downdate is a function.
  4. This is an error, because update is undeclared.

HTML and CSS

HTML elements and CSS rules are similarly vertically structured.

HTML is a

  • Element
    • Start Tag
      • Attributes
        • Attribute name
        • Attribute value
    • Content
    • End Tag
  • Element
    • Void Tag
      • Attributes
        • ...

CSS is a

  • Rule
    • Selector(s)
    • Declaration Block
      • Declaration
        • Property
        • Value
  • Attribute Value
    • Declaration Block
      • ...

RECALL: Canvas

Today we will start with a centered rectangle.

  • Reflect: How does centering differ in HTML document vs. within a canvas?
function draw()
{
	const dspl = document.getElementById("display") ;
	ctx = dspl.getContext("2d") ;	
	w = dspl.width ;
	h = dspl.height ;
	s = w / 8 ;
	x = w / 2 - s / 2 ;
	y = h / 2 - s / 2 ;
	ctx.fillRect(x, y, s, s) ; // x y width height
}

This is a bit goofy because I declared variables globally for Reasons™

RECALL: Canvas

End-to-end, this is what we made:

Note at this time I've switched to externally rendered .png files, from internal live canvas elements.

Events

We use built-in functions to attach an event listener to the entire HTML document.

document.addEventListener('keydown', keybind);
  • document refers to the special HTML element of type document.
  • addEventListener is a built-in .js function that takes two arguments.
  • 'keydown' is the name of the HTML event for which the listener listens.
  • keybind is the name of the .js function I will write to capture keystrokes.

Keybind is a variable, keydown is a keyword.

Scope

I set things up like this.

var x ;
var y ;
var s ;
var ctx ;
var w ;
var h ;

document.addEventListener('keydown', keybind);

function keybind()
{
	...

Events

When an event occurs, it generates an event object in .js.

function keybind()
{
	const key = event.key;

For keydown events, this will always be a key of some sort.

function keybind()
{
	alert(event.key)
}

Events

I decided to use the arrow keys. You can include wasd as well.

function keybind()
{
	const key = event.key; // "ArrowRight", "ArrowLeft", "ArrowUp", or "ArrowDown"

I introduce (?) the switch statement.

	switch (event.key) 
	{
		case "ArrowLeft":
		case "a":
			x = x - s ;
			break ;
		...
	}

This updates the global x value to be less when the left arrow key is pressed.

Switch

Switches are commonly used in IO programming, which is okay I guess.

  • Switches are control flow statements, like if/for/while.
  • Switches "fall through" - after a case is met, all code is executed until a break or return.
  • Breaks and returns are also control flow statements!

    switch (event.key) {
    	case "ArrowLeft":
    	case "a":
    		x = x - s  ; // this runs for a or left
    		break ;      // this exits the switch
    	case "ArrowRight":
    	case "d":
    		x = x + s  ; // this runs for d or right - but not a or left
    		break ;
    

Switch

Be careful!

switch (event.key) {
	case "ArrowLeft":
	case "a":
		x = x - s  ; // this runs for a or left
	case "ArrowRight":
	case "d":
		x = x + s  ; // this runs for d or right or a or left
		break ;

Switch

Be careful!

switch (event.key) {
	case "ArrowLeft":
	case "a":
		x = x - s  ; // this runs for a or left
		return ;
	case "ArrowRight":
	case "d":
		x = x + s  ; // this runs for d or right or a or left
		return ;
}
alert(event.key) ; // this doesn't fire for arrows

Switch

Be efficient! This would be bad.

switch (event.key) {
	case "ArrowLeft":
		x = x - s  ; // this runs for a or left
		return ;
	case "a":
		x = x - s  ; // this runs for a or left
		return ;
	}

Canvas

Well... we can compute new x (or y) values with switch... but what good is that.

function keybind()
{
	// old x value here
	switch (event.key) {
		// well written switch
	}
	// new x value here
}

This doesn't exactly doing IO - it does the I, but there's no changes to the canvas!

Canvas

We need to draw rectangles - just like in the onload function!

function keybind()
{
	switch (event.key) {
		// well written switch
	}
	ctx.fillRect(x, y, s, s) ; // x y width height
}

This adds a new rectangle to the canvas!

Canvas

We use another built in function to clear the old rectangle.

function keybind()
{
	ctx.clearRect(0, 0, w, h);
	switch (event.key) {
		// well written switch
	}
	ctx.fillRect(x, y, s, s) ; // x y width height
}

In effect, this moves the rectangle.

  • Question: What happenes when a key not enumerated in the switch statement is pressed?

Trenary Operator

But wait - we have a problem with bounds checking.

switch (event.key) {
	case "ArrowLeft":
		x = x - s  ; // this runs for a or left
		return ;
	case "a":
		x = x - s  ; // this runs for a or left
		return ;
	}

What happens when the box is moved off of the canvas space?

Trenary Operator

We could write extensive if statements.

switch (event.key) {
	case "ArrowLeft":
		if (x - s > 0)
		{
			x = x - s  ;
		}
		break ;
	case "ArrowRight":
		if (x + s < w)
		{
			x = x + s  ;
		}
		break ;
	}

Trenary Operator

Imagine how bad that looks without switch.

if (event.key == "ArrowLeft")
{
	if (x - s > 0)
	{
		x = x - s  ;
	}
} else if (event.key == "ArrowRight") {
	if (x + s < w)
	{
		x = x + s  ;
	}
}

Trenary Operator

Though of course there's some case combinations we can do

if ((event.key == "ArrowLeft") && (x - s > 0))
	x = x - s  ;
} else if ((event.key == "ArrowRight") && (x + s < w))
	x = x + s  ;
}

This could be an argument against switch, that said.

Trenary Operator

We can inline conditions with the "trenary operator".

switch (event.key) {
	case "ArrowLeft":
	case "a":
		x = x - s > 0 - s ? x - s : x ;
		break ;

Basically, it is

const bool = x - s > 0 ;
const someVal = x - s ;
const otherVal = x ;
x = bool ? someVal : otherVal ;

This is the same as an if statement in this simple assignment case.

Practice

Write a .js plotter, based on ye olde utilator.

  • Create an HTML file, plot.html
  • Create a .js file, plot.js
  • Create a canvas element in the HTML file.
  • Create a listener or listeners to do the following:
    • 'wasd' to scroll
    • 'p' and 'm' (plus and minus) to zoom
    • 'r', 'h', or 'd' to reset to defaults

Review:https://github.com/cd-public/eths23/blob/main/html/utilator.html

Demo:https://cd-public.github.io/eths23/html/visual.html

The demo shows a solution if you get stuck.

Homework

Homework for Monday

  • Read (watch) “We Need To Fix Black Hair in Video Games”.
  • Write an HTML/CSS response paper. 500 words / ~3k chars / ~10-20 theses.
    • You don't have to write just 15 theses, but I would.
    • Bold a main thesis that summarizes your thoughts.
    • Aim for between 30% and 70% to be discussion-provoking questions.
    • These can be like my abstract responses, for example.
  • Webhost at *.github.io/kindafunny.html no latter than Friday at Midnight AOE
  • Read at least 3 of your peers' documents before class.
  • Have an event listener do something to your page, and document it (write a sentence somewhere saying what it does).

There may be a way to integrate plots into your rhetoric!

// reveal.js plugins