Compare commits

17 Commits
main ... main

Author SHA1 Message Date
Andrea Bianchi
e51e774ef8 exceptions 2026-05-05 19:50:18 +09:00
Andrea Bianchi
bd2b95ea1e w11 design patterns 2026-04-30 21:32:03 +09:00
Andrea Bianchi
fec15709e7 inheritance 2026-04-29 09:54:15 +09:00
Andrea Bianchi
e8fb1810e3 lights exercise 2026-04-22 13:54:03 +09:00
Andrea Bianchi
13e99a84d5 clock exercise 6.2 2026-04-07 22:53:08 +09:00
Andrea Bianchi
7ee7a5ea29 fix 6.1. 2026-04-06 09:28:27 +09:00
Andrea Bianchi
414ba22ba1 6.1 2026-04-06 09:27:33 +09:00
Andrea Bianchi
9054d5c511 6.1 2026-04-06 09:26:07 +09:00
Andrea Bianchi
bd53e91476 Exercise 6.1 2026-04-05 18:49:32 +09:00
Andrea Bianchi
d8cdc977e6 5.2 2026-04-01 06:57:45 +09:00
Andrea Bianchi
bd1954bc3b 5.2_exercise 2026-03-31 14:59:47 +09:00
Andrea Bianchi
baa0d8559f w_5_1 HOF 2026-03-25 22:18:37 +09:00
Andrea Bianchi
a869f49907 4.2 added 2026-03-23 23:44:26 +09:00
Andrea Bianchi
a5b0cc7b8f week 4 recursion 2026-03-20 16:39:59 +09:00
Andrea Bianchi
07d83842d7 Upldated gitignore 2026-03-17 10:01:49 +09:00
Andrea Bianchi
158a3d0784 Week 3.2. exercise 2026-03-17 10:00:59 +09:00
Andrea Bianchi
9a4b251976 w3 exercises 2026-03-14 12:08:37 +09:00
72 changed files with 4156 additions and 1 deletions

3
.gitignore vendored
View File

@@ -3,4 +3,5 @@ node_modules
**/.DS_Store **/.DS_Store
todo/** todo/**
_*.js _*.js
solution-*.js solution-*
old

View File

@@ -0,0 +1,4 @@
{
"name": "Andrea",
"job": "Professor"
}

View File

@@ -0,0 +1,11 @@
// read the file and print the content
const fs = require('fs');
const path = require('path');
const data = fs.readFileSync(path.join(__dirname, 'data.json'), 'utf8');
console.log(data);
// Fix this
// Read a file that does not exist. This will throw an error.
const wrong = fs.readFileSync(path.join(__dirname, 'wrong.json'), 'utf8');
console.log(wrong);

View File

@@ -0,0 +1,9 @@
{
"name": "exceptions1",
"version": "1.0.0",
"main": "index.js",
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}

View File

@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@@ -0,0 +1,47 @@
# Svelte + Vite
This template should help get you started developing with Svelte in Vite.
## Recommended IDE Setup
[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode).
## Need an official Svelte framework?
Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more.
## Technical considerations
**Why use this over SvelteKit?**
- It brings its own routing solution which might not be preferable for some users.
- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app.
This template contains as little as possible to get started with Vite + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project.
Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate.
**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?**
Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information.
**Why include `.vscode/extensions.json`?**
Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project.
**Why enable `checkJs` in the JS template?**
It is likely that most cases of changing variable types in runtime are likely to be accidental, rather than deliberate. This provides advanced typechecking out of the box. Should you like to take advantage of the dynamically-typed nature of JavaScript, it is trivial to change the configuration.
**Why is HMR not preserving my local component state?**
HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/sveltejs/svelte-hmr/tree/master/packages/svelte-hmr#preservation-of-local-state).
If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR.
```js
// store.js
// An extremely simple external store
import { writable } from 'svelte/store'
export default writable(0)
```

View File

@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>

View File

@@ -0,0 +1,32 @@
{
"compilerOptions": {
"moduleResolution": "bundler",
"target": "ESNext",
"module": "ESNext",
/**
* svelte-preprocess cannot figure out whether you have
* a value or a type, so tell TypeScript to enforce using
* `import type` instead of `import` for Types.
*/
"verbatimModuleSyntax": true,
"isolatedModules": true,
"resolveJsonModule": true,
/**
* To have warnings / errors of the Svelte compiler at the
* correct position, enable source maps by default.
*/
"sourceMap": true,
"esModuleInterop": true,
"skipLibCheck": true,
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable this if you'd like to use dynamic types.
*/
"checkJs": true
},
/**
* Use global.d.ts instead of compilerOptions.types
* to avoid limiting type declarations.
*/
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
{
"name": "exceptions-exercise",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"svelte": "^5.23.1",
"vite": "^6.3.1"
}
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,41 @@
<script>
// @ts-nocheck
let people = 1;
function getPecentage(divisor) {
return (100 / divisor).toFixed(0);
}
let cakeDivided = getPecentage(people);
function update() {
cakeDivided = getPecentage(people);
}
</script>
<main>
<h3>In how many parts shall we divide the cake?</h3>
<input type="number" bind:value={people} placeholder="Enter a number" />
<button on:click={update}>Update</button>
<p>
Each person eats <span class="highlight">{cakeDivided}%</span> of the cake
</p>
</main>
<style>
input {
padding: 0.5rem;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1rem;
width: 60%;
max-width: 200px;
margin-top: 1rem;
}
.highlight {
color: #ff6347;
}
</style>

