THE UNIVERSITY OF DODOMA
COLLEGE OF INFORMATICS AND VIRTUAL EDUCATION
DEPARTMENT OF COMPUTER SCIENCE AND ENGINEERING
UNDERGRADUATE UNIVERSITY EXAMINATIONS
FIRST SEMESTER 2018/2019
Course Code: CS 312
Course Title: INTERNET PROGRAMMING AND APPLICATIONS
INSTRUCTIONS:
- Closed Book Examination.
- This examination consists SEVEN questions.
- Answer all questions in Section A and only two (2) questions from Section B.
- Use the user Cs312 and password 312Pass to access the database udom_sr.
- The IP address for the PHP server is 192.168.2.1 and MySQL server is 192.168.2.4.
- All University of Dodoma examination regulations apply.
SECTION A: (40 Marks)
Question One
Choose the letter of the most correct answer. (1 Mark Each)
i. If no expiration time is explicitly set for a cookie, what happens to it?
(a) It expires right away (b) It never expires (c) It is not set (d) It expires at the end of the user’s browser session (e) It expires only if the script doesn’t create a server-side session
Answer (Click to show)
(d) It expires at the end of the user’s browser session
ii. Under what circumstance is it impossible to assign a default value to a parameter while declaring a function?
(a) When the parameter is Boolean. (b) When the function is being declared as a member of a class. (c) When the parameter is being declared as passed by reference. (d) When the function contains only one parameter (e) Never
Answer (Click to show)
(c) When the parameter is being declared as passed by reference
iii. By default, PHP stores session data in
(a) The filesystem (b) A database (c) Virtual memory (d) Shared memory (e) None of the above
Answer (Click to show)
(a) The filesystem
iv. Which of the following will not combine strings s2 into a single string?
(a) s2 (b) “s2” (c) s2 (d) implode("", array(s2)) (e) All of the above combine strings
Answer (Click to show)
(a) s2
v. Given a variable $email containing the string user@example.com, which of the following statements would extract the string example.com?
(a) substr(email,”@”)); (b) strstr(email,”@”) (d) substr(email,”@”)+1); (e) strpos($email,”@”);
Answer (Click to show)
(d) substr(email,”@”)+1);
vi. What is the correct CSS syntax for making all the <p> elements bold?
(a) p {text-size:bold} (b) p {font-weight:bold} (c) style:bold (d) p{font:bold} (e) All of the above.
Answer (Click to show)
(b) p {font-weight:bold}
vii. How do you make a list that lists its items with squares?
(a) type: square (b) list-style-type: square (c) list-type: square (d) style-list: square (e) style-list-type: square
Answer (Click to show)
(b) list-style-type: square
viii. Under what circumstance is it impossible to assign a default value to a parameter while declaring a function?
(a) When the parameter is Boolean (b) When the function is being declared as a member of a class (c) When the parameter is being declared as passed by reference (d) When the function contains only one parameter (e) Never
Answer (Click to show)
(c) When the parameter is being declared as passed by reference
ix. Which property in JavaScript would you use to redirect visitor to another page?
(a) window.location.href (b) document.href (c) java.redirect.url (d) link.redirect.href (e) header(‘Location: url’)
Answer (Click to show)
(a) window.location.href
x. Run-time inclusion of a PHP script is performed using the _____ construct, while compile-time inclusion of PHP scripts is performed using the _____ construct.
(a) include_once, include (b) require, include (c) require_once, include (d) include, require (e) All of the above are correct
Answer (Click to show)
(d) include, require
Question Two
What will be the output of the following script? (10 Marks)
<?php
$array = array(1,2,3,5,8,13,21,34,55);
$sum = 0;
for($i = 0; $i < 5; $i++) {
$sum += $array[$array[$i]];
}
echo $sum;
?>Answer (Click to show)
Step-by-step execution:
$i i] array[$i]] Calculation $sum 0 1 $array[1] = 2 $sum = 0 + 2 2 1 2 $array[2] = 3 $sum = 2 + 3 5 2 3 $array[3] = 5 $sum = 5 + 5 10 3 5 $array[5] = 13 $sum = 10 + 13 23 4 8 $array[8] = 55 $sum = 23 + 55 78 Output:
78
Question Three
Write CSS rules for the following: (2 Marks Each)
i. Write a CSS rule that makes all text 1.5 times larger than the base font of the system and color the text red.
Answer (Click to show)
body { font-size: 1.5em; color: red; } /* Or using universal selector */ * { font-size: 1.5em; color: red; } /* Or using root em (rem) for better accessibility */ html { font-size: 1.5rem; color: red; }
ii. Write a CSS rule that places a background image halfway down the page, tiling it horizontally. The image should remain in place when the user scrolls up or down.
Answer (Click to show)
body { background-image: url('image.jpg'); background-repeat: repeat-x; /* Tile horizontally */ background-position: center 50%; /* Halfway down the page */ background-attachment: fixed; /* Remain in place when scrolling */ } /* Alternative with shorthand */ body { background: url('image.jpg') repeat-x fixed center 50%; }
iii. Write a CSS rule that gives all h1 and h2 elements a padding of 0.5ems, dashed border style and a margin of 0.5 ems.
Answer (Click to show)
h1, h2 { padding: 0.5em; border-style: dashed; border-width: 1px; /* Specify border width (optional) */ border-color: black; /* Specify border color (optional) */ margin: 0.5em; } /* Or with border shorthand */ h1, h2 { padding: 0.5em; border: 1px dashed black; margin: 0.5em; }
iv. Write a CSS rule that changes the color of all elements containing attribute class=“green-Move” to green and shift them down 25 pixels and right 15 pixels.
Answer (Click to show)
.green-Move { color: green; position: relative; top: 25px; left: 15px; } /* Alternative using transform */ .green-Move { color: green; transform: translate(15px, 25px); }
v. Write a layout template that contains a header and two columns. Use divs for each layout component, and use float to line up the columns side by side. Give each component a border and/or a background color so you can see where your divs are.
Answer (Click to show)
<!DOCTYPE html> <html> <head> <title>Two-Column Layout</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: Arial, sans-serif; padding: 20px; background-color: #f0f0f0; } .container { max-width: 1200px; margin: 0 auto; overflow: hidden; } .header { background-color: #4CAF50; color: white; padding: 20px; text-align: center; border: 2px solid #2E7D32; margin-bottom: 10px; } .column { float: left; padding: 15px; min-height: 300px; border: 2px solid #333; } .left-column { width: 30%; background-color: #2196F3; color: white; border-color: #0D47A1; } .right-column { width: 70%; background-color: #FF9800; color: white; border-color: #BF360C; } .footer { background-color: #9C27B0; color: white; padding: 15px; text-align: center; border: 2px solid #4A148C; margin-top: 10px; clear: both; } .clearfix::after { content: ""; display: table; clear: both; } </style> </head> <body> <div class="container"> <div class="header"> <h2>Header Section</h2> </div> <div class="column left-column"> <h3>Left Column (30%)</h3> <p>This is the left column with blue background.</p> </div> <div class="column right-column"> <h3>Right Column (70%)</h3> <p>This is the right column with orange background.</p> </div> <div class="footer"> <p>Footer Section - cleared float</p> </div> </div> </body> </html>
Question Four
Find SIX (6) errors in the following JavaScript code and rewrite the correct one. (10 Marks)
<script language="javascript">
var test1= prompt("Insert test 1 marks (0-50)","");
var test2 = prompt("Insert test 2 marks (0-50)","");
marks = parseFloat(test1) + parseFloat(test1);
if ((marks>=80) (marks<=100)){
document.write("Excellent");
}
elseif ((marks>=60) && (marks<=79)){
document.write("Good");
}
else if ((marks>=30) && (marks<=59)){
document.write("Intermediate");
}
{
document.write(Try again);
}
</script>Answer (Click to show)
Six Errors Identified:
- Error 1: Missing operator between conditions in first if statement
- Incorrect:
if ((marks>=80) (marks<=100))- Correct:
if ((marks>=80) && (marks<=100))- Error 2:
elseifshould be written aselse if(with space)
- Incorrect:
elseif- Correct:
else if- Error 3: Wrong variable used in calculation
- Incorrect:
marks = parseFloat(test1) + parseFloat(test1);(adds test1 twice)- Correct:
marks = parseFloat(test1) + parseFloat(test2);(adds test1 and test2)- Error 4: Missing condition for the last else block
- Incorrect:
{ document.write(Try again); }(else block without else if condition)- Correct: Should be
else { document.write("Try again"); }- Error 5: String not quoted in document.write
- Incorrect:
document.write(Try again);(Try again treated as variable)- Correct:
document.write("Try again");- Error 6: No handling for marks below 30 (incomplete condition coverage)
- The code doesn’t handle marks below 30
- Should add condition for marks < 30
Corrected Code:
<script language="javascript"> var test1 = prompt("Insert test 1 marks (0-50)",""); var test2 = prompt("Insert test 2 marks (0-50)",""); var marks = parseFloat(test1) + parseFloat(test2); if ((marks >= 80) && (marks <= 100)) { document.write("Excellent"); } else if ((marks >= 60) && (marks <= 79)) { document.write("Good"); } else if ((marks >= 30) && (marks <= 59)) { document.write("Intermediate"); } else { document.write("Try again"); } </script>
SECTION B (60 Marks)
Attempt ANY TWO questions from this section.
Question Five
The University of Dodoma wants to modify the Continuous Assessment (CA) registration form so that it appears like the one shown in figure 1. The Course instructor can use it to register CA for more than two students by clicking the Add Row button to append the row. The appended row may be deleted by clicking the delete Row button. You are required to create a form using XHTML, Ajax and PHP, the submit button should save the information in the ca_result table in the database udom_sr. [30 Marks]
Table Structure:
tbl_student (student_id, registration_no)tbl_ca_result (student_id, test_one, test_two)
Figure 1: CA registration form
| # | Registration No | Test One (0-50) | Test Two (0-50) | Assignment | Total |
|---|---|---|---|---|---|
| 1 | T/UDOM/2010/03999 | 80 | 70 | 60 | 210 |
| 2 |
Answer (Click to show)
Complete Solution: CA Registration System with Ajax
1. Database Connection File: config.php
<?php // Database configuration $db_host = '192.168.2.4'; // MySQL server IP $db_user = 'Cs312'; $db_pass = '312Pass'; $db_name = 'udom_sr'; // Create connection $conn = new mysqli($db_host, $db_user, $db_pass, $db_name); // Check connection if ($conn->connect_error) { die("Connection failed: " . $conn->connect_error); } // Set charset to UTF-8 $conn->set_charset("utf8"); ?>2. Main HTML Form: ca_registration.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>CA Registration Form</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; } .container { max-width: 1200px; margin: 0 auto; background-color: white; border-radius: 15px; padding: 30px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); } h1 { color: #333; margin-bottom: 20px; text-align: center; } h1 span { color: #667eea; } .form-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 15px; border-radius: 10px 10px 0 0; margin-bottom: 20px; } .table-container { overflow-x: auto; margin-bottom: 20px; border: 1px solid #e0e0e0; border-radius: 10px; } table { width: 100%; border-collapse: collapse; background-color: white; } th { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 12px; font-weight: 600; } td { padding: 10px; border-bottom: 1px solid #e0e0e0; } input[type="text"] { width: 100%; padding: 8px; border: 2px solid #e0e0e0; border-radius: 5px; font-size: 14px; } input[type="text"]:focus { outline: none; border-color: #667eea; } .btn { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; font-size: 14px; margin: 5px; transition: transform 0.3s; } .btn:hover { transform: scale(1.05); } .btn-delete { background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%); } .btn-container { text-align: center; margin: 20px 0; } .total { font-weight: bold; color: #4CAF50; } .loading { display: none; text-align: center; padding: 20px; } .spinner { border: 4px solid #f3f3f3; border-top: 4px solid #667eea; border-radius: 50%; width: 40px; height: 40px; animation: spin 1s linear infinite; margin: 0 auto; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .message { padding: 10px; border-radius: 5px; margin: 10px 0; display: none; } .success { background-color: #4CAF50; color: white; } .error { background-color: #f44336; color: white; } </style> <!-- jQuery for Ajax --> <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> </head> <body> <div class="container"> <h1>📝 <span>CA Registration System</span></h1> <div class="form-header"> <h3>Continuous Assessment Registration Form</h3> </div> <div id="message" class="message"></div> <div class="table-container"> <table id="caTable"> <thead> <tr> <th>#</th> <th>Registration No</th> <th>Test One (0-50)</th> <th>Test Two (0-50)</th> <th>Assignment</th> <th>Total</th> <th>Action</th> </tr> </thead> <tbody id="tableBody"> <tr id="row1"> <td>1</td> <td><input type="text" name="reg_no[]" class="reg-no" value="T/UDOM/2010/03999" placeholder="Enter Reg No"></td> <td><input type="text" name="test_one[]" class="test-one" value="80" onkeyup="calculateTotal(this)"></td> <td><input type="text" name="test_two[]" class="test-two" value="70" onkeyup="calculateTotal(this)"></td> <td><input type="text" name="assignment[]" class="assignment" value="60" onkeyup="calculateTotal(this)"></td> <td class="total">210</td> <td><button class="btn btn-delete" onclick="deleteRow(this)">Delete</button></td> </tr> <tr id="row2"> <td>2</td> <td><input type="text" name="reg_no[]" class="reg-no" value="" placeholder="Enter Reg No"></td> <td><input type="text" name="test_one[]" class="test-one" value="" onkeyup="calculateTotal(this)"></td> <td><input type="text" name="test_two[]" class="test-two" value="" onkeyup="calculateTotal(this)"></td> <td><input type="text" name="assignment[]" class="assignment" value="" onkeyup="calculateTotal(this)"></td> <td class="total">0</td> <td><button class="btn btn-delete" onclick="deleteRow(this)">Delete</button></td> </tr> </tbody> </table> </div> <div class="btn-container"> <button class="btn" onclick="addRow()">➕ Add Row</button> <button class="btn" onclick="submitData()">💾 Save All</button> </div> <div id="loading" class="loading"> <div class="spinner"></div> <p>Saving data...</p> </div> </div> <script> let rowCount = 2; // Function to add new row function addRow() { rowCount++; const tableBody = document.getElementById('tableBody'); const newRow = document.createElement('tr'); newRow.id = 'row' + rowCount; newRow.innerHTML = ` <td>${rowCount}</td> <td><input type="text" name="reg_no[]" class="reg-no" placeholder="Enter Reg No"></td> <td><input type="text" name="test_one[]" class="test-one" onkeyup="calculateTotal(this)"></td> <td><input type="text" name="test_two[]" class="test-two" onkeyup="calculateTotal(this)"></td> <td><input type="text" name="assignment[]" class="assignment" onkeyup="calculateTotal(this)"></td> <td class="total">0</td> <td><button class="btn btn-delete" onclick="deleteRow(this)">Delete</button></td> `; tableBody.appendChild(newRow); } // Function to delete row function deleteRow(button) { const row = button.closest('tr'); if (row && row.id !== 'row1') { // Keep at least one row row.remove(); updateRowNumbers(); } else { alert('Cannot delete the first row!'); } } // Function to update row numbers after deletion function updateRowNumbers() { const rows = document.querySelectorAll('#tableBody tr'); rows.forEach((row, index) => { row.cells[0].textContent = index + 1; }); } // Function to calculate total for a row function calculateTotal(element) { const row = element.closest('tr'); const testOne = parseFloat(row.querySelector('.test-one').value) || 0; const testTwo = parseFloat(row.querySelector('.test-two').value) || 0; const assignment = parseFloat(row.querySelector('.assignment').value) || 0; const total = testOne + testTwo + assignment; row.querySelector('.total').textContent = total; } // Function to submit data via Ajax function submitData() { const rows = []; const rowElements = document.querySelectorAll('#tableBody tr'); rowElements.forEach(row => { const regNo = row.querySelector('.reg-no').value; const testOne = parseFloat(row.querySelector('.test-one').value) || 0; const testTwo = parseFloat(row.querySelector('.test-two').value) || 0; // Only include rows with registration number if (regNo.trim() !== '') { rows.push({ reg_no: regNo, test_one: testOne, test_two: testTwo }); } }); if (rows.length === 0) { alert('Please enter at least one registration number'); return; } // Show loading document.getElementById('loading').style.display = 'block'; document.getElementById('message').style.display = 'none'; // Ajax request using jQuery $.ajax({ url: 'save_ca.php', type: 'POST', data: { students: rows }, dataType: 'json', success: function(response) { document.getElementById('loading').style.display = 'none'; const messageDiv = document.getElementById('message'); messageDiv.style.display = 'block'; if (response.success) { messageDiv.className = 'message success'; messageDiv.innerHTML = '✅ ' + response.message; // Clear form if needed if (response.saved_count > 0) { // Optionally clear or keep data } } else { messageDiv.className = 'message error'; messageDiv.innerHTML = '❌ ' + response.message; } }, error: function(xhr, status, error) { document.getElementById('loading').style.display = 'none'; const messageDiv = document.getElementById('message'); messageDiv.style.display = 'block'; messageDiv.className = 'message error'; messageDiv.innerHTML = '❌ Error saving data: ' + error; } }); } </script> </body> </html>3. PHP Save Handler: save_ca.php
<?php header('Content-Type: application/json'); // Include database connection require_once 'config.php'; // Get POST data $students = isset($_POST['students']) ? $_POST['students'] : []; if (empty($students)) { echo json_encode([ 'success' => false, 'message' => 'No student data received' ]); exit; } // Start transaction $conn->begin_transaction(); try { $savedCount = 0; $errors = []; foreach ($students as $student) { $regNo = $conn->real_escape_string($student['reg_no']); $testOne = floatval($student['test_one']); $testTwo = floatval($student['test_two']); // Validate marks if ($testOne < 0 || $testOne > 50 || $testTwo < 0 || $testTwo > 50) { $errors[] = "Invalid marks for registration: $regNo"; continue; } // Get student_id from tbl_student $studentQuery = "SELECT student_id FROM tbl_student WHERE registration_no = '$regNo'"; $result = $conn->query($studentQuery); if ($result && $result->num_rows > 0) { $studentRow = $result->fetch_assoc(); $studentId = $studentRow['student_id']; // Check if CA result already exists $checkQuery = "SELECT * FROM tbl_ca_result WHERE student_id = $studentId"; $checkResult = $conn->query($checkQuery); if ($checkResult && $checkResult->num_rows > 0) { // Update existing record $updateQuery = "UPDATE tbl_ca_result SET test_one = $testOne, test_two = $testTwo WHERE student_id = $studentId"; if ($conn->query($updateQuery)) { $savedCount++; } else { $errors[] = "Failed to update for: $regNo"; } } else { // Insert new record $insertQuery = "INSERT INTO tbl_ca_result (student_id, test_one, test_two) VALUES ($studentId, $testOne, $testTwo)"; if ($conn->query($insertQuery)) { $savedCount++; } else { $errors[] = "Failed to insert for: $regNo"; } } } else { $errors[] = "Student not found: $regNo"; } } if (empty($errors)) { $conn->commit(); echo json_encode([ 'success' => true, 'message' => "Successfully saved $savedCount records", 'saved_count' => $savedCount ]); } else { $conn->rollback(); echo json_encode([ 'success' => false, 'message' => "Errors: " . implode(", ", $errors) ]); } } catch (Exception $e) { $conn->rollback(); echo json_encode([ 'success' => false, 'message' => 'Database error: ' . $e->getMessage() ]); } $conn->close(); ?>4. Optional: Student Lookup Script: get_student.php
<?php header('Content-Type: application/json'); require_once 'config.php'; $search = isset($_GET['search']) ? $_GET['search'] : ''; if (empty($search)) { echo json_encode([]); exit; } $search = $conn->real_escape_string($search); $query = "SELECT registration_no FROM tbl_student WHERE registration_no LIKE '%$search%' LIMIT 10"; $result = $conn->query($query); $students = []; if ($result && $result->num_rows > 0) { while ($row = $result->fetch_assoc()) { $students[] = $row['registration_no']; } } echo json_encode($students); ?>
Question Six
a) Computers are playing an increasing role in education. Use XHTML and JavaScript to write a program that will help elementary-school student learn multiplication. Use random function to produce two positive one digit integers. It should then display a question such as “How much is 4 times 9?” The student then types the answer into a text field. Your program checks the student’s answer. If it is correct, display the string “Very good!” and generate a new question. If the answer is wrong, display the string “No. Please try again.” And let the student try the same question again repeatedly until the student finally gets it right. A separate function should be used to generate each new question. This function should be called once when the script begins execution and each time the user answers the question correctly. [15 Marks]
Answer (Click to show)
Multiplication Learning Program: multiplication.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Multiplication Learning Program</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; } .container { background-color: white; border-radius: 15px; padding: 40px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); max-width: 500px; width: 100%; } h1 { color: #333; margin-bottom: 20px; text-align: center; } .question-box { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 10px; font-size: 32px; text-align: center; margin-bottom: 20px; } .input-group { margin-bottom: 20px; } label { display: block; margin-bottom: 5px; color: #555; font-weight: 600; } input[type="number"] { width: 100%; padding: 15px; font-size: 20px; border: 2px solid #e0e0e0; border-radius: 8px; text-align: center; } input[type="number"]:focus { outline: none; border-color: #667eea; } .btn { width: 100%; padding: 15px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 18px; cursor: pointer; transition: transform 0.3s; } .btn:hover { transform: scale(1.02); } .message { padding: 15px; border-radius: 8px; margin: 20px 0; text-align: center; font-size: 18px; font-weight: bold; } .correct { background-color: #4CAF50; color: white; } .wrong { background-color: #f44336; color: white; } .stats { margin-top: 20px; padding: 15px; background-color: #f5f5f5; border-radius: 8px; text-align: center; } .score { font-size: 24px; color: #4CAF50; font-weight: bold; } </style> </head> <body> <div class="container"> <h1>🧮 Multiplication Practice</h1> <div id="questionBox" class="question-box"> Loading question... </div> <div class="input-group"> <label for="answer">Your Answer:</label> <input type="number" id="answer" placeholder="Enter your answer" autofocus> </div> <button class="btn" onclick="checkAnswer()">Check Answer</button> <div id="message" class="message"></div> <div class="stats"> <p>Correct Answers: <span id="correctCount" class="score">0</span></p> </div> </div> <script> // Variables to store current question let num1, num2, correctAnswer; let correctCount = 0; let isCorrect = false; // Function to generate new question function generateQuestion() { // Generate two random numbers between 1 and 9 num1 = Math.floor(Math.random() * 9) + 1; num2 = Math.floor(Math.random() * 9) + 1; correctAnswer = num1 * num2; // Update question display document.getElementById('questionBox').innerHTML = `How much is ${num1} times ${num2}?`; // Clear input field document.getElementById('answer').value = ''; // Clear message document.getElementById('message').innerHTML = ''; document.getElementById('message').className = 'message'; // Focus on input document.getElementById('answer').focus(); } // Function to check answer function checkAnswer() { const userAnswer = parseInt(document.getElementById('answer').value); const messageDiv = document.getElementById('message'); // Check if answer is valid if (isNaN(userAnswer)) { messageDiv.innerHTML = 'Please enter a number!'; messageDiv.className = 'message wrong'; return; } // Compare with correct answer if (userAnswer === correctAnswer) { // Correct answer messageDiv.innerHTML = '✅ Very good!'; messageDiv.className = 'message correct'; // Increment correct count correctCount++; document.getElementById('correctCount').innerHTML = correctCount; // Generate new question after a short delay setTimeout(generateQuestion, 1500); } else { // Wrong answer messageDiv.innerHTML = '❌ No. Please try again.'; messageDiv.className = 'message wrong'; // Clear input for retry document.getElementById('answer').value = ''; document.getElementById('answer').focus(); } } // Allow Enter key to submit answer document.getElementById('answer').addEventListener('keypress', function(event) { if (event.key === 'Enter') { checkAnswer(); } }); // Generate first question when page loads window.onload = generateQuestion; </script> </body> </html>
b) Modify the program from question One to allow the user to pick the type of arithmetic problems he or she wishes to study. An option of 1 means addition problem only, 2 means subtraction problems only, 3 means multiplication problem only, 4 means division problems only and 5 means to intermix randomly of all these types. [15 Marks]
Answer (Click to show)
Enhanced Arithmetic Learning Program: arithmetic_tutor.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Arithmetic Learning Program</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; } .container { background-color: white; border-radius: 15px; padding: 40px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); max-width: 600px; width: 100%; } h1 { color: #333; margin-bottom: 20px; text-align: center; } .mode-selector { background-color: #f5f5f5; padding: 20px; border-radius: 10px; margin-bottom: 20px; } .mode-selector h3 { color: #555; margin-bottom: 15px; } .radio-group { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px; } .radio-item { display: flex; align-items: center; } .radio-item input[type="radio"] { margin-right: 8px; width: 18px; height: 18px; cursor: pointer; } .radio-item label { color: #666; cursor: pointer; } .question-box { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px; border-radius: 10px; font-size: 36px; text-align: center; margin-bottom: 20px; } .input-group { margin-bottom: 20px; } label { display: block; margin-bottom: 5px; color: #555; font-weight: 600; } input[type="number"] { width: 100%; padding: 15px; font-size: 20px; border: 2px solid #e0e0e0; border-radius: 8px; text-align: center; } input[type="number"]:focus { outline: none; border-color: #667eea; } .btn { width: 100%; padding: 15px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 8px; font-size: 18px; cursor: pointer; transition: transform 0.3s; } .btn:hover { transform: scale(1.02); } .btn:disabled { opacity: 0.5; cursor: not-allowed; } .message { padding: 15px; border-radius: 8px; margin: 20px 0; text-align: center; font-size: 18px; font-weight: bold; } .correct { background-color: #4CAF50; color: white; } .wrong { background-color: #f44336; color: white; } .stats { margin-top: 20px; padding: 15px; background-color: #f5f5f5; border-radius: 8px; display: flex; justify-content: space-around; flex-wrap: wrap; } .stat-item { text-align: center; } .stat-label { color: #666; font-size: 14px; } .stat-value { font-size: 24px; font-weight: bold; color: #4CAF50; } </style> </head> <body> <div class="container"> <h1>🧮 Arithmetic Learning Program</h1> <div class="mode-selector"> <h3>Select Problem Type:</h3> <div class="radio-group"> <div class="radio-item"> <input type="radio" id="mode1" name="mode" value="1" checked> <label for="mode1">1. Addition (+)</label> </div> <div class="radio-item"> <input type="radio" id="mode2" name="mode" value="2"> <label for="mode2">2. Subtraction (-)</label> </div> <div class="radio-item"> <input type="radio" id="mode3" name="mode" value="3"> <label for="mode3">3. Multiplication (×)</label> </div> <div class="radio-item"> <input type="radio" id="mode4" name="mode" value="4"> <label for="mode4">4. Division (÷)</label> </div> <div class="radio-item"> <input type="radio" id="mode5" name="mode" value="5"> <label for="mode5">5. Mixed (All)</label> </div> </div> </div> <div id="questionBox" class="question-box"> Select a mode to start </div> <div class="input-group"> <label for="answer">Your Answer:</label> <input type="number" id="answer" placeholder="Enter your answer" step="any"> </div> <button class="btn" onclick="checkAnswer()" id="checkBtn">Check Answer</button> <button class="btn" onclick="generateQuestion()" id="newBtn" style="margin-top: 10px; background: #9C27B0;">New Question</button> <div id="message" class="message"></div> <div class="stats"> <div class="stat-item"> <div class="stat-label">Correct</div> <div class="stat-value" id="correctCount">0</div> </div> <div class="stat-item"> <div class="stat-label">Wrong</div> <div class="stat-value" id="wrongCount">0</div> </div> <div class="stat-item"> <div class="stat-label">Current Mode</div> <div class="stat-value" id="currentMode">Addition</div> </div> </div> </div> <script> // Variables to store current question let num1, num2, correctAnswer, currentOperation; let correctCount = 0; let wrongCount = 0; let currentQuestion = ''; // Operation symbols const operations = { 1: { symbol: '+', name: 'Addition' }, 2: { symbol: '-', name: 'Subtraction' }, 3: { symbol: '×', name: 'Multiplication' }, 4: { symbol: '÷', name: 'Division' }, 5: { symbol: '?', name: 'Mixed' } }; // Function to get selected mode function getSelectedMode() { const radios = document.getElementsByName('mode'); for (let radio of radios) { if (radio.checked) { return parseInt(radio.value); } } return 1; // Default to addition } // Function to generate random numbers based on operation function generateNumbers(operation) { switch(operation) { case 1: // Addition num1 = Math.floor(Math.random() * 20) + 1; num2 = Math.floor(Math.random() * 20) + 1; correctAnswer = num1 + num2; break; case 2: // Subtraction (ensure positive result) num1 = Math.floor(Math.random() * 20) + 1; num2 = Math.floor(Math.random() * num1) + 1; correctAnswer = num1 - num2; break; case 3: // Multiplication num1 = Math.floor(Math.random() * 12) + 1; num2 = Math.floor(Math.random() * 12) + 1; correctAnswer = num1 * num2; break; case 4: // Division (ensure integer result) num2 = Math.floor(Math.random() * 10) + 1; correctAnswer = Math.floor(Math.random() * 10) + 1; num1 = num2 * correctAnswer; break; case 5: // Mixed const randomOp = Math.floor(Math.random() * 4) + 1; generateNumbers(randomOp); return; // Return early to avoid duplicate generation } } // Function to generate new question function generateQuestion() { const mode = getSelectedMode(); // Update current mode display document.getElementById('currentMode').innerHTML = operations[mode].name; // Generate numbers based on mode generateNumbers(mode); // Create question text let questionText = ''; switch(mode) { case 1: questionText = `What is ${num1} + ${num2}?`; break; case 2: questionText = `What is ${num1} - ${num2}?`; break; case 3: questionText = `What is ${num1} × ${num2}?`; break; case 4: questionText = `What is ${num1} ÷ ${num2}?`; break; case 5: // Operation already set in generateNumbers const currentOp = getCurrentOperation(); questionText = `What is ${num1} ${currentOp.symbol} ${num2}?`; break; } currentQuestion = questionText; document.getElementById('questionBox').innerHTML = questionText; document.getElementById('answer').value = ''; document.getElementById('message').innerHTML = ''; document.getElementById('message').className = 'message'; document.getElementById('answer').focus(); } // Helper function to get current operation symbol for mixed mode function getCurrentOperation() { const mode = getSelectedMode(); if (mode === 5) { // Determine which operation was generated if (num1 + num2 === correctAnswer) return operations[1]; if (num1 - num2 === correctAnswer) return operations[2]; if (num1 * num2 === correctAnswer) return operations[3]; if (num1 / num2 === correctAnswer) return operations[4]; } return operations[mode]; } // Function to check answer function checkAnswer() { const userAnswer = parseFloat(document.getElementById('answer').value); const messageDiv = document.getElementById('message'); // Check if answer is valid if (isNaN(userAnswer)) { messageDiv.innerHTML = 'Please enter a number!'; messageDiv.className = 'message wrong'; return; } // Compare with correct answer (allow small floating point error for division) const tolerance = 0.01; if (Math.abs(userAnswer - correctAnswer) < tolerance) { // Correct answer messageDiv.innerHTML = '✅ Very good!'; messageDiv.className = 'message correct'; correctCount++; document.getElementById('correctCount').innerHTML = correctCount; // Generate new question after delay setTimeout(generateQuestion, 1500); } else { // Wrong answer messageDiv.innerHTML = `❌ No. The correct answer is ${correctAnswer}`; messageDiv.className = 'message wrong'; wrongCount++; document.getElementById('wrongCount').innerHTML = wrongCount; // Clear input for retry document.getElementById('answer').value = ''; document.getElementById('answer').focus(); } } // Allow Enter key to submit answer document.getElementById('answer').addEventListener('keypress', function(event) { if (event.key === 'Enter') { checkAnswer(); } }); // Regenerate question when mode changes document.getElementsByName('mode').forEach(radio => { radio.addEventListener('change', function() { generateQuestion(); }); }); // Generate first question when page loads window.onload = function() { generateQuestion(); }; </script> </body> </html>
Question Seven
Write the PHP code for a web page filter.php that filters lines of text from a file. The page should contain a short form with a text box where the user can type a word. The page also displays the current contents of the file text.txt as a pre-formatted block. The form submits back to the same page, filter.php, as a POST request. When the word is submitted, your code should examine the contents of text.txt and remove any lines from the file that contain the given word, case-insensitively. Write the changes to the file so that any future viewings of the page will see the changes. You can write just the code dealing with the page’s body; you don’t need to output a head section or a complete page. [30 Marks]
Match the exact word, not other words that contain it as a substring. For example, if the user submits the word “me” you would filter out lines containing the word “me”, but not lines that just contain a word such as “men” or “game”.
Answer (Click to show)
filter.php - Complete Solution
<?php // filter.php - Word Filter for Text File // Configuration $filename = 'text.txt'; $message = ''; $messageType = ''; // Create sample file if it doesn't exist if (!file_exists($filename)) { $sampleContent = "This is a sample text file.\n"; $sampleContent .= "The quick brown fox jumps over the lazy dog.\n"; $sampleContent .= "Learning PHP is fun and interesting.\n"; $sampleContent .= "One two three four five.\n"; $sampleContent .= "The word 'me' appears here.\n"; $sampleContent .= "Men are working in the game park.\n"; $sampleContent .= "This line contains the word hello.\n"; $sampleContent .= "Hello world! Welcome to PHP programming.\n"; $sampleContent .= "Filter out lines containing specific words.\n"; $sampleContent .= "Case insensitive matching is important.\n"; file_put_contents($filename, $sampleContent); $message = "Sample file created. "; } // Handle form submission if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['filter_word'])) { $filterWord = trim($_POST['filter_word']); if (!empty($filterWord)) { // Read file contents $lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $originalCount = count($lines); // Filter lines $filteredLines = array_filter($lines, function($line) use ($filterWord) { // Use word boundary regex to match exact word only // Pattern: /\bword\b/i (case insensitive) $pattern = '/\b' . preg_quote($filterWord, '/') . '\b/i'; return !preg_match($pattern, $line); }); $newCount = count($filteredLines); $removedCount = $originalCount - $newCount; // Write filtered content back to file if ($removedCount > 0) { file_put_contents($filename, implode("\n", $filteredLines) . "\n"); $message = "Removed $removedCount line(s) containing '$filterWord'."; $messageType = 'success'; } else { $message = "No lines found containing '$filterWord'."; $messageType = 'info'; } } else { $message = "Please enter a word to filter."; $messageType = 'error'; } } // Read current file content for display $fileContent = file_exists($filename) ? file_get_contents($filename) : "File not found."; ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Text File Filter</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; } .container { max-width: 800px; margin: 0 auto; background-color: white; border-radius: 15px; padding: 30px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); } h1 { color: #333; margin-bottom: 20px; text-align: center; } h1 span { color: #667eea; } .info-box { background-color: #f8f9fa; border-left: 4px solid #667eea; padding: 15px; margin-bottom: 20px; border-radius: 5px; } .filter-form { background-color: #f5f5f5; padding: 20px; border-radius: 10px; margin-bottom: 20px; } .form-group { display: flex; gap: 10px; } input[type="text"] { flex: 1; padding: 12px; border: 2px solid #e0e0e0; border-radius: 5px; font-size: 16px; } input[type="text"]:focus { outline: none; border-color: #667eea; } button { padding: 12px 30px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; border-radius: 5px; font-size: 16px; cursor: pointer; transition: transform 0.3s; } button:hover { transform: scale(1.05); } .message { padding: 15px; border-radius: 5px; margin: 20px 0; } .success { background-color: #4CAF50; color: white; } .error { background-color: #f44336; color: white; } .info { background-color: #2196F3; color: white; } .file-section { background-color: #f8f9fa; border-radius: 10px; padding: 20px; } .file-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .file-stats { color: #666; font-size: 14px; } .file-content { background-color: #2d2d2d; color: #f8f8f8; padding: 20px; border-radius: 8px; font-family: 'Courier New', monospace; white-space: pre-wrap; word-wrap: break-word; max-height: 400px; overflow-y: auto; font-size: 14px; line-height: 1.5; } .line-number { color: #888; margin-right: 15px; user-select: none; } .reset-btn { background: #9C27B0; margin-left: 10px; } .footer { margin-top: 20px; text-align: center; color: #666; font-size: 12px; } </style> </head> <body> <div class="container"> <h1>📄 <span>Text File Filter</span></h1> <div class="info-box"> <p><strong>File:</strong> <?php echo $filename; ?></p> <p><strong>Instructions:</strong> Enter a word to remove all lines containing that word (exact match, case insensitive).</p> </div> <?php if ($message): ?> <div class="message <?php echo $messageType; ?>"> <?php echo $message; ?> </div> <?php endif; ?> <div class="filter-form"> <form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>"> <div class="form-group"> <input type="text" name="filter_word" placeholder="Enter word to filter out..." value="<?php echo isset($_POST['filter_word']) ? htmlspecialchars($_POST['filter_word']) : ''; ?>"> <button type="submit">Filter Lines</button> </div> </form> </div> <div class="file-section"> <div class="file-header"> <h3>Current File Contents</h3> <div class="file-stats"> <?php $lines = file($filename, FILE_IGNORE_NEW_LINES); $lineCount = count($lines); $charCount = strlen($fileContent); echo "Lines: $lineCount | Characters: $charCount"; ?> </div> </div> <div class="file-content"> <?php // Display with line numbers $lines = explode("\n", $fileContent); foreach ($lines as $index => $line) { if (trim($line) !== '') { echo '<span class="line-number">' . str_pad($index + 1, 3, ' ', STR_PAD_LEFT) . '</span> ' . htmlspecialchars($line) . "\n"; } } ?> </div> </div> <div style="margin-top: 20px; text-align: right;"> <form method="POST" action="<?php echo $_SERVER['PHP_SELF']; ?>" style="display: inline;"> <input type="hidden" name="reset" value="1"> <button type="submit" class="reset-btn" onclick="return confirm('Reset to sample file? This will restore default content.')">↻ Reset to Sample</button> </form> </div> <div class="footer"> <p>© 2019 University of Dodoma - CS312 Internet Programming</p> </div> </div> </body> </html>Alternative Minimal Version (Body Only as Requested):
<?php // filter.php - Minimal version (body only as requested) $filename = 'text.txt'; $message = ''; // Create sample file if needed if (!file_exists($filename)) { $sample = "This is line one.\nThis line contains the word hello.\nAnother line here.\nOne more line with me.\nMen are working.\n"; file_put_contents($filename, $sample); } // Handle form submission if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['filter_word'])) { $word = trim($_POST['filter_word']); if (!empty($word)) { $lines = file($filename, FILE_IGNORE_NEW_LINES); $pattern = '/\b' . preg_quote($word, '/') . '\b/i'; $filtered = array_filter($lines, function($line) use ($pattern) { return !preg_match($pattern, $line); }); $removed = count($lines) - count($filtered); if ($removed > 0) { file_put_contents($filename, implode("\n", $filtered) . "\n"); $message = "Removed $removed line(s) containing '$word'."; } else { $message = "No lines containing '$word' found."; } } } // Read current content $content = file_get_contents($filename); ?> <div style="font-family: Arial; max-width: 800px; margin: 0 auto; padding: 20px;"> <h2>Text File Filter</h2> <?php if ($message): ?> <div style="background: #4CAF50; color: white; padding: 10px; border-radius: 5px; margin-bottom: 20px;"> <?php echo $message; ?> </div> <?php endif; ?> <form method="POST" style="margin-bottom: 20px;"> <input type="text" name="filter_word" placeholder="Enter word to filter..." style="padding: 10px; width: 300px;"> <button type="submit" style="padding: 10px 20px; background: #667eea; color: white; border: none;"> Filter </button> </form> <h3>Current File Content:</h3> <pre style="background: #f4f4f4; padding: 15px; border-radius: 5px; overflow: auto;"><?php echo htmlspecialchars($content); ?></pre> </div>