Week 4 – Reading Response

Reading Norman’s chapter made me realize how often I get frustrated with specific designs, especially ones that lack efficiency in everyday objects. Norman emphasizes that good design should communicate clearly, prevent errors, and provide feedback. I see this principle in some interactive media, where the design makes it easy to use without much explanation—anyone can figure it out quickly. When something is designed well, you don’t even notice it because everything feels natural and intuitive. Unlike the examples the author mentioned, such as the sink that requires pushing down on it or the door that needs a sign to explain that it is a sliding door, good design should not require instructions. If a user has to stop and think about how to use something basic, then the design has already failed.

Something that drives me crazy is the access doors on campus. I walk around carrying two access cards—one specifically for my suite and room, and another for the rest of the campus. It feels unnecessary and inefficient. On top of that, the glass doors are extremely heavy, and the sensors do not work most of the time. Instead of making entry smooth and accessible, the design creates frustration. According to Norman’s ideas, better mapping, clearer feedback, and fewer constraints could significantly improve this experience.

Week 4 – Global Mood (Data Visualization)

Concept:
My concept is based on showing the current global mood, and the world’s current situation. Because whenever I used would google “news” most of the things would is evoke aa negative emotion from me. So, I decided to visualize the news and categorize them into a few different emotions or feelings.

How I created the code:

I used Guardian and NYT API keys in order to get access to live articles, although there are some restrictions, like page requests. Therefore, I added some delay in order to access a larger number of pages and news article headlines. I also used world.json for the country borders.

I then created different arrays: one for the emotional bubbles, one for the country borders, one for the CNN breaking news ticker, and one for tracking articles so they are not shown twice. I also added a timer that updates every 60 seconds and adjusted the speed and position of the news ticker.

Then I added geographical points for a list of countries. I created bubbles for different emotions, with each emotion represented by a color. There is also a map key showing which color represents which emotion. The bubbles have visual effects like glowing and shrinking over time to make the map feel dynamic. Emotions are detected using keywords in article titles to classify sadness, anger, hope, or joy.

It initially gets the last 48 hours of news, then it is updated with live breaking news. I also added fallbacks: if the world map fails to load, a simple grid is shown, and if the API fails, a CORS proxy is used to make sure the news still comes through.

The code:
// Convert guardian format to our format
// Fetch 48 hours of historical news from The Guardian
function fetchHistoricalNews() {
let twoDaysAgo = new Date();
twoDaysAgo.setDate(twoDaysAgo.getDate() - 2);
let fromDate = twoDaysAgo.toISOString().split("T")[0]; // Format: YYYY-MM-DD
console.log("📅 Fetching Guardian news from " + fromDate + " to today...");

let totalArticles = [];
let pagesToFetch = 10; // Get 10 pages of results
let pagesLoaded = 0;
let failedPages = 0;

// Fetch pages sequentially with delay to avoid rate limiting
for (let pageNumber = 1; pageNumber <= pagesToFetch; pageNumber++) {
setTimeout(() => {
let apiURL =
"https://content.guardianapis.com/search?section=world&show-tags=keyword&from-date=" +
fromDate +
"&page-size=30&page=" +
pageNumber +
"&show-fields=webPublicationDate&api-key=" +
GUARDIAN_API_KEY;
console.log("🔄 Requesting Guardian page " + pageNumber + "...");
fetch(apiURL)
.then((response) => {
console.log("📡 Guardian page " + pageNumber + " response status: " + response.status);
if (!response.ok) throw new Error("HTTP " + response.status);
return response.json();
})
.then((data) => {
if (data && data.response && data.response.results) {
totalArticles = totalArticles.concat(data.response.results);
pagesLoaded++;
console.log("✅ Page " + pageNumber + " loaded: " + data.response.results.length + " articles");
if (pagesLoaded + failedPages === pagesToFetch) {
if (totalArticles.length > 0) {
console.log("📊 Total Guardian historical: " + totalArticles.length + " (" + pagesLoaded + "/" + pagesToFetch + " pages successful)");
isShowingHistorical = true;
sourceStatus.guardian.active = true;
sourceStatus.guardian.articleCount = totalArticles.length;
processArticles(totalArticles, true, "guardian"); // true = historical
} else {
console.error("❌ All Guardian pages failed");
sourceStatus.guardian.active = false;
}
}
} else {
console.warn("⚠️ Guardian page " + pageNumber + " returned empty results");
failedPages++;
}
})
.catch((error) => {
console.error("❌ Guardian page " + pageNumber + " failed:", error.message);
failedPages++;
if (pagesLoaded + failedPages === pagesToFetch) {
if (totalArticles.length > 0) {
console.log("📊 Total Guardian historical: " + totalArticles.length + " (" + pagesLoaded + "/" + pagesToFetch + " pages successful)");
isShowingHistorical = true;
sourceStatus.guardian.active = true;
sourceStatus.guardian.articleCount = totalArticles.length;
processArticles(totalArticles, true, "guardian");
} else {
console.error("❌ All Guardian pages failed");
sourceStatus.guardian.active = false;
}
}
});
}, pageNumber * PAGE_REQUEST_DELAY); // Use delay variable
}
}