View File

@@ -0,0 +1,79 @@
:root {
font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
line-height: 1.5;
font-weight: 400;
color-scheme: light dark;
color: rgba(255, 255, 255, 0.87);
background-color: #242424;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
a {
font-weight: 500;
color: #646cff;
text-decoration: inherit;
}
a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
.card {
padding: 2em;
}
#app {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
button {
border-radius: 8px;
border: 1px solid transparent;
padding: 0.6em 1.2em;
font-size: 1em;
font-weight: 500;
font-family: inherit;
background-color: #1a1a1a;
cursor: pointer;
transition: border-color 0.25s;
}
button:hover {
border-color: #646cff;
}
button:focus,
button:focus-visible {
outline: 4px auto -webkit-focus-ring-color;
}
@media (prefers-color-scheme: light) {
:root {
color: #213547;
background-color: #ffffff;
}
a:hover {
color: #747bff;
}
button {
background-color: #f9f9f9;
}
}

View File

@@ -0,0 +1,9 @@
import { mount } from 'svelte'
import './app.css'
import App from './App.svelte'
const app = mount(App, {
target: document.getElementById('app'),
})
export default app

View File

@@ -0,0 +1,2 @@
/// <reference types="svelte" />
/// <reference types="vite/client" />

View File

@@ -0,0 +1,7 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
export default {
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
// for more information about preprocessors
preprocess: vitePreprocess(),
}

View File

@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
// https://vite.dev/config/
export default defineConfig({
plugins: [svelte()],
})

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<script src="index.js"></script>
<meta charset="utf-8" />
</head>
<body></body>
</html>

View File

@@ -0,0 +1,26 @@
class Computer {
constructor(brand, os, ram, cpu, ssdSize) {
this.brand = brand;
this.os = os;
this.ram = ram;
this.cpu = cpu;
this.ssd = ssdSize;
}
showSpects() {
console.log(
`Brand is ${this.brand} with ${this.os} OS.
CPU: ${this.cpu} / RAM: ${this.ram} / SSD size: ${this.ssd}
`
);
}
}
// 1. Create a Builder for this
class ComputerBuilder {}
// 2. Create a factory
// 3. Change it using a singleton
class ComputerFactory {}
console.log('ready');

View File

@@ -0,0 +1,5 @@
class Subject {}
class Observer {}
export { Subject, Observer };

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<script type="module" src="index.js"></script>
<meta charset="utf-8" />
</head>
<body></body>
</html>

View File

@@ -0,0 +1,44 @@
import { Observer, Subject } from './Subject.js';
class Fish {
constructor(weight) {
super();
this.weight = weight;
}
getWeight() {
return this.weight;
}
getSpecies() {
return this.species;
}
}
class Salmon extends Fish {
constructor() {
super(2);
this.species = 'Atalntinc salmon';
}
}
class Tuna extends Fish {
constructor() {
super(200);
this.species = 'Bluefin tuna';
}
}
class Fisherman {
constructor(name) {
super();
this.name = name;
}
}
// Main
const bob = new Fisherman('Bob');
const fish1 = new Tuna();
const fish2 = new Salmon();
// 1. subsribe bob (observer) to fish1 and fish2 (subjects)
// 2. fishes (subjects) notify when they are caught

View File

@@ -0,0 +1,38 @@
class Subject {
- observers: Observer []
+ constructor();
+ subscribe(observer: Observer);
+ unsubscribeAll();
+ unsubscribe(observer);
+ notifiSubstribers();
}
class Observer {
+ {abstract} update(src: Subject);
}
class Fish extends Subject {
- species: String;
- weight: Number;
+ constructor(weight: Number);
+ getWeight(): Number;
+ getSpecies(): String;
}
class Salmon extends Fish {
+ constructor();
}
class Tuna extends Fish {
+ constructor();
}
class Fisherman extends Observer {
- name: String;
+ constructor(name: String);
+ update(src);
}
Fisherman "1" -left- "many" Fish : has

6
w3_1_arrays/arrays.js Normal file
View File

@@ -0,0 +1,6 @@
const paragraph = `Call me Ishmael. Some years ago- never mind how long precisely- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world. It is a way I have of driving off the spleen and regulating the circulation. Whenever I find myself growing grim about the mouth; whenever it is a damp, drizzly November in my soul; whenever I find myself involuntarily pausing before coffin warehouses, and bringing up the rear of every funeral I meet; and especially whenever my hypos get such an upper hand of me, that it requires a strong moral principle to prevent me from deliberately stepping into the street, and methodically knocking people's hats off- then, I account it high time to get to sea as soon as I can. This is my substitute for pistol and ball. With a philosophical flourish Cato throws himself upon his sword; I quietly take to the ship. There is nothing surprising in this. If they but knew it, almost all men in their degree, some time or other, cherish very nearly the same feelings towards the ocean with me.`;
// Print a frequency counter of all the letters of the alphabet appearing in the paragraph
// Ignore case
console.log('Frequency Counter: ...');

16
w3_1_arrays/index.html Normal file
View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Types</title>
</head>
<body>
<script src="arrays.js" defer></script>
<script src="objects.js" defer></script>
</body>
</html>

48
w3_1_arrays/objects.js Normal file
View File

@@ -0,0 +1,48 @@
/**
* typedef {{name:string, age:number, job:string}} Person
*
*/
const persons = [
{ name: 'John', age: 30, job: 'Developer' },
{ name: 'Mary', age: 25, job: 'Designer' },
{ name: 'Peter', age: 27, job: 'Developer' },
{ name: 'Jane', age: 22, job: 'Designer' },
{ name: 'Bob', age: 33, job: 'Developer' },
{ name: 'Alice', age: 35, job: 'Manager' },
{ name: 'Tim', age: 32, job: 'Designer' },
{ name: 'Sara', age: 21, job: 'Designer' },
{ name: 'Tom', age: 34, job: 'Developer' },
{ name: 'Alex', age: 24, job: 'Manager' },
{ name: 'John', age: 30, job: 'Manager' },
{ name: 'Mary', age: 25, job: 'Designer' },
{ name: 'Peter', age: 27, job: 'Developer' },
{ name: 'Jane', age: 22, job: 'Designer' },
{ name: 'Bob', age: 33, job: 'Developer' },
{ name: 'Alice', age: 35, job: 'Manager' },
{ name: 'Tim', age: 32, job: 'Designer' },
{ name: 'Sara', age: 21, job: 'Designer' },
{ name: 'Tom', age: 34, job: 'Developer' },
{ name: 'Alex', age: 24, job: 'Developer' },
];
/**
* averageAge.
*
* @param {Person[]} persons
*/
function averageAge(persons) {
// placehlder
}
console.log('Average age:', averageAge(persons));
/**
* listJobs.
*
* @param {Person[]} persons
*/
function listJobs(persons) {
// placehlder
}
console.log('List of jobs:', listJobs(persons));

24
w3_2_functions/index.html Normal file
View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/2.0.5/p5.min.js'
integrity='sha512-jOTg6ikYiHx1LvbSOucnvZi4shXbaovZ91+rfViIiUFLgAJK+k1oQtGEaLvDB8rsZwEfUksTgmhrxdvEDykuzQ=='
crossorigin='anonymous'></script>
<meta charset="utf-8" />
<style>
/* Center the canvas */
canvas {
display: block;
margin: 0 auto;
}
</style>
</head>
<script defer src="./sorting.js"></script>
<!-- <script defer src="./solution-sorting.js"></script> -->
<body></body>
</html>

55
w3_2_functions/sorting.js Normal file
View File

@@ -0,0 +1,55 @@
// Main
const N = 10;
let strips = [];
function setup() {
createCanvas(400, 300);
strips = createStrips(N);
// TODO sort the strips by luminance
}
function draw() {
background(0);
noStroke();
const h = height / strips.length;
// TODO draw the strips
}
// HELPERS
/**
*
* @typedef {{red:number, green:number, blue:number}} Color
*/
/**
* createRndColorStrip
* @returns Color
*/
function createRndColorStrip() {
return {
red: Math.floor(Math.random() * 255),
green: Math.floor(Math.random() * 255),
blue: Math.floor(Math.random() * 255),
};
}
/**
* getLuminance -- get luminance given an array of Color
* @param {Color} strip
* @returns number
*/
function getLuminance(strip) {
// TODO
}
/**
* createStrips -- create an array of random colors
* @param {number} n
* @returns Color[]
*/
function createStrips(n) {
// TODO
}

View File

@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.2/p5.min.js"></script>
<meta charset="utf-8" />
</head>
<script defer src="sketch.js"></script>
<body></body>
</html>

View File

@@ -0,0 +1,72 @@
const DISK_WIDTH = 30;
const DISK_HEIGHT = 20;
const DELAY_MS = 500;
const NUMBER_OF_DISKS = 3;
let pole1, pole2, pole3;
let A = generateDisks(NUMBER_OF_DISKS); // bottom up, from large to small, like [4,3,2,1]
let B = [];
let C = [];
// Solving the Tower of Hanoi
async function solveTower(n, from, to, helper) {
// todo
}
async function move(from, to) {
to.push(from.pop());
await sleep(DELAY_MS);
}
// Main program
function setup() {
createCanvas(windowWidth, 600); // full width
pole1 = (1 * width) / 5;
pole2 = width / 2;
pole3 = (4 * width) / 5;
}
function draw() {
background(200);
// draw three poles
stroke(0);
strokeWeight(5);
line(pole1, height, pole1, height / 3);
line(pole2, height, pole2, height / 3);
line(pole3, height, pole3, height / 3);
fill(255, 0, 0);
drawDisks(pole1, A);
drawDisks(pole2, B);
drawDisks(pole3, C);
}
function drawDisks(poleLocation, disks) {
let y = height - DISK_HEIGHT / 2;
rectMode(CENTER);
stroke(0);
strokeWeight(2);
for (let disk of disks) {
rect(poleLocation, y, DISK_WIDTH * disk, DISK_HEIGHT);
y -= DISK_HEIGHT;
}
}
function mousePressed() {
solveTower(A.length, A, B, C);
}
// Helpers
function generateDisks(n) {
return Array(n)
.fill()
.map((_, i) => n - i);
}
function sleep(milliseconds) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.2/p5.min.js"></script>
<meta charset="utf-8" />
</head>
<script defer src="sketch.js"></script>
<body></body>
</html>

View File

@@ -0,0 +1,109 @@
let t;
const len = 1000;
function setup() {
// createCanvas(400, 300);
createCanvas(window.innerWidth, window.innerHeight);
noLoop(); // will draw only once
t = new Turtle(); // getting ready to draw
// green
stroke(0, 200, 0);
strokeWeight(5);
}
function draw() {
background(240);
// getting ready
t.setxy(-len / 2, 0);
t.right(90);
// draw Koch line
koch(5, len);
}
function koch(order, length) {
// PLACEHOLDER
t.forward(200);
}
// Don't write underneath this line
class Turtle {
constructor() {
this.oldx = int(width / 2);
this.oldy = int(height / 2);
this.x = this.oldx;
this.y = this.oldy;
this.tcolor = 0;
this.angle = 0;
stroke(this.tcolor);
}
forward(step) {
this.x = this.oldx - step * cos(radians(this.angle + 90));
this.y = this.oldy - step * sin(radians(this.angle + 90));
line(this.oldx, this.oldy, this.x, this.y);
this.oldx = this.x;
this.oldy = this.y;
}
back(step) {
this.x = this.oldx + step * cos(radians(this.angle + 90));
this.y = this.oldy + step * sin(radians(this.angle + 90));
line(this.oldx, this.oldy, this.x, this.y);
this.oldx = this.x;
this.oldy = this.y;
}
home() {
this.oldx = int(width / 2);
this.oldy = int(height / 2);
line(this.oldx, this.oldy, this.x, this.y);
this.oldx = this.x;
this.oldy = this.y;
this.angle = 0.0;
}
setx(step) {
this.x = this.oldx + step;
this.oldx = this.x;
}
sety(step) {
this.y = this.oldy + step;
this.oldy = this.y;
}
setxy(stepx, stepy) {
this.x = this.oldx + stepx;
this.y = this.oldy + stepy;
this.oldx = this.x;
this.oldy = this.y;
}
left(dangle) {
this.angle -= dangle;
}
right(dangle) {
this.angle += dangle;
}
setheading(nangle) {
this.angle = nangle;
}
pencolor(ncolor) {
this.tcolor = ncolor;
stroke(this.tcolor);
}
penup() {
noStroke();
}
pendown() {
stroke(this.tcolor);
}
}

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/js-confetti@latest/dist/js-confetti.browser.js"></script>
<script defer src="index.js"></script>
<h1 id="countdown">x</h1>
</body>
</html>

View File

@@ -0,0 +1,25 @@
function countDown(n) {
if (n == 0) {
celebrate();
setText('Happy New Year!');
} else {
setText(n);
setTimeout(() => {
countDown(n - 1);
}, 1000);
}
}
const n = 10;
setText(n);
countDown(n);
// Helpers
function setText(n) {
document.getElementById('countdown').textContent = n;
}
function celebrate() {
const jsConfetti = new JSConfetti();
jsConfetti.addConfetti();
}

View File

@@ -0,0 +1,15 @@
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
font-family: Arial, sans-serif;
margin: auto;
}
#countdown {
font-size: 10rem;
color: #333;
text-align: center;
}

