Week 4 Assignment: Personal Electronics Market in India

I had initially wanted to work with generative text to create poems in my native language (Bengali), which would have translations in English. Midway through this project however, I realized how challenging it was as the rules of grammar in English and Bengali are quite different, and I couldn’t just make one-to-one sentences, even simple ones.

Then I decided to go through the Kaggle website to search for suitable datasets. The dataset on the Device market in India over last 15 years (https://www.kaggle.com/datasets/michau96/device-market-in-india-over-last-15-years) was a trending dataset, so I decided to use that. Since the dataset was on a monthly basis, I first used Excel to take averages across each year, converting the dataset to an annual one.

When it came to making the plot itself, I first tried getting the basic stacked histogram right. This was done using rectMode(CORNERS) as it allows to specify the opposite corners of the rectangle. The x position for each bar was specified using the Year column and the y position and height using the percentage value of each column normalized to the desired height of the plot.

    rectMode(CORNERS); //to allow stacking of the bars
    //bar for mobile
    fill(this.mobileColor);
    rect(
      (this.dataYear - 2007) * w,
      y,
      w * (this.dataYear - 2007 + 1),
      y - (h / 100 * this.mobile)
    );
    //bar for desktop
    fill(this.desktopColor);
    rect(
      (this.dataYear - 2007) * w,
      y - (h/100 * this.mobile),
      w * (this.dataYear - 2007 + 1),
      y - (h / 100 * this.mobile) - (h / 100 * this.desktop)
    );
    //bar for tablet
    fill(this.tabletColor);
    rect(
      (this.dataYear - 2007) * w,
      y - (h / 100 * this.mobile) - (h/100 * this.desktop),
      w * (this.dataYear - 2007 + 1),
      y - h
    );

After that, I decided to work on the graph legend. The legend class takes one of the bars and makes the legend based off of that (this works since every bar is identical when it comes to the number of groups and the color associated with each group).

Finally, I wanted to add a level of interactivity in the form of a popup that comes up when you hover over a bar, similar to the statistics website Statista (statista.com). I tried using the mouseOver() event listener, but that didn’t work with the bar object for some reason, so I decided to go with the hard route of checking mouseX and mouseY against the bar’s dimensions.

The final result is below:

 

I would have loved to make this more generalized and capable of visualizing any dataset loaded by a user (kind of like ggplot in R). In that case, the program would need to work for any number of columns. But until I figure out how to make function arguments optional, this is kind of impossible.

Reading Response 4: The Design of Everyday Things

Upon delving into “The Psychopathology of Everyday Things,” I found Don Norman’s exploration of design principles and challenges to be thought-provoking and relevant. The idea that technological advancements, while promising increased benefits, also introduce more complexities and challenges in usability, is a stark reality in today’s rapidly evolving tech landscape. This made me think of the evolution of smartphones, which our generation was the last to experience. Initially, phones were simple – calls, texts, and perhaps a basic camera (remembering my flip phone). However, we now have smartphones that can do almost everything but are accompanied by a myriad of complexities. Consider the addition of facial recognition, Bluetooth, and a multitude of applications on our smartphones. While these features enhance functionality, they often lead to confusion and frustration– such as the times I’m fumbling through settings and menus on my smartphone, realizing that the very advancements intended to make life easier can, at times, make it more challenging.

 

I believe that technology should enhance, not complicate, our lives. Thus I agree that as we embrace innovation, designers must prioritize user experience and human-centred design to ensure that technological progress truly benefits users. For example, the shift from traditional wired earphones to wireless counterparts provided a significant leap in user convenience. Wireless earphones, like Apple’s AirPods, offer users unparalleled freedom of movement and freedom from tangled cords. However, it introduced new challenges, such as using touch gestures, which might not always be intuitive. Moreover, since the two buds are not connected, it was very easy to misplace them.

To strike a balance between innovation and user-friendliness, designers should adopt a user-centric approach. Conducting extensive user testing and feedback sessions can provide invaluable insights into which features are genuinely beneficial and how users prefer to interact with them. Prioritizing essential functions and ensuring that they are easily accessible, perhaps through intuitive gestures or a clear menu hierarchy, may help prevent users from feeling inundated. For example, the ‘Find My AirPods’ feature was added to address the challenge of potential loss. Overall, achieving equilibrium involves understanding that not every technological advancement needs to be incorporated if it compromises usability.

Reading Reflection #4

Don Norman presents a key idea in “The Design of Everyday Things,” which is feedback in design. According to Norman, feedback is a means of informing the user of the outcomes of an action. He uses commonplace examples to demonstrate this, such as sitting at a traffic light without seeing any indication that the system has spotted your automobile, or pushing buttons on an elevator without knowing if the elevator is on its way. This idea emphasizes how crucial it is to provide users with prompt, understandable feedback so they may be assured that their action has been recorded and is being handled. Ineffective feedback can cause consumers to feel doubtful, angry, or confused, which can make them dislike the system or product.

When I think about it, this idea has really changed the way I think about user interface and design. I can think of several instances where I kept pressing buttons on gadgets or user interfaces and got no reaction. I’ve always found this experience disconcerting because I’m not sure if my activities were acknowledged. I completely agree with Norman’s assessment on the importance of receiving feedback that is both clear and fast. It draws attention to a prevalent problem found in many designs and emphasizes how crucial it is to include transparent feedback methods in order to increase usability and user happiness. This understanding highlights the vital role feedback plays in enabling successful human-machine interactions, and it motivates me to examine designs more closely, both those I work with on a daily basis and those I might develop.

Asciilumination – Assignment 4 – Dachi Tarughishvili

Passing by Interactive Media Lab, I always noticed those TVs that used webcams to track our movement and demonstrate interesting visualization using predefined symbols. I always wondered how it actually worked. So for this data visulization assignment I wanted to recreate it and perhaps add some more adjustments. I followed Coding Train’s coding challenge tutorial regarding ASCII Text images where most of my code comes from.
The basic mechanism behind this program is to map the pixel brightness values which are calculated by dividing their average RGB values and mapping it to characters from density character strings. In this case, I am using ‘ÑYUAD876543210?!abc;:+=-,._’; since initial symbols take up more density and show contrast better but it can realistically be anything. Super bright parts of the image have no space value at all. Additionally, there is no Canvas, and this is direct html implementation with little bit of CSS. I also added a slider for density value which adjusts number of spaces that are added to the string, which acts similiar to how contrast slider would act in photo editing app. If uyou think about it, thats actually whats happening. There are more spaces for wider value of brighter pixels. There is also a Toggle Color button on top left, which assigns the symbols colors based on initial pixel value. This is done per frame basis.
To ensure that you see full working project, make sure to follow P5 link, since this website does not correctly display it and also you need camera permissions anyway since it takes the video of your webcam.
Here is perhaps the most important code out of entire project:

 //loop to iterate over pixels
  for (let j = 0; j < video.height; j++) { //iterates over rows (height)
    for (let i = 0; i < video.width; i++) { //iterates over columns (width)
      const pixelIndex = (i + j * video.width) * 4; 
      //calculates index of pixel in videos pixel array based on its x and y cordinates (i and j). basically vertical and horizontal displacement. Video width indicates how many pixels are in each row. r, g b, a so we multiply by 4 since pixel takes up 4 spaces in array
      const r = video.pixels[pixelIndex];
      const g = video.pixels[pixelIndex + 1];
      const b = video.pixels[pixelIndex + 2];
      const avg = (r + g + b) / 3;
      const len = adjustedDensity.length;//to later map brightness value
      
      const charIndex = floor(map(avg, 0, 255, 0, len)); 
      
      //maps avg value from 0 to 255 to 0 to len. floor is used for rounding
      
      const c = adjustedDensity.charAt(charIndex);
      
      //brighter pixel = higher char index lower density
      
      const charColor = `rgb(${r},${g},${b})`; 
      //its a template literal, javascript uses it for embedding expressions within the string
      
      if (c == " ") {
        asciiImage += "&nbsp;";
      } else if (check == true) {
         asciiImage += `<span style="color:${charColor};">${c}</span>`; 
      } else {
        asciiImage += c; //adds c to our image
      }
      
      //span element is inline container in hztml used ot apply styles without line break
      //if our c is empty by mapping, correspond that to true space (html does not conventionally display empty spaces) 
      
    }
    asciiImage += '<br/>'; //line break to start fresh rows
  }
  asciiDiv.html(asciiImage); //sets html content of ascidiv to our finalized asciimage, by continously drawing we update div content and thus motion is live
}

