Teaching Hacks
Hacks completed for Tri 2 lessons
Unit 1: SASS Fundamentals
Hack Question: Can you guess what its changing style of the text to?
body {
color: #0000FF;
font-family: Ariel, sans-serif;
font-size: 16px;
}
Nesting
What is nesting? > Answer here (hack question):
- Nesting is a way to organize your code and make it easier to read. It also helps keep your code DRY (Don't Repeat Yourself) .
- Nesting is when you put one selector inside another selector. This is a great way to keep your code organized and make it easier to read.
- When we make HTML we often nest different elements within each other and have a clear structure when we look at it.
- The problem is that in regular CSS we don’t have that so we need to use SASS to help us organize our code.
- Warning: Don’t nest too much as when the CSS is processed it can make overqualified selectors which can be hard to read and maintain. Which means that it would only target that specific element type and not any other elements that have the same class name.
Sass Nesting
- Through nesting the ul, li, and a selectors within the nav selector makes your CSS better and increases its readability overall.
Variables
What is a variable?
- A variable is a container that stores information so for instance when you have multiple places that refer to one value you can just use the variable name instead of the value.
- This is valuable in SASS because it allows you to reuse that value in multiple places throughout your stylesheet.
- The $ symbol is used in Sass to designate a variable.
Pro Tip: The reason SASS variables are better than variables in regular CSS is that they are easier to read with a much simpler syntax.
Fun Fact: Variables in SASS came before CSS and often SASS has features long before they are actually added to CSS as a whole.
Variable Example Syntax
- $variable-name: value;
- Once the sass is processed the variable name is replaced with the value throughout the program.
Mixins: What is a mix in what are we mixing in? Answer here (hack question):
A mixin is kind of a class. If you’re taking the name “mixin” at face value, we’re “mixing in” different styles that other elements can include.
Inheritance
What is inheritance? Answer here (hack question):
- In general programming concept where the child class can inherit properties from the parent class. These properties can be changed and modified in the child class. This prevents code from being repeated and makes the code more usable and flexible.
- In SASS we have a similar concept that can be used as well we can create base styles and then have other styles inherit from them and then we can change them as we please.
- We can do that by through using @extend .name-of-class and then we can add more styles to it as we please. Simple as that.
SASS Demo:
Below is the SASS code I used:
// Variables
$primary-color: #3498db;
$secondary-color: #2ecc71;
$card-background: #ecf0f1;
$card-hover: #bdc3c7;
// Mixins
@mixin transition($property: all, $duration: 0.3s, $timing-function: ease-in-out) {
transition: $property $duration $timing-function;
}
// Styles
.card {
background-color: $card-background;
border-radius: 8px;
padding: 20px;
margin: 20px;
width: 300px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
// Nesting and hover effect
&:hover {
background-color: $card-hover;
}
// Title styling
h2 {
color: $primary-color;
margin-bottom: 10px;
}
// Content styling
p {
color: $secondary-color;
}
// Apply transition mixin
@include transition(background-color);
}
// Usage example
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
// Create multiple cards with different colors
.card-one {
@extend .card;
$card-background: #e74c3c;
$card-hover: #c0392b;
}
.card-two {
@extend .card;
$card-background: #f39c12;
$card-hover: #d35400;
}
.card-three {
@extend .card;
$card-background: #2c3e50;
$card-hover: #34495e;
h2 {
color: #e74c3c; // Customize title color for this card
}
p {
color: #f39c12; // Customize content color for this card
}
}
And here is the running project
Reflection:
The SASS code provided showcases the styling of a card-based layout in a website, and it utilizes various tools and features to enhance the maintainability and reusability of the code. Let’s delve into the tools used and understand why they were incorporated:
- Variables:
- Purpose: Variables are used to store and manage reusable values, such as colors, throughout the stylesheet.
- Why: They promote consistency and ease of maintenance. If a color needs to be changed, it can be done at a single point in the code.
- Mixins:
- Purpose: Mixins are reusable pieces of code that can be included in multiple selectors.
- Why: The
transitionmixin is employed to create consistent and easily modifiable transition effects. This ensures a standardized animation across different elements.
- Nesting:
- Purpose: Nesting is used to structure the code in a more visually intuitive way, especially when dealing with pseudo-classes or nested elements.
- Why: It helps in better organization and readability. The hover effect for the card is defined within the
.cardselector, making it clear that it applies specifically to cards.
- Extend:
- Purpose: The
@extenddirective allows one selector to inherit the styles of another. - Why: It helps to avoid code duplication. In this case, the
.card-one,.card-two, and.card-threeclasses extend the base.cardclass, inheriting its common styles.
- Purpose: The
- Customization:
- Purpose: Customization is applied to specific instances of cards.
- Why: This allows for unique styling for individual cards while still leveraging the common styles from the base
.cardclass. For example, different background and hover colors are assigned to each card.
- Flexbox:
- Purpose: Flexbox is used for layout purposes, ensuring a centered and responsive design.
- Why: It simplifies the alignment and distribution of elements within the
.container. The use ofdisplay: flex;along with alignment properties helps achieve a centered layout.
In summary, the tools used in this SASS code contribute to code organization, maintainability, and reusability. Variables maintain consistency, mixins enable reusable animations, nesting aids readability, extend avoids duplication, and customization allows for flexibility in styling. The combination of these tools enhances the overall efficiency and scalability of the stylesheet.
Unit 2: UX/UI Through JQuery & CRUD
What is UX?
-
UX is the shortform of user experience; a standard of understanding the usability of a product and optimise it based on data recived from users.
-
UX is a necessity in all industries since collecting UX and improving the product based on it increases the popularity of the product on the market, increasing profits of the company or collaboration.
What is jQuery?
-
jQuery is a lightweight, “write less, do more”, JavaScript library. The purpose of jQuery is to make it much easier to use JavaScript on your site and it simplifies many tasks that require many lines of JavaScript code to accomplish, wraping them into methods that you can call with a single line of code.
-
jQuery also simplifies a lot of the complicated things from JavaScript, like AJAX calls and DOM manipulation.
-
With jQuery you select (query) HTML elements and perform “actions” on them.
-
All jQuery methods begin inside a document ready event
Popcorn Hack: Name 3 other event HTML events
- hover
- onpress
- onreload
What Does CRUD Stand For?
- Answer this as a Popcorn Hack: Create, Read, Update, Delete
Popcorn Hack: Complete the Jquery and JavaScript code: This represents a website for buying dogs. The API contains an id, name, price, and breed for each dog. Display them all as html using jQuery.
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
.dog {
border: 1px solid #ddd;
margin-bottom: 20px;
padding: 20px;
border-radius: 5px;
}
.price {
color: #007BFF;
}
</style>
</head>
<body>
<div id="dogs"></div>
<script>
// Fake API function
function getAPI() {
return [
{id: 1, name: 'Max', price: '$1000', breed: 'Golden Retriever'},
{id: 2, name: 'Bella', price: '$800', breed: 'Labrador Retriever'},
{id: 3, name: 'Charlie', price: '$1200', breed: 'German Shepherd'}
];
}
$(document).ready(function(){
var dogs = getAPI();
$.each(dogs, function(i, dog) {
var dogHtml = '<div class="dog"><h2>Dog ' + dog.id + '</h2><p>Name: ' + dog.name + '</p><p>Breed: ' + dog.breed + '</p><p class="price">Price: ' + dog.price + '</p></div>';
$('#dogs').append(dogHtml);
});
});
</script>
</body>
In the following example, write in one of the comments where the selector is (popcorn hack ~ raise hand when found)
$(document).ready(function(){ //
$("button").click(function(){ // Selector
$("p").hide(); // Selector
}); //
}); //
All Hacks Done
Unit 3: ThymeLeaf
Popcorn Hack:
Summarize the key features of Thymeleaf and explain why it is preferred for server-side rendering in Spring applications.
Without Thymeleaf, we make projects with two parts, a frontend and a backend. With Thymeleaf, you can use server-side techniques to make it so that your frontend is on the same project as your backend, making the project size more optimal.
Popcorn Hacks:
What do you think the Model model means and why is it important?
- Answer Here: The model parameter is a database or part of a database, represented as a class in the backend, that will store data such as a username, age, and email that can later be pulled by the frontend.
PopCorn Hack:
List 3 more Attributes of Thymleaf in the Frontend:
- th:switch (similar to switch-case functionality in Java)
- th:fragment (similar to div elemeent in HTML)
- th:object (similar to instantiation in Java)
Hacks
Create a controller that uses the model function, then in html use the methods in Thymeleaf that were taught. Extra Points For creativity.
Java:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class ProductController {
@GetMapping("/product")
public String getProduct(Model model) {
String productName = "Smartphone";
double price = 599.99;
String description = "High-end smartphone with advanced features";
String imageUrl = "https://example.com/smartphone-image.jpg";
model.addAttribute("productName", productName);
model.addAttribute("price", price);
model.addAttribute("description", description);
model.addAttribute("imageUrl", imageUrl);
return "productDetails";
}
}
HTML:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Product Details</title>
</head>
<body>
<h1 th:text="${productName}"></h1>
<div>
<img th:src="${imageUrl}" alt="Product Image" style="max-width: 300px;"/>
</div>
<p th:text="'Price: $' + ${price}"></p>
<p th:text="${description}"></p>
</body>
</html>
I committed my backend hacks to a branch that you can find here.
Unit 4: HashMap
Hashing
- HashMap uses a hash function to map keys to their respective buckets.
- A good hash function generates a unique hash code for each key, but collisions can still occur.
- The hash map in Java does not maintain insertion order.
Key and Value Types
- HashMap allows any non-null object as a key and any object (including null) as a value.
- For a class to be used as a key, it must implement the get and put methods.
Iteration
- HashMap provides methods like keySet(), values(), and entrySet() for iterating over key-value pairs.
- The entrySet() method returns a Set view of key-value pairs, allowing iteration and moderation.
Popcorn Hack 1 Declare a Hashmap, and then research 5 different HashMap method which were not listed above and use them in your code just like the one above.
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("Paaras", "Purohit");
hashMap.put("Rachit", "Jaiswal");
hashMap.put("Varaprasad", "Nibhanupudi");
hashMap.put("Harshavaratan", "Gnanam");
hashMap.put("Aditya", "Nawendhar");
hashMap.remove("Paaras");
String lastName = hashMap.get("Rachit");
boolean isEmpty = hashMap.isEmpty();
int size = hashMap.size();
Collection values = hashMap.values();
System.out.println(lastName);
System.out.println(isEmpty);
System.out.println(size);
System.out.println(values);
Jaiswal
false
4
[Gnanam, Nawendhar, Jaiswal, Nibhanupudi]
Popcorn Hack 2 (Extra Credit) Try to find a different way to traverse a HashMap (Hint: try using a forEach function)
import java.util.HashMap;
import java.util.Map;
public class HashMapTraversalExample {
public static void main(String[] args) {
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("John", 25);
hashMap.put("Alice", 30);
hashMap.put("Bob", 28);
hashMap.put("Eve", 22);
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
String key = entry.getKey();
Integer value = entry.getValue();
System.out.println("Key: " + key + ", Value: " + value);
}
}
}
HashMapTraversalExample.main(null);
Key: Bob, Value: 28
Key: Eve, Value: 22
Key: Alice, Value: 30
Key: John, Value: 25
Popcorn HACK 3 (Shaurya):
import java.util.HashMap;
import java.util.Map;
public class HashMapTest {
public static void main(String[] args) {
// Create a new HashMap with Integer keys and String values
Map<Integer, String> myMap = new HashMap<>();
// Add some key-value pairs to the HashMap
myMap.put(1, "Apple");
myMap.put(2, "Banana");
myMap.put(3, "Cherry");
// Fill in the blanks: Retrieve and print the value for key 2
String valueForKey2 = myMap.get(2);
System.out.println("Value for key 2: " + valueForKey2);
// Fill in the blanks: Check if the HashMap contains key 4
boolean containsKey4 = myMap.containsKey(4);
System.out.println("Does the map contain key 4? " + containsKey4);
// Fill in the blanks: Remove the entry with key 1 from the HashMap
myMap.remove(1);
// Print the updated contents of the HashMap
System.out.println("Updated HashMap:");
for (Map.Entry<Integer, String> entry : myMap.entrySet()) {
System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue());
}
}
}
HashMapTest.main(null);
Popcorn HACK 4 - Quiz (Shaurya)
Multiple Choice:
Question 1: Hashing in HashMap
What is the primary purpose of a hash function in a HashMap?
- A) To encrypt the keys
- B) To map keys to corresponding buckets
- C) To validate the keys
- D) To generate random numbers
Question 2: Performance of HashMap
What is the time complexity of the get() and put() operations in a well-distributed HashMap?
- A) O(log n)
- B) O(n)
- C) O(1)
- D) O(n^2)
Free Response:
Question 3: Key and Value Types in HashMap
Describe the types of objects that can be used as keys and values in a HashMap. Additionally, explain the methods that a class should implement if used as a key.
For basic cases, primitive types are used as keys and values in a HashMap. However, any data type of any type of class can be used as a key and value. If a class is used as a key or value, it needs to use the constructor method.
Question 4: Iteration in HashMap
Provide brief explanations for two methods in HashMap that can be used to iterate over its key-value pairs.
There are more than two. You can use pretty much any type of loop. The best two to use are either a for or for-each loop, because using them to iterate through a list is more efficient to code with.
Question 5: Thread Safety in HashMap
Explain why HashMap is not thread-safe and what issues might arise when multiple threads access the same HashMap instance concurrently. Suggest an alternative class that can be used for concurrent access and explain its benefits.
Based on the lesson, the type of HashMap you would want to use for threads is ConcurrentHashMap, which is built to handle asynchronous and concurrent threading, unlike the regular HashMap.
Java for Hack:
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class SportsTeamRoster {
public static void main(String[] args) {
Map<Integer, Player> roster = new HashMap<>();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("1. Add new player");
System.out.println("2. Update player information");
System.out.println("3. Search for player by jersey number");
System.out.println("4. Exit");
System.out.print("Enter your choice: ");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
addPlayer(roster, scanner);
break;
case 2:
updatePlayer(roster, scanner);
break;
case 3:
searchPlayerByJerseyNumber(roster, scanner);
break;
case 4:
System.out.println("Exiting the program.");
System.exit(0);
break;
default:
System.out.println("Invalid choice. Please enter a valid option.");
}
}
}
private static void addPlayer(Map<Integer, Player> roster, Scanner scanner) {
System.out.print("Enter player name: ");
String name = scanner.nextLine();
System.out.print("Enter player position: ");
String position = scanner.nextLine();
System.out.print("Enter player jersey number: ");
int jerseyNumber = scanner.nextInt();
Player player = new Player(name, position, jerseyNumber);
roster.put(jerseyNumber, player);
System.out.println("Player added successfully!");
}
private static void updatePlayer(Map<Integer, Player> roster, Scanner scanner) {
System.out.print("Enter player's jersey number to update: ");
int jerseyNumber = scanner.nextInt();
if (roster.containsKey(jerseyNumber)) {
System.out.print("Enter new player name: ");
String name = scanner.nextLine();
System.out.print("Enter new player position: ");
String position = scanner.nextLine();
Player updatedPlayer = new Player(name, position, jerseyNumber);
roster.put(jerseyNumber, updatedPlayer);
System.out.println("Player information updated successfully!");
} else {
System.out.println("Player not found with jersey number " + jerseyNumber);
}
}
private static void searchPlayerByJerseyNumber(Map<Integer, Player> roster, Scanner scanner) {
System.out.print("Enter player's jersey number to search: ");
int jerseyNumber = scanner.nextInt();
if (roster.containsKey(jerseyNumber)) {
Player player = roster.get(jerseyNumber);
System.out.println("Player found:");
System.out.println(player);
} else {
System.out.println("Player not found with jersey number " + jerseyNumber);
}
}
static class Player {
private String name;
private String position;
private int jerseyNumber;
public Player(String name, String position, int jerseyNumber) {
this.name = name;
this.position = position;
this.jerseyNumber = jerseyNumber;
}
@Override
public String toString() {
return "Name: " + name + ", Position: " + position + ", Jersey Number: " + jerseyNumber;
}
}
}
SportsTeamRoster.main(null);
1. Add new player
2. Update player information
3. Search for player by jersey number
4. Exit
Enter your choice: Enter player name: Enter player position: Enter player jersey number: Player added successfully!
1. Add new player
2. Update player information
3. Search for player by jersey number
4. Exit
Enter your choice: Exiting the program.
The Kernel crashed while executing code in the the current cell or a previous cell. Please review the code in the cell(s) to identify a possible cause of the failure. Click <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. View Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details.
I didn’t and won’t do the Collections hacks due to the lesson being cut off and the lesson itself not being too clear on it. To make up for this, I will be practicing these concepts in CollegeBoard as well as doing my own research into Collections to implement them in my project.