1402
w5_1_HOF/data.js Normal file

File diff suppressed because it is too large Load Diff

5
w5_1_HOF/example.js Normal file
View File

@@ -0,0 +1,5 @@
const city = 'Seoul';
const item = {};
item.city = city;
item[city] = item[city] || 0;
console.log(item);

49
w5_1_HOF/index.html Normal file
View File

@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="./style.css" />
<meta charset="utf-8" />
</head>
<body>
<ol class="smallText">
<li>
<p>Get the list of people with age > 21. How many are there?</p>
<p class="result" id="q1">TODO</p>
</p>
</li>
<li>
<p>Get the total and average income for the entire population.
</p>
<p class="result" id="q2">TODO</p>
</p>
</li>
<li>
<p>Get total and average income of people older than 21 (included).</p>
<p class="result" id="q3">TODO</p>
</p>
</li>
<li>
<p>Find in which city “Mitsue Tollner” lives.</p>
<p class="result" id="q4">TODO</p>
</p>
</li>
<li>
<p>Find if there is anyone who lives in the same city of others.</p>
<p class="result" id="q5">TODO</p>
</p>
</li>
<li>
<p>Get the city/cities where most people live.</p>
<p class="result" id="q6">TODO</p>
</p>
</li>
</ol>
<script defer type="module" src="index.js"></script>
<!-- <script defer type="module" src="solution-index.js"></script> -->
</body>
</html>