The code is fully commented but the general idea is to find out r g b values for individual pixels. After that, we find average value which corresponds to our brightness. We map our string index to brightness values. Therefore we have a constant C which is a character for every-frame and we add it to our frame. If color is on, then its color is modified.

In the future, I could work on optimizing since. Refreshing html elements so many times, especially when color is applied is very taxing on CPU and the process becomes laggy. Lowering frame-rate does not help much. Additionally, I could add more adjustmenets and variables, such as video size, font options and more. The latter is especially interesting since the font I am using has same horizontal length. Variable font would be harder to implement. Overall I am very glad with how this project turned out and would like to work on it more in the future.

Week 4 – Reading Response: Every day’s Life Design | Haziel

I found the reading really interesting and relatable as it provides a thought-provoking exploration of design principles and their application to everyday life, particularly focusing on the challenges posed by modern design complexity. Don Norman’s concept of “Norman Doors” highlights a common frustration experienced by many individuals, including me, when interacting with poorly designed products, such as doors with ambiguous instructions.

The reading also made me think of other trivial daily life examples. For instance, the design of a smartphone interfaces often reflects the principles discussed in the reading, particularly regarding feedback and conceptual models. When typing a message on the smartphone keyboard, the visual feedback of each keystroke appearing on the screen provides immediate confirmation of input, enhancing the user’s understanding of their actions. This feedback loop is crucial for users to feel confident and engaged with the device.

