Welcome to Module 5, @name! Darwin here with a new chapter - Web Development!
So far you've been working exclusively with the backend - Python, databases, API. Now it's time to learn the frontend - the user interface that visitors see on your website! 🌐🎨
Safari Analogy: The backend is like the research laboratory behind the scenes - Python, databases, logic. The frontend is the tourist information center - colorful boards, interactive maps, "See more about lions" buttons! 📊🖼️
As a Python developer you'll be building web applications - so you need frontend basics!
Frontend = HTML + CSS + JavaScript
Analogy: HTML is the dinosaur skeleton, CSS is the skin and colors, JavaScript is the muscles that allow movement! 🦴🎨💪
HTML (HyperText Markup Language) is a markup language defining the structure of a page.
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <meta name="viewport" content="width=device-width, initial-scale=1.0">
6 <title>Safari Database</title>
7</head>
8<body>
9 <h1>Welcome to Safari Database</h1>
10 <p>Species data management system</p>
11</body>
12</html>Structure:
<!DOCTYPE html> - document type declaration<html> - root element<head> - metadata (title, charset, styles)<body> - visible content on the page1<!-- Headings (h1 most important, h6 least) -->
2<h1>Safari Database</h1>
3<h2>African Species</h2>
4<h3>Lion (Panthera leo)</h3>
5
6<!-- Paragraph -->
7<p>The lion is Africa's largest predator...</p>
8
9<!-- Link -->
10<a href="/species/lion">See lion details</a>
11
12<!-- Image -->
13<img src="/static/images/lion.jpg" alt="Lion in Serengeti">
14
15<!-- Unordered list -->
16<ul>
17 <li>Lion</li>
18 <li>Elephant</li>
19 <li>Cheetah</li>
20</ul>
21
22<!-- Ordered list -->
23<ol>
24 <li>Fetch data</li>
25 <li>Process</li>
26 <li>Display</li>
27</ol>
28
29<!-- Button -->
30<button>Add observation</button>
31
32<!-- Form -->
33<form action="/add-species" method="POST">
34 <label for="name">Name:</label>
35 <input type="text" id="name" name="name" required>
36
37 <label for="population">Population:</label>
38 <input type="number" id="population" name="population">
39
40 <button type="submit">Save</button>
41</form>
42
43<!-- Table -->
44<table>
45 <thead>
46 <tr>
47 <th>Species</th>
48 <th>Population</th>
49 <th>Habitat</th>
50 </tr>
51 </thead>
52 <tbody>
53 <tr>
54 <td>Lion</td>
55 <td>120</td>
56 <td>Savanna</td>
57 </tr>
58 <tr>
59 <td>Elephant</td>
60 <td>450</td>
61 <td>Savanna</td>
62 </tr>
63 </tbody>
64</table>
65
66<!-- Div - block container -->
67<div class="species-card">
68 <h3>Lion</h3>
69 <p>Population: 120</p>
70</div>
71
72<!-- Span - inline container -->
73<p>Status: <span class="endangered">Endangered</span></p>1<!-- class - CSS class -->
2<div class="species-card endangered">...</div>
3
4<!-- id - unique identifier -->
5<div id="lion-details">...</div>
6
7<!-- data-* - custom data attributes -->
8<div class="species" data-id="123" data-population="120">...</div>
9
10<!-- href - link -->
11<a href="https://example.com">Link</a>
12
13<!-- src, alt - images -->
14<img src="image.jpg" alt="Image description">
15
16<!-- placeholder, required - forms -->
17<input type="text" placeholder="Enter name" required>CSS (Cascading Style Sheets) defines the appearance of HTML elements.
1<!-- 1. Inline CSS (not recommended) -->
2<p style="color: green; font-size: 18px;">Text</p>
3
4<!-- 2. Internal CSS (in <head>) -->
5<head>
6 <style>
7 p {
8 color: green;
9 font-size: 18px;
10 }
11 </style>
12</head>
13
14<!-- 3. External CSS (recommended) -->
15<head>
16 <link rel="stylesheet" href="/static/css/style.css">
17</head>1/* Tag selector */
2p {
3 color: #333;
4 line-height: 1.6;
5}
6
7/* Class selector */
8.species-card {
9 border: 2px solid #ddd;
10 padding: 20px;
11 margin: 10px;
12 border-radius: 8px;
13}
14
15/* ID selector */
16#lion-details {
17 background-color: #f9f9f9;
18}
19
20/* Attribute selector */
21[data-endangered="true"] {
22 border-color: red;
23}
24
25/* Child selector */
26.species-card > h3 {
27 color: #2c5f2d;
28}
29
30/* Hover state */
31button:hover {
32 background-color: #45a049;
33 cursor: pointer;
34}1/* Colors */
2.endangered {
3 color: red;
4 background-color: #ffe6e6;
5}
6
7/* Typography */
8h1 {
9 font-family: 'Arial', sans-serif;
10 font-size: 32px;
11 font-weight: bold;
12 text-align: center;
13}
14
15/* Box model */
16.species-card {
17 width: 300px;
18 height: 200px;
19 padding: 20px; /* Inner spacing */
20 margin: 10px; /* Outer spacing */
21 border: 2px solid #ddd;
22}
23
24/* Flexbox - layout */
25.species-list {
26 display: flex;
27 flex-wrap: wrap;
28 gap: 20px;
29 justify-content: center;
30}
31
32/* Grid - layout */
33.species-grid {
34 display: grid;
35 grid-template-columns: repeat(3, 1fr);
36 gap: 20px;
37}1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Safari Database</title>
6 <style>
7 body {
8 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
9 background-color: #f4f1de;
10 margin: 0;
11 padding: 20px;
12 }
13
14 h1 {
15 text-align: center;
16 color: #2c5f2d;
17 }
18
19 .species-list {
20 display: flex;
21 flex-wrap: wrap;
22 gap: 20px;
23 justify-content: center;
24 max-width: 1200px;
25 margin: 0 auto;
26 }
27
28 .species-card {
29 background-color: white;
30 border: 2px solid #e0afa0;
31 border-radius: 12px;
32 padding: 20px;
33 width: 280px;
34 box-shadow: 0 4px 6px rgba(0,0,0,0.1);
35 transition: transform 0.2s;
36 }
37
38 .species-card:hover {
39 transform: translateY(-5px);
40 box-shadow: 0 6px 12px rgba(0,0,0,0.15);
41 }
42
43 .species-card.endangered {
44 border-color: #d62828;
45 border-width: 3px;
46 }
47
48 .species-name {
49 color: #2c5f2d;
50 font-size: 24px;
51 margin-top: 0;
52 }
53
54 .badge {
55 display: inline-block;
56 padding: 4px 8px;
57 border-radius: 4px;
58 font-size: 12px;
59 font-weight: bold;
60 }
61
62 .badge-endangered {
63 background-color: #d62828;
64 color: white;
65 }
66
67 .badge-safe {
68 background-color: #4caf50;
69 color: white;
70 }
71 </style>
72</head>
73<body>
74 <h1>🦁 Safari Database 🐘</h1>
75
76 <div class="species-list">
77 <div class="species-card endangered">
78 <h3 class="species-name">Lion</h3>
79 <p><strong>Population:</strong> 120 individuals</p>
80 <p><strong>Habitat:</strong> Savanna</p>
81 <span class="badge badge-endangered">Endangered</span>
82 </div>
83
84 <div class="species-card endangered">
85 <h3 class="species-name">African Elephant</h3>
86 <p><strong>Population:</strong> 450 individuals</p>
87 <p><strong>Habitat:</strong> Savanna</p>
88 <span class="badge badge-endangered">Endangered</span>
89 </div>
90
91 <div class="species-card">
92 <h3 class="species-name">Giraffe</h3>
93 <p><strong>Population:</strong> 850 individuals</p>
94 <p><strong>Habitat:</strong> Savanna</p>
95 <span class="badge badge-safe">Safe</span>
96 </div>
97 </div>
98</body>
99</html>JavaScript adds interaction - reactions to clicks, animations, dynamic changes.
1<!DOCTYPE html>
2<html>
3<head>
4 <title>Safari JS</title>
5</head>
6<body>
7 <h1 id="title">Safari Database</h1>
8 <button onclick="changeName()">Change title</button>
9 <button id="addBtn">Add species</button>
10
11 <div id="species-count">Species: 0</div>
12
13 <script>
14 // Variables
15 let speciesCount = 3;
16 const databaseName = "Safari DB";
17
18 // Function
19 function changeName() {
20 document.getElementById("title").textContent = "🦁 New title!";
21 }
22
23 // Event listener (better way than onclick)
24 document.getElementById("addBtn").addEventListener("click", function() {
25 speciesCount++;
26 document.getElementById("species-count").textContent = `Species: ${speciesCount}`;
27 });
28
29 // Console log
30 console.log("Page loaded!");
31
32 // Fetch data from API
33 fetch("/api/species")
34 .then(response => response.json())
35 .then(data => {
36 console.log("Data fetched:", data);
37 })
38 .catch(error => console.error("Error:", error));
39 </script>
40</body>
41</html>1// Get element
2const title = document.getElementById("title");
3const cards = document.querySelectorAll(".species-card");
4const firstCard = document.querySelector(".species-card");
5
6// Change content
7title.textContent = "New title";
8title.innerHTML = "<strong>Bold title</strong>";
9
10// Change styles
11title.style.color = "red";
12title.style.fontSize = "32px";
13
14// Add/remove classes
15title.classList.add("highlight");
16title.classList.remove("old-class");
17title.classList.toggle("active");
18
19// Create new element
20const newCard = document.createElement("div");
21newCard.className = "species-card";
22newCard.innerHTML = \`
23 <h3>Cheetah</h3>
24 <p>Population: 7100</p>
25\`;
26
27// Add to page
28document.querySelector(".species-list").appendChild(newCard);
29
30// Remove element
31const cardToRemove = document.querySelector(".species-card");
32cardToRemove.remove();1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>Interactive Safari</title>
6 <style>
7 body {
8 font-family: Arial, sans-serif;
9 max-width: 800px;
10 margin: 0 auto;
11 padding: 20px;
12 background-color: #f4f1de;
13 }
14
15 .add-form {
16 background: white;
17 padding: 20px;
18 border-radius: 8px;
19 margin-bottom: 20px;
20 }
21
22 input, button {
23 padding: 10px;
24 margin: 5px;
25 border-radius: 4px;
26 border: 1px solid #ddd;
27 }
28
29 button {
30 background-color: #2c5f2d;
31 color: white;
32 cursor: pointer;
33 border: none;
34 }
35
36 button:hover {
37 background-color: #45a049;
38 }
39
40 .species-card {
41 background: white;
42 padding: 15px;
43 margin: 10px 0;
44 border-radius: 8px;
45 border-left: 4px solid #2c5f2d;
46 display: flex;
47 justify-content: space-between;
48 align-items: center;
49 }
50
51 .delete-btn {
52 background-color: #d62828;
53 padding: 8px 12px;
54 font-size: 14px;
55 }
56
57 .delete-btn:hover {
58 background-color: #9d0208;
59 }
60 </style>
61</head>
62<body>
63 <h1>🦁 Safari Database - Interactive List</h1>
64
65 <div class="add-form">
66 <h3>Add new species</h3>
67 <input type="text" id="speciesName" placeholder="Species name">
68 <input type="number" id="speciesPopulation" placeholder="Population">
69 <button id="addBtn">Add</button>
70 </div>
71
72 <div id="speciesList"></div>
73
74 <p><strong>Total species:</strong> <span id="totalCount">0</span></p>
75
76 <script>
77 // Application state
78 let species = [
79 { id: 1, name: "Lion", population: 120 },
80 { id: 2, name: "Elephant", population: 450 },
81 { id: 3, name: "Cheetah", population: 7100 }
82 ];
83 let nextId = 4;
84
85 // Render list
86 function renderSpecies() {
87 const listElement = document.getElementById("speciesList");
88 listElement.innerHTML = "";
89
90 species.forEach(spec => {
91 const card = document.createElement("div");
92 card.className = "species-card";
93 card.innerHTML = `94 <div>
95 <strong>${spec.name}</strong> - Population: ${spec.population} individuals
96 </div>
97 <button class="delete-btn" onclick="deleteSpecies(${spec.id})">Delete</button>
98`;
99 listElement.appendChild(card);
100 });
101
102 // Update counter
103 document.getElementById("totalCount").textContent = species.length;
104 }
105
106 // Add species
107 document.getElementById("addBtn").addEventListener("click", function() {
108 const nameInput = document.getElementById("speciesName");
109 const popInput = document.getElementById("speciesPopulation");
110
111 const name = nameInput.value.trim();
112 const population = parseInt(popInput.value);
113
114 if (name && population) {
115 species.push({
116 id: nextId++,
117 name: name,
118 population: population
119 });
120
121 // Clear form
122 nameInput.value = "";
123 popInput.value = "";
124
125 // Re-render
126 renderSpecies();
127 } else {
128 alert("Please fill in all fields!");
129 }
130 });
131
132 // Delete species
133 function deleteSpecies(id) {
134 if (confirm("Are you sure you want to delete this species?")) {
135 species = species.filter(s => s.id !== id);
136 renderSpecies();
137 }
138 }
139
140 // Initial render
141 renderSpecies();
142 </script>
143</body>
144</html>HTML → Structure ("what") CSS → Appearance ("how it looks") JavaScript → Interaction ("what happens")
1<!-- HTML - structure -->
2<button id="likeBtn" class="btn">Like it!</button>
3
4<!-- CSS - appearance -->
5<style>
6 .btn {
7 background-color: #4CAF50;
8 color: white;
9 padding: 15px 32px;
10 border: none;
11 border-radius: 4px;
12 cursor: pointer;
13 }
14 .btn.liked {
15 background-color: #f44336;
16 }
17</style>
18
19<!-- JavaScript - interaction -->
20<script>
21 document.getElementById("likeBtn").addEventListener("click", function() {
22 this.classList.toggle("liked");
23 this.textContent = this.classList.contains("liked")
24 ? "Don't like :("
25 : "Like it!";
26 });
27</script>Minimum frontend for Flask:
You don't have to be a frontend expert - Flask with Jinja2 generates HTML for you!
What you'll do in Flask:
CSS Frameworks (ready-made styles) will help you quickly create nice interfaces:
In this lesson you learned:
Final Safari Analogy: The frontend is the park's information center - colorful boards (CSS), trail maps (HTML), interactive "See more" buttons (JavaScript). The backend is the laboratory behind the scenes (Python + databases)! 🏛️🔬
In the next lesson Darwin will show you Flask - a microframework for building web applications in Python! 🐍🌐