// Fetch the latest breaking news from The Guardian
function fetchGuardianNews() {
console.log("📰 [" + getCurrentTime() + "] Fetching Guardian news...");
let apiURL =
"https://content.guardianapis.com/search?section=world&show-tags=keyword&page-size=25&show-fields=webPublicationDate&api-key=" +
GUARDIAN_API_KEY;
fetch(apiURL)
.then((response) => {
if (!response.ok) throw new Error("HTTP " + response.status);
return response.json();
})
.then((data) => {
if (data && data.response && data.response.results) {
console.log("✅ [" + getCurrentTime() + "] Guardian: " + data.response.results.length + " articles");
sourceStatus.guardian.active = true;
sourceStatus.guardian.lastUpdate = new Date();
sourceStatus.guardian.articleCount = data.response.results.length;
isShowingHistorical = false; // We're showing breaking news now
processArticles(data.response.results, false, "guardian"); // false = breaking news
}
})
.catch((error) => {
console.log("⚠️ Guardian direct failed, trying CORS proxy...");
tryGuardianWithProxy();
});
}

// Backup method: Try Guardian API through CORS proxy
function tryGuardianWithProxy() {
let apiURL =
"https://content.guardianapis.com/search?section=world&show-tags=keyword&page-size=25&show-fields=webPublicationDate&api-key=" +
GUARDIAN_API_KEY;
let proxiedURL = "https://api.allorigins.win/raw?url=" + encodeURIComponent(apiURL);
fetch(proxiedURL)
.then((response) => {
if (!response.ok) throw new Error("HTTP " + response.status);
return response.json();
})
.then((data) => {
if (data && data.response && data.response.results) {
console.log("✅ [" + getCurrentTime() + "] Guardian via proxy: " + data.response.results.length + " articles");
sourceStatus.guardian.active = true;
sourceStatus.guardian.lastUpdate = new Date();
sourceStatus.guardian.articleCount = data.response.results.length;
isShowingHistorical = false;
processArticles(data.response.results, false, "guardian");
}
})
.catch((error) => {
console.error("❌ [" + getCurrentTime() + "] Guardian completely failed:", error.message);
sourceStatus.guardian.active = false;
});
}

 

Reflection and ideas for future work or improvements:

Reflection:

Global Mood taught me a lot about combining live data, visualization, and emotion analysis. Seeing emotions vary across regions in real time was fascinating, and effects like glowing and shrinking bubbles made the map feel dynamic. It also taught me how to APIs and json files on P5.js.

Future Work and  improvements:

I would love to present it as an installation to show people the current global situation. For future improvements, I would incorporate Natural Language Processing to classify emotions more accurately, rather than relying solely on specific keywords. I also wish I had greater access to open-source news APIs to expand the dataset.

 

Week 4 – Data Visualization

Data Visualization

For this week’s assignment, an animated visualization of global temperature data from 1880 to today. The sketch fetches real data from NASA’s GISS API and draws it as a bar chart. Blue bars mean cooler-than-average years. Red bars mean warmer-than-average years. As the bars animate in, poetic phrases appear based on the temperature, giving the data a human, storytelling feel.