Assignment 4 – Lyrics Video | Haziel

For this assignment, I got inspiration from one of my favorite Brazilian songs, Wave by Antonio Carlos Jobim. The objective of this project is to display a Canva that looks like a YouTube lyrics video. Using generative text, I have created a CSV file with the translation of the lyrics. Then, it is loaded in the main sketch along with the background image and the instrumental of the song.

Rather than just displaying the lyrics on the screen, I added a bit of interactivity as the user gets to choose when to read the next sentences. So, if we click on the screen, we load one sentence at a time, following the order of the song. Additionally, I added some animation to the sentences, as they move in a wave format to match the concept of the song. It also allows the user to immerse themselves in the project and read the (I would say) beautiful and romantic lyrics.

When coding this assignment, I also got references from the text() function.

function draw() {
  // Display the background image
  image(bgImage, 0, 0, width, height);

  // Sets the text alignment to center
  textAlign(CENTER);
  
  // Calculate y-coordinate with a sinusoidal function for wave animation
  let y = height - 20 + sin(frameCount * 0.05) * 10; // Adjust the amplitude (10) for desired wave height
                                                     // Adjust the frequency (0.05) for wave speed

  // Draw the current sentence at the bottom center with animated wave effect
  drawWords(width / 2, y);
}

function drawWords(x, y) {
  // Text color
  fill('gold');

  // Display the current sentence at the specified position on the canvas
  text(sentences[currentSentenceIndex], x, y);
}

Reflection: One area I could still improve is to make the Canva more animated and dynamic. Currently, the animation is limited to the wave effect applied to the text as it moves on the screen. However, there are several ways we can enhance the animation to make the canvas more engaging, such as background animations and transitions between the sentences.

Assignment 4 – Reading Reflection

The excerpt from Don Norman’s “The Design of Everyday Things” offers a perceptive look at the psychology of commonplace objects and their designs. In his discussion of frequent problems with doors, light switches, and technology, Norman highlights the significance of design features like affordances and signifiers. He contends that effective design should be intuitive, enabling people to utilize a product without the need for manuals, mostly by means of obvious and sensible hints included into the design itself.