39
w5_1_HOF/index.js Normal file
View File

@@ -0,0 +1,39 @@
import data from './data.js';
import dataJSON from './data.js'; // this file is a module so we can import
console.log(dataJSON);
// 1. Get the list of people with age > 21. How many are there?
const over21 = undefined;
// setAnswer(1, over21);
// 2. Add a universal basic income of 100 but 500 to Andrea
const updatedData = undefined;
// 3. Get the total and average income for the entire population.
const totIncome = undefined;
const avgIncome = undefined;
// setAnswer(2, `Tot income: ${totIncome}, Average income: ${avgIncome}`);
// 4. Get total and average income of people older than 21 (included).
const totIncome21 = undefined;
const avgIncome21 = undefined;
// setAnswer(3, `Tot income: ${totIncome21}, Average income: ${avgIncome21}`);
// 5. Find in which city “Mitsue Tollner” lives.
const city = undefined;
// setAnswer(4, city);
// 6. Find if there is anyone who lives in the same city of others.
const sameCities = undefined;
// setAnswer(5, sameCities);
// 7. Get the city/cities where most people live.
const mostPopularCity = undefined;
// setAnswer(6, mostPopularCity);
function setAnswer(n, content) {
if (n < 0 || n > 7) return;
const el = document.getElementById(`q${n}`);
el.innerHTML = content;
el.style.color = 'green';
}