Controls: Click to pause/play · Hover bars for details · Press R to restart · Press S to save · Spacebar to toggle

Code I Am Proud Of

The part I am most proud of is how the bars get their color. Instead of just picking “blue” or “red,” I used lerpColor() to blend between shades based on the actual temperature value. Colder years get a deeper blue, and warmer years get a more intense red. It makes the warming trend really pop visually:

// Color: blue for cold, red for warm
let barColor;
if (d.anomaly < 0) {
  barColor = lerpColor(
    color(70, 130, 200, 200),
    color(40, 80, 160, 200),
    map(d.anomaly, 0, -0.5, 0, 1)
  );
} else {
  barColor = lerpColor(
    color(200, 100, 70, 200),
    color(240, 60, 40, 220),
    map(d.anomaly, 0, 1.5, 0, 1)
  );
}

I also like the generative text system. Each time a new data point appears, the sketch picks a phrase from a pool that matches the temperature: cold, warm, or neutral. It is a simple idea but it adds a lot of personality to the piece:

function triggerPhrase(anomaly) {
  if (millis() - lastPhraseTime < 1200) return;

  let phrases;
  if (anomaly < -0.1) {
    phrases = coldPhrases;
  } else if (anomaly > 0.3) {
    phrases = warmPhrases;
  } else {
    phrases = neutralPhrases;
  }

  activePhrase = random(phrases);
  phraseTargetAlpha = 255;
  lastPhraseTime = millis();
}

What I Learned

Working with a real API changed everything. The full 145-year dataset tells a story on its own. You can see the blue bars dominate the early decades, then the reds creep in and accelerate. I did not need to editorialize; the shape of the data is the narrative. The hardest part was dealing with CORS issues and making sure broken data rows do not crash the sketch.


Data: NASA GISS Surface Temperature Analysis · Built with p5.js · February 2026

Week 4 – Creative Reading Response

What’s something (not mentioned in the reading) that drives you crazy and how could it be improved?

Something that drives me crazy is some of the dryers in the laundry rooms on campus, specifically the ones that don’t have a screen! How am I supposed to know when my laundry will be ready? This system could make sense if this machine was just used by one person in their house, and they could just check on the machine whenever (or maybe there’s some sound that plays when a cycle is done). However, for a machine that’s shared by a whole building, it’s so inconvenient that you kinda have to just guess when your laundry would be ready. And if you’re too late, your laundry might just be tossed on the floor! This can be blamed on either university facilities for purchasing machines that do not have screens (since a few do, it’s just some that don’t have screens) or we can just blame the machines, because why can’t I know how long my clothes will take? So the improvement from my perspective is to add a screen!

How can you apply some of the author’s principles of design to interactive media?

Instructions! But, simple ones. Ones that build on what user’s are used to. For example, users are now used to pressing on the right side of their screen to speed up videos as that is how you do it on TikTok, YouTube, and Instagram. Instead of trying to reinvent wheel, sometimes it’s best to use what already exists.

Week 4 – Reading Response – Kamila Dautkhan

1. Something that drives me crazy (not mentioned in the reading) and how it could be improved

One of the problems that drive me crazy is the touch screen controls in cars because many new cars have replaced physical buttons and knobs with a large screen for everything (like changing the AC or the radio). This is frustrating because you have to take your eyes off the road to look at the screen. You can’t feel where the button is like you could with a real knob.

I think the solution for this problem can be bringing back physical knobs for the most important things like volume and temperature. This uses what Norman calls “tactile feedback” so that you can feel the click of the knob and know exactly what you’re doing without looking away from the road.

  1. How can you apply some of the author’s principles of design to interactive media? 

On a website buttons should look like buttons (maybe with a shadow or a bright color). This provides the user a visual cue. When you click “Submit” on a form, the button should change color or a loading circle should appear. This lets you know the website actually giving you an instant response and is actually working. Also, I found natural layout principle very useful because now I know that controls  should be placed in a logical way. For example, I should put important buttons on the right side of the screen because that’s the direction we read and move forward. Moreover, Conceptual I would use icons that people already understand. A trash can icon for deleting files or a house icon for the home page helps users understand how the app works instantly because it is already familiar to them.