When I think about it, Norman’s emphasis on user-friendly design resonates even more. From my own experience, I have come across a lot of non-intuitive products and interfaces, which has caused annoyance and mistakes. I’m more conscious of the importance of user-centered design now that I’ve read this, and it’s inspired me to think about how the systems and items around me may be made clearer and easier to use. Norman’s concept of “affordances,” which refers to the potential interactions between people and their surroundings, has altered my understanding of how products should be made to fit naturally with human use rather than requiring users to adjust to complicated or counterintuitive systems.

Week 4 Readings – Norman Doors

Ah yes, should I pull or should I push this door? From the image, we can already tell that something is off with the door. The sign says to pull the door, yet the handle is flat. These doors are commonly referred to as Norman Doors, introduced by Donald A. Norman in his book we read this week.

When designing something, it is always best to remember the target audience. Most object designs require human senses as an input to be used. While this does sound able-ist, we should also ask ourselves the question: How would this object be used for those who require more assistance? 

People will always seek the path of least resistance. An intuitive design is always good. We can measure how good a design is by simply using our senses. If it feels ‘natural’ to use, as if it is part of our body, it means the object is well designed. Otherwise, if we stop to think about how to use the object, that means it is redundant.

I believe that the concept of affordances Norman wants us to embed in our minds is this: As a designer, we need to put ourselves in the shoes of the audience. Designers can impact the lives of its users, be it for good, or for the worse. Being able to distinguish the holes or problems in the experience of our design is an important aspect to always remember.

Assignment 4 – UI/UX Reading

“Design of Everyday Things” presents a compelling exploration of the interdisciplinary nature of design and the challenges involved in creating successful products. For me, it emphasized the importance of considering various perspectives, goals, and priorities from different disciplines, such as marketing, engineering, manufacturing, and customer support. In the modern age, where industries increasingly rely on cross-functional collaboration to innovate and deliver products that meet diverse consumer needs, the point that the text makes shine. In today’s fast-paced market, where competition is fierce, understanding and integrating these varied viewpoints is crucial for achieving market success.
Don Norman highlights the significance of user experience and the formation of conceptual models in product design. He underscores the gap that often exists between the designer’s vision and the user’s perception, emphasizing the critical role of the system image in bridging this divide. In our modern digital landscape, where user-centered design principles are paramount, this notion holds particular relevance.
Norman stated many things which I found relevant to myself. One such idea was that designers will often take shortcuts when something is too complex. This reminded me of myself: I am lazy, and if there is a way to do something quicker without too much of a quality sacrifice, I will do it. Interestingly, I also remembered Japanese web design, and how it differs from Western websites. While her in the West, sites are usually as streamlined as possible, Eastern sites often feel cluttered to me, and present a lot of information all at once.

Assignment 4 (production 4) Word Search

The concept of this assignment is a word search. I was inspired to do this because of how much I help my younger brother with his word search activities at home. So I immediately started working on the idea.

I started y creating a grid and then have randomized letters in the grid. There are three specific words that you need to find: “WOW” “FUN” “CAT”. Obviously there are more extra and bonus words that you will find in the grid. The process was long but this is what I ended up with. Please mouse click on the letter that you want to highlight:

A big part of the code that I am proud, which was the most challenging part is the WordGrid Class that I created to have many different functions.

class WordGrid {
  
  
  
    // Constructor 
    constructor(gridSize, cellSize) {
      // Number of cells along one edge of grid 
        this.gridSize = gridSize; 
      // Size of each cell in pixels
        this.cellSize = cellSize; 
        this.words = ['FUN', 'WOW', 'CAT']; 
      // Initialize grid layout
        this.grid = this.initGrid(); 
      // Place words in the grid
        this.placeWords(); 
      // Fill empty spaces in grid
        this.fillGrid(); 
    }

  
  
    // Initializes grid with empty values.
    initGrid() {
      // Array to hold grid data 
        let grid = []; 
      // Iterate over each row 
        for (let i = 0; i < this.gridSize; i++) { 
          // Initialize an empty row
            grid[i] = []; 
          // Iterate over each column in row
            for (let j = 0; j < this.gridSize; j++) { 
      // Set each cell to default state with no letter and not colored
                grid[i][j] = { letter: '-', colored: false };
            }
        }
        return grid; 
    }

  
  