11
w5_1_HOF/style.css Normal file
View File

@@ -0,0 +1,11 @@
body {
width: 600px;
}
ol {
text-align: left;
}
.result {
color: red;
}

22
w5_2_FP/data.js Normal file
View File

@@ -0,0 +1,22 @@
export const data = [
{ name: 'tom', last: 'hanks' },
{ name: 'meryl', last: 'streep' },
{ name: 'leonardo', last: 'dicaprio' },
{ name: 'scarlett', last: 'johansson' },
{ name: 'brad', last: 'pitt' },
{ name: 'angelina', last: 'jolie' },
{ name: 'denzel', last: 'washington' },
{ name: 'jennifer', last: 'lawrence' },
{ name: 'robert', last: 'downey jr.' },
{ name: 'natalie', last: 'portman' },
{ name: 'morgan', last: 'freeman' },
{ name: 'emma', last: 'stone' },
{ name: 'johnny', last: 'depp' },
{ name: 'anne', last: 'hathaway' },
{ name: 'will', last: 'smith' },
{ name: 'charlize', last: 'theron' },
{ name: 'matt', last: 'damon' },
{ name: 'julia', last: 'roberts' },
{ name: 'christian', last: 'bale' },
{ name: 'cate', last: 'blanchett' },
];

22
w5_2_FP/index.html Normal file
View File