Week 4: Reading Response

My first time going to a library study room, I was confused on how to get out because I didn’t know you had to click a button to leave. Although it has a sign that says “click to exit,” I was still lost because other study rooms on campus didn’t have this, and the button is on the side of the door where you usually don’t look, something Norman calls a classic signifier failure. The more I used the study rooms, I found myself still struggling as sometimes the button to leave or the ID scanner to get inside just don’t work. When I swipe my ID and nothing happens I have no idea if my card failed, the reader failed, or I did something wrong, which is exactly the feedback problem Norman describes. Getting in and getting out also use two completely different interactions with no consistent logic and it breaks any conceptual model I try to build of how the door works.

I think I can apply Norman’s principles to my own work in p5.js sketches. One thing I want to start doing is making it clearer to users how they are supposed to interact with my sketches, whether they need to click, long press, or drag to interact with my piece. Right now someone could open my sketch and have no idea what to do with it, which is the same signifier problem Norman talks about with doors. I want to incorporate small visual cues like a pulsing cursor, an animated hand icon, or a brief on-screen hint that disappears after a few seconds to guide the user naturally into the interaction without overwhelming them with instructions.

Week 4 – Inside Out

Your concept

I had many ideas for this assignment. When we saw the flight path visualizations in class, I was inspired to do something similar, focusing on maybe DXB and AUH airports. However, after looking through Kaggle, I didn’t find datasets that would really work for the ideas I had, and I didn’t have many idea on how to do a new kind of visualization. Instead, I decided to think about how I could include generative text and that’s how I came up with the idea I ended up doing! I love the Inside Out movie, so I decided to create a visual of the orbs that store her memories, and when the user presses on each orb, it displays that memory.

Embedded sketch

How this was made

The first thing I did was create the design for the orbs. At first, I was going to just import images for each color, however, I decided to explore the different features of p5.js and instead create them from scratch. I referred to a video by Patt Vira where she was actually creating a Gradient Screensaver, built from circles with gradient fill. I watched up till almost the half point of the video to understand how to create the gradient fill. I’ve included comments wherever I used code from her video. I customized the colors based on the colors of the emotions from the movie. At first, I had the colors randomized and were generated using a function. I was planning to repeat the same memories for multiple orbs since it wasn’t guaranteed that I’d have enough memories for the number of orbs generated from each color. After actually creating the csv file of the memories, I realized that there weren’t that many and decided that the number of orbs would be equivalent to the number of memories, and the color of each orb would match up with the emotions for each memory. To actually create this in code, I created an object that stored all the emotion names and the color for each one. Then, I had a function called when creating the orbs that would check what color each one should be based on the emotion it was assigned.

The other main bit of code in this is the interactivity of the user pressing on the orb and the text being displayed.  When creating the orbs, each orb is assigned a line in the csv file (an emotion and corresponding memory), so when the user selects a specific orb, it just shows whichever memory text was assigned to that orb. I also imported a font from Google Fonts to try to add my own touch to the text section.

A highlight of some code that you’re particularly proud of
// referred to yt vid: https://youtu.be/Mdt81-7-U18?si=Uzq8KlE-3FfifFLA
function drawOrb(orb) {
  let gradient = ctx.createRadialGradient(orb.x, orb.y, 0, orb.x, orb.y, orb.r);
  
  let rr = red(orb.c);
  let gg = green(orb.c);
  let bb = blue(orb.c);
  
  // make the center transpert and outer area solid
  gradient.addColorStop(0, `rgba(${rr}, ${gg}, ${bb}, 0)`);
  gradient.addColorStop(0.8, `rgba(${rr}, ${gg}, ${bb}, 1)`);
  
  // use gradient as fill for the circles
  ctx.fillStyle = gradient;

  noStroke();
  ellipse(orb.x, orb.y, orb.r * 2, orb.r * 2);
}