    // Places words from 'words' array into grid 
    placeWords() {
        // Iterate over each word and its index in the array
        this.words.forEach((word, index) => {
    // Calculate row number based on word's index to space out words
            let row = index * 2; 
            // Place each letter of the word into grid.
            for (let i = 0; i < word.length; i++) {
       // Set cell at calculated row and current column to letter of word
                this.grid[row][i] = { letter: word[i], colored: false };
            }
        });
    }

  
  
    // Fills empty cells of grid with random letters
    fillGrid() {
        // Iterate over each cell in grid
        for (let i = 0; i < this.gridSize; i++) {
            for (let j = 0; j < this.gridSize; j++) {
                // Check if cell is empty (marked by '-') 
                if (this.grid[i][j].letter === '-') {
                    // Set the cell to random letter
                    this.grid[i][j].letter = this.getRandomLetter();
                }
            }
        }
    }


  
    // Returns random letter from the alphabet
    getRandomLetter() {
      // String containing all letters 
        const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
        // Return random letter from alphabet string 
        return alphabet[Math.floor(Math.random() * alphabet.length)];
    }

    // Toggles color state of specific cell
    toggleCell(row, col) {
        // Check if cell contains a valid letter (not '-')
        if (this.grid[row][col].letter !== '-') {
            // Toggle 'colored' state of cell
            this.grid[row][col].colored = !this.grid[row][col].colored;
        }
    }

  
  
    // Draws grid on screen
    draw() {
        // Iterate over each cell in grid
        for (let i = 0; i < this.gridSize; i++) {
            for (let j = 0; j < this.gridSize; j++) {
              // Set fill color based on cell's 'colored' state
                fill(this.grid[i][j].colored ? 'red' : 255);
                // Draw border around cell 
                stroke(0);
                // Draw cell as rectangle
                rect(j * this.cellSize, i * this.cellSize, this.cellSize, this.cellSize);
                // Set fill color for text (letter) to black
                fill(0);
              // Align text to center of cell and draw letter
                textAlign(CENTER, CENTER);
                text(this.grid[i][j].letter, j * this.cellSize + this.cellSize / 2, i * this.cellSize + this.cellSize / 2);
            }
        }
    }
}

initGrid(): This function creates a two-dimensional array with objects that correspond to each cell in order to set up the grid’s basic structure. At first, I had trouble seeing the grid as an arrangement of objects instead than just letters or empty spaces. But structuring every cell as an object with letter and color characteristics made managing the state of the grid more adaptable.

placeWords(): It was difficult to arrange the words on the grid, especially to make sure they matched and did not overlap. Every word in this condensed form is arranged horizontally and separated by rows. This function established the foundation for comprehending how words interact with the grid, even though the true problem lay in creating more sophisticated placement algorithms.

fillGrid(): To finish the setup of a standard word search puzzle, random letters had to be placed into the remaining vacant cells of the grid. This method iterates across the grid, substituting random letters for unassigned cells. It filled all the cells that had “-” instead of letters of the words that we placed in the grid.

getRandomLetter(): This function selects a letter at random from the alphabet. It fills in the blank cells in the grid, completing the word search problem and enabling gameplay. It’s a little but essential component of the code. It works directly with the function before it.

toggleCell(row, col): The requirement for grid interaction made this function difficult to implement. Users can choose which cells to change color by clicking them. The gameplay revolves around this interaction, which lets players highlight words they come across.

draw(): Lastly, the draw method gives the word grid a visual representation of each cell’s condition, bringing it to life. For the game to be visually appealing and functional, it was essential that every cell’s content—a letter—and state—colored or not—be shown clearly.

 

There are a couple of limitations for my assignment though. First of all the function that places the words in the grid is placing them all horizontally and under each other which makes the word search game less interesting. Moreover, I only chose three words all with three letters only which again makes this game easy and will end fast. From the technical side, you are required to press on every letter of the grid when you find a word which makes it harder and less appealing to play the game. Making it more realistic like striking through the letters when the correct word is found will make the game more realistic and more appealing to the player. However, overall, I think I did a good job with the representation of the grid and creating a separate  file for the WordGrid class to make the code more organized.