@@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="./style.css" />
<meta charset="utf-8" />
</head>
<body>
<ul id="list">
<li><span class="blue">Christian</span> <span class="pink">BALE</span></li>
<li><span class="blue">Cate</span> <span class="pink">BLANCHETT</span></li>
<!-- ... -->
</ul>
<script defer type="module" src="index.js"></script>
</body>
</html>

35
w5_2_FP/index.js Normal file
View File

@@ -0,0 +1,35 @@
import { data } from './data.js';
// Utility function to compose functions
const pipe =
(...fns) =>
(x) =>
fns.reduce((v, f) => f(v), x);
/*
Given
{ name: 'tom', last: 'hanks' },
transform it to
<li><span class="blue">Tom</span> <span class="pink">HANKS</span></li>
Sort all the actors by their lastname.
*/
// Transfor the following code with loops to use functional programming style
// Sort by lastname
data.sort((a, b) => a.last.localeCompare(b.last));
// Create HTML list items
let html = '';
// For each actor
for (const actor of data) {
const name = actor.name[0].toUpperCase() + actor.name.slice(1);
const last = actor.last.toUpperCase();
html += `<li><span class="blue">${name}</span> <span class="pink">${last}</span></li>`;
}
// set the innerHTML of the list element to the generated HTML
document.getElementById('list').innerHTML = html;

21
w5_2_FP/style.css Normal file
View File

@@ -0,0 +1,21 @@
body {
width: 600px;
}
ol {
text-align: left;
}
li {
list-style: circle;
}
.blue {
color: dodgerblue;
font-style: italic;
}
.pink {
color: fuchsia;
font-weight: bold;
}

23
w6_1_FP/index.html Normal file
View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<button id="sort-by-name">Sort by Name</button>
<button id="sort-by-last">Sort by Last Name</button>
<button id="sort-by-age">Sort by Age</button>
</div>
<ul id="people-list"></ul>
<script defer src="index.js"></script>
</body>
</html>

52
w6_1_FP/index.js Normal file
View File