Despite using a video to do this section, I am still really proud that I explored something new to improve the aesthetics of my assignment!

Reflection and ideas for future work or improvements

Something I wanted to add, but didn’t have the time, was a glowing effect to kind of mimic how the orbs look in the movie. I think that’s a possible improvement that could make the sketch look more realistic to the inspiration.

Week 4- Reading response

One thing that drives me crazy is self-checkout and checkout lanes in general. Stores build 30 checkout stations but only use two. Now we have self-checkout, and still the process is confusing and slow. This problem is not about the technology itself. It is about poor design. The system does not clearly show how to use it efficiently. It lacks good signifiers. Simple visual cues, clear instructions, or intuitive layout would solve the problem. The action should be easy to understand without guessing.

From the reading, I learned that good design depends on affordances, signifiers, mapping, feedback, and clear conceptual models. In the case of self-checkout, the affordance exists because you can scan items and pay. But the signifiers are missing. The design does not communicate the correct sequence of actions. The mapping between the screen, the scanner, and the bagging area is also unclear. If designers focused more on discoverability and understanding, these everyday frustrations would not happen.

I can apply these principles to interactive media. In digital design, buttons, gestures, and workflows should clearly show what they do. Users should not guess how to swipe, click, or complete a task. Good feedback is also important. When a user takes an action, the system should respond immediately. Finally, the interface should support a simple conceptual model. Users should understand how the system works just by looking at it and trying it. If I design with clear signifiers, natural mapping, and strong feedback, I can create interactive work that feels simple, clear, and easy to use.

Week 4 – Digital Oracle

Concept

This work  acts an oracle by generating wise sayings. Predefined times, elements, actions and destinations are stored in the program and they are randomly paired up to create the oracle. This work employs the concept of lists to store the times, elements, actions and destinations. Text in p5js concept was explored in this work by employing textAlign, textSize and textFont to create the desired output for the work.

A background animation was created for the program by creating translucent circle that randomly move around on the screening. This was done using class and arrays. To keep the design visually appealing, when a ball goes off the screen, it appears on the opposite side of the screen and and continues moving the same trajectory.

An oracles fades and a new one appears and this is done by changing the transparency of the text each frame. When the text becomes fully transparent, it is deleted and a new one is formed and displayed. When you click on the screen, the program can also change between light and dark mode using the callback function mouseClicked and an if statement

Code I’m proud of

for (let i=0; i<currentLines.length; i++) {
    text(currentLines[i], width/2, startY + (i*spacing));
  }
  
  // Fading 
  textAlpha += fadeSpeed;
  
  if (textAlpha < 0) {
    currentLines.length = 0;
    generateNewPoem();
    fadeSpeed = 2;
  }
  
  if (textAlpha > 400) {
    fadeSpeed = -2;
  }

This is the code that generates the oracle and causes the fading effect. A for loop is used to print out randomly generated text in a vertical format and the if statements gradually increase the opaqueness of the the text and then makes it transparent eventually disappear.

Embedded Sketch

How it was made

The texts in the various arrays that are randomly selected where generated with Chat GPT with the goal of creating a more natural and consistent text

Reflection

This was a good exercise to make use of my knowledge in text manipulation, arrays, classes and other concepts learnt in other lectures. This work can be improved by building on the background animations and changing the colors the text are printed in to create a more visually pleasing effect.

Week 3 – creative reading response

I think a strongly interactive system is one where the user and the system affect each other. It is not just clicking and seeing something move. It feels like a two way conversation. The system responds fast and clearly. The user understands what caused the change. The user’s choices matter and can change what happens next.

In my p5 sketches, I mostly use mouse movement and clicks. The shapes or colors react, but the interaction is sometimes very basic. It does not always feel deep. To improve this, I can make the sketch remember what the user did before. The drawing can change over time based on their actions. This will make it feel more alive and less repetitive.

I also want to give better feedback. The system should clearly show that it is responding. Small changes in color, size, or movement can help. I can also use more controls like the keyboard. This will give the user more ways to interact. I want my sketches to feel like small worlds the user can explore, not just simple animations.