@@ -0,0 +1,52 @@
const people = [
{ name: 'Bob', last: 'Johnson', age: 30 },
{ name: 'Charlie', last: 'Brown', age: 25 },
{ name: 'David', last: 'Williams', age: 35 },
{ name: 'Alice', last: 'Smith', age: 28 },
{ name: 'Eve', last: 'Davis', age: 22 },
{ name: 'Frank', last: 'Miller', age: 40 },
];
const buttonName = document.getElementById('sort-by-name');
const buttonLast = document.getElementById('sort-by-last');
const buttonAge = document.getElementById('sort-by-age');
// Helpers
const pipe =
(...functions) =>
(value) => {
return functions.reduce((acc, fn) => fn(acc), value);
};
const render = (listItems) => {
const ul = document.getElementById('people-list');
ul.innerHTML = listItems.join('');
};
// Exercise helpers
const compareByName = (a, b) => a.name.localeCompare(b.name);
const compareByLast = (a, b) => a.last.localeCompare(b.last);
const compareByAge = (a, b) => a.age - b.age;
const sortPeopleBy = /* ... PLACEHOLDER ... */ () => {};
const peopleToString = (people) => {
return 'PLACEHOLDER';
};
const peopleToListItems = (strings) => 'PLACEHOLDER';
// Main
const byname = /* ... PLACEHOLDER ... */ undefined;
const bylast = /* ... PLACEHOLDER ... */ undefined;
const byage = /* ... PLACEHOLDER ... */ undefined;
buttonName.addEventListener('click', () => undefined);
buttonLast.addEventListener('click', () => undefined);
buttonAge.addEventListener('click', () => undefined);
render(['<li>a</li>', '<li>b</li>', '<li>c</li>']);

44
w6_2_clock/clock.js Normal file
View File

@@ -0,0 +1,44 @@
/*
* Clock Module
*/
/**
* @typedef Clock
* @type {object}
* @property {number} x - The x-coordinate of the clock center.
* @property {number} y - The y-coordinate of the clock center.
* @property {number} radius - The radius of the clock.
* @property {string} color - The color of the clock.
* @property {number} oneSecondMs - The interval in milliseconds for one second.
* @property {number} hours - The current hour.
* @property {number} minutes - The current minute.
* @property {number} seconds - The current second.
*/
const createClock = (color, oneSecondMs) => (x, y, radius) => {
// return a clock
};
// export const createSportsClock = createClock('#FFF000', 500);
// export const createStandardClock = createClock('#FFFFFF', 1000);
export const drawClock = (clock) => {
// draw the clock face
};
export function startClock(clock) {
// start animating the clock
}
export function stopClock(intervalId) {
// stop the clock
}
// Private Helpers
const tick = (clock) => {
// return a new clock that advances the time of 1 second
};
const drawClockHands = (x, y, alpha, length) => {
// draw the clock hands
};

16
w6_2_clock/index.html Normal file
View File

@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=<device-width>, initial-scale=1.0">
<title>Document</title>
<script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/p5.js'
integrity='sha512-BLd2MDTrBCo01Vkhjbjn3ITBDbx3o/Lt7D5hj5oLwW8vlDHYXMenxglTcUURCgBhdLNAjZ7KD8x4ZA7bQY3OhA=='
crossorigin='anonymous'></script>
</head>
<body>
<script type="module" src="./index.js""></script>
</body>
</html>

30
w6_2_clock/index.js Normal file
View File

@@ -0,0 +1,30 @@
import {
createStandardClock,
createSportsClock,
drawClock,
startClock,
stopClock,
} from './clock.js';
let clock;
let timer;
window.setup = function () {
createCanvas(800, 600);
// clock = createStandardClock(width / 2, height / 2, 200);
// clock = createSportsClock(width / 2, height / 2, 200);
// timer = startClock(clock);
};
window.draw = function () {
background('#eee');
// drawClock(clock);
};
window.keyPressed = function () {
if (key === 's' || key === 'S') {
// stopClock(timer);
console.log('Clock stopped');
}
};

11
w9_cars/css/style.css Normal file
View File

@@ -0,0 +1,11 @@
html,
body {
margin: 0;
/* padding: 5px; */
align-items: center;
text-align: center;
background-color: beige;
}
canvas {
display: block;
}

BIN
w9_cars/data/car.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

BIN
w9_cars/data/font.vlw Normal file

Binary file not shown.

BIN
w9_cars/data/sport.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
w9_cars/data/truck.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

18
w9_cars/index.html Normal file
View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/p5.js'
integrity='sha512-BLd2MDTrBCo01Vkhjbjn3ITBDbx3o/Lt7D5hj5oLwW8vlDHYXMenxglTcUURCgBhdLNAjZ7KD8x4ZA7bQY3OhA=='
crossorigin='anonymous'></script>
<link rel="stylesheet" type="text/css" href="./css/style.css" />
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>

43
w9_cars/sketch.js Normal file
View File

@@ -0,0 +1,43 @@
const vehicles = [];
const IMG_SIZE = 400;
let message = '';
const images = {};
function setup() {
createCanvas(4 * IMG_SIZE, 300);
vehicles.push(new Car(4));
}
function draw() {
background(255);
for (let i = 0; i < vehicles.length; i += 1) {
vehicles[i].draw(i * IMG_SIZE, 0, IMG_SIZE);
}
fill(0);
textFont('Arial', 20);
textAlign(CENTER);
text(message, width / 2, IMG_SIZE);
}
function mousePressed() {
const index = floor(mouseX / IMG_SIZE);
message = vehicles[index]?.getDescription() ?? 'None'; // polymorphism!
}
// CLASSES
class Car {
constructor(passengers) {
// ...
}
getDescription() {
// PLACEHOLDER
}
draw() {}
}

38
w9_cars/test.wsd Normal file
View File

@@ -0,0 +1,38 @@
@startuml
class Vehicle {
-img: PImage
+ {abstract} getDescription(): String
+ draw (x: Number, y: Number, size: Number): void
}
class Car {
- passengers: Number
+ constructor (passengers: Number)
+ getDescription (): String
}
class Truck {
- load: Number
+ constructor (load: Number)
+ getDescription (): String
}
class SportCar {
- fullOp: Bolean
+ constructor (fullOptions: Boolean)
+ getDescription (): String
+ getTurbo (): String
+ getOptions (): String
}
class Convertible {
+ constructor()
+ getDescription(): String
+ getRooftop(): String
}
Vehicle <|.. Car
Vehicle <|.. Truck
Car <|-- SportCar
SportCar <|-- Convertible
@enduml

View File

@@ -0,0 +1,11 @@
html,
body {
margin: 0;
/* padding: 5px; */
align-items: center;
text-align: center;
background-color: beige;
}
canvas {
display: block;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/p5.js'
integrity='sha512-BLd2MDTrBCo01Vkhjbjn3ITBDbx3o/Lt7D5hj5oLwW8vlDHYXMenxglTcUURCgBhdLNAjZ7KD8x4ZA7bQY3OhA=='
crossorigin='anonymous'></script>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>

View File

@@ -0,0 +1,19 @@
const images = {};
// We used this in P5.js (in Vite we would simply import the assets)
function preload() {
images.lightOn = loadImage('data/lightOn.jpg');
images.lightOff = loadImage('data/lightOff.jpg');
}
class Light {}
function setup() {
createCanvas(800, 600);
// createCanvas(400, 300);
console.log(images);
}
function draw() {
background(255);
}

View File

@@ -0,0 +1,11 @@
html,
body {
margin: 0;
/* padding: 5px; */
align-items: center;
text-align: center;
background-color: beige;
}
canvas {
display: block;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

18
w9_lights_obj/index.html Normal file
View File

@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<head>
<script src='https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.3/p5.js'
integrity='sha512-BLd2MDTrBCo01Vkhjbjn3ITBDbx3o/Lt7D5hj5oLwW8vlDHYXMenxglTcUURCgBhdLNAjZ7KD8x4ZA7bQY3OhA=='
crossorigin='anonymous'></script>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<meta charset="utf-8" />
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>

32
w9_lights_obj/sketch.js Normal file
View File

@@ -0,0 +1,32 @@
const images = {};
// We used this in P5.js (in Vite we would simply import the assets)
function preload() {
images.lightOn = loadImage('data/lightOn.jpg');
images.lightOff = loadImage('data/lightOff.jpg');
}
const light = {
init: function (x, width) {
/* ... */
},
toggle: function () {
/* ... */
},
isOn: function () {
/* ... */
},
draw: function () {
/* ... */
},
};
function setup() {
createCanvas(800, 600);
// createCanvas(400, 300);
console.log(images);
}
function draw() {
background(255);
}