Files
mini-test-projects-2-release/module-a/module-a-en.md
2026-04-12 18:58:03 +09:00

20 KiB
Raw Blame History

Test Project: Module A — Speed Test

1. Project Overview

This assessment is a Speed Test designed to quickly and accurately evaluate practical proficiency across web technologies. Competitors must complete a total of 20 independent tasks across four categories — A (Design), B (Layout), C (Frontend), and D (Backend) — within the allotted time. Each task is independent and may be attempted in any order.


2. Tech Stack & Constraints

Category Allowed Technologies Restrictions
A. Design GIMP No other image editors (e.g., Photoshop) permitted
B. Layout HTML, CSS JavaScript is not permitted
C. Frontend JavaScript (Vanilla) No external libraries or frameworks permitted
D. Backend PHP, MySQL Database must be connected using PDO
  • All deliverables will be evaluated in a desktop Chrome browser.
  • Save each task's deliverable in a subdirectory named after the task ID under /module_a/. (e.g., /module_a/a1/, /module_a/b1/)
  • Design tasks must include the GIMP source file (.xcf) in the submission directory.

3. Tasks

🎨 A. Design — GIMP Proficiency

Provided files: Files for A1 (source.png), A2 (base.jpg), and A3 (photo.jpg, mask.png) are pre-placed in each task's working directory. A4 and A5 have no provided files; competitors must create all assets from scratch.

A1. Layer Compositing and Text Placement Easy

Create an image in GIMP using a layered structure.

  • Canvas size: 800×400px, Resolution: 72dpi
  • Layer 1: Fill the background with the solid color #2C3E50.
  • Layer 2: Open the provided image (source.png), place it at the center of the canvas, and set its opacity to 70%.
  • Layer 3: Add the text "Hello, GIMP" in white (#FFFFFF) at 36pt, and position it at the top-left of the canvas (x: 20px, y: 20px).
  • Save the project as a .xcf file first. Then flatten all layers (Flatten Image) and export the result as result.png.

A2. Selection and Layer Compositing Easy

Apply shape effects to an image using GIMP's selection tools and layers.

  • Open the provided image (base.jpg) as the background layer.
  • Effect 1: Add a new layer. Use the Rectangle Select tool to select the region from (0, 0) to (200, 200) in the top-left corner, fill it with #E74C3C, and set this layer's opacity to 60%.
  • Effect 2: Add another new layer. Create an elliptical selection with a diameter of 150px at the center of the image. Go to Selection → Border, set the border width to 3px, and fill the resulting selection with #FFFFFF.
  • Save the project as a .xcf file first. Then flatten all layers (Flatten Image) and export the result as result.jpg.

A3. Color Correction and Layer Mask Normal

Apply color correction and a layer mask to the provided image (photo.jpg) in GIMP.

  • Color correction: Use the Hue-Saturation tool to increase Saturation by +40.
  • Curves adjustment: Use the Curves tool to raise the output value of highlights by +20 or more and lower the output value of shadows by -20 or less to increase contrast.
  • Layer mask: Add a layer mask to the image layer. Paste the provided mask image (mask.png) into the mask layer so that the background outside the subject is removed.
  • Save the project as a .xcf file first. Then export the result as result.png, ensuring the transparent background is preserved (PNG format).

A4. Text Effect and Glow Normal

Apply a glow visual effect to text in GIMP.

  • Canvas size: 600×200px, Background color: #1A1A2E
  • Add the text "SPEED TEST" in white (#FFFFFF), Bold, 60pt, centered on the canvas.
  • Duplicate the text layer and place the duplicate below the original text layer.
  • Rasterize the duplicate layer (Layer → Rasterize). In the Layers panel, set the duplicate layer's Mode to Color first. Then set the foreground color to #4A90D9 and apply Edit → Fill with Foreground Color so the blue color is applied.
  • Apply Gaussian Blur with a radius of 8px to the duplicate layer to complete the outer glow effect.
  • Save the project as a .xcf file first, then export the result as result.png.

A5. Text Warp and Filter Effects Hard

Rasterize text and apply a combination of Distorts filters in GIMP to create visual distortion effects.

  • Canvas size: 800×300px, Background color: #0D0D0D
  • Add the text "DISTORTION" in white (#FFFFFF), Bold, 72pt, centered on the canvas.
  • Rasterize the text layer (Layer → Rasterize).
  • Apply the following two Distorts filters to the rasterized text layer in order:
    • Ripple: Amplitude 8, Wavelength 40, Orientation: Horizontal
    • Whirl and Pinch: Whirl angle 20 degrees, Pinch 0, Radius 1.0
  • Duplicate the distorted text layer. Apply Gaussian Blur with a radius of 3px to the duplicate, then place the duplicate below the original layer to create a ghosting effect.
  • Save the project as a .xcf file first, then export the result as result.png.

📐 B. Layout — HTML / CSS Only

B1. Flexbox Card Layout Easy

Build a card list layout using HTML and CSS only.

  • Use Flexbox to arrange cards 4 per row. (Use flex-wrap: wrap)
  • Each card must contain: an image area (<div>, height 160px, with a background color), a title (<h3>), body text (<p>), and a button (<button>).
  • Set the gap between cards to 24px.
  • Create 8 dummy cards. Each card's image area must have a different background color.

B2. Sticky Header and CSS Interaction Easy

Build a header with CSS-only interactions using HTML and CSS only.

  • Use Flexbox to arrange the header with a logo text on the left, 4 menu links in the center, and 2 buttons on the right.
  • Implement a CSS-only interaction where hovering over a menu link reveals a 2px solid underline with a transition effect. (Use border-bottom or a ::after pseudo-element)
  • Use position: sticky; top: 0; to keep the header fixed at the top while scrolling.
  • Place dummy content with a minimum height of 3000px below the header to enable scrolling.

B3. CSS Grid Two-Column Layout Normal

Build a two-column page layout using CSS Grid with HTML and CSS only.

  • Use CSS Grid to create a layout with a fixed left sidebar (250px) and a right main content area (1fr).
  • Place a vertical navigation menu (5 items) in the left sidebar. Style the first item to indicate an active state using background color and text color.
  • Place a title, body text, and a 3-column card grid (using CSS Grid, 6 cards) in sequence in the right main area.
  • Apply height: 100vh and overflow: hidden to the layout wrapper. Apply height: 100vh and overflow-y: auto to both the sidebar and the main area so that each scrolls independently.

B4. CSS Animations and Transitions Normal

Implement various CSS animations and transition effects on a single page using HTML and CSS only.

  • Card hover effect: Arrange 4 cards in a row using Flexbox. On hover, each card should move up 8px and have a stronger shadow using a transition. (Use transform: translateY(-8px), box-shadow, and transition)
  • Loading spinner: Use @keyframes to create a circular loading spinner. The spinner should be 48px in diameter with a 4px border. Only the top border (border-top) should be colored #3498DB; the remaining borders should be #e0e0e0. The spinner rotates infinitely.
  • Fade-in text: On page load, a heading (<h1>) should animate from translateY(20px) to translateY(0) while fading from opacity: 0 to opacity: 1 using @keyframes. (animation-duration: 0.8s, animation-fill-mode: both)

B5. CSS Grid and Advanced Selectors Hard

Build a two-column content layout with a CSS-only tab interaction using HTML and CSS only.

  • Use CSS Grid to create a two-column layout: left column (65%) and right column (35%).
  • Left area: Place a main image area (<div>, height 300px, with a background color) and a horizontal thumbnail list below it (Flexbox, overflow-x: auto). Include 5 thumbnails, each as an 80×80px <div> with a different background color.
  • Right area — upper: Place a title, subtitle, and body text.
  • Right area — lower: Implement 3 tabs (Overview / Details / Reviews) with their respective content areas.
    • Use <input type="radio" name="tab"> and the CSS :checked selector without JavaScript so that only the selected tab's content is shown.
    • Hide the <input type="radio"> elements with display: none and style the corresponding <label> elements to look like tab buttons.
  • At the bottom of the right area, place a Primary button and a Secondary button side by side. Apply a @keyframes animation to the Primary button so its background color transitions smoothly on hover.

C. Frontend — JavaScript (Vanilla)

C1. localStorage-based Memo App Easy

Build a simple memo app using Vanilla JavaScript and localStorage.

  • The page must include a text input (<textarea>) and a "Save" button.
  • Clicking "Save" adds the memo to a JSON array stored under the memos key in localStorage. Empty content must not be saved.
  • Render the saved memo list below the input area. Each item must include the memo content and a "Delete" button.
  • Clicking "Delete" removes the item from localStorage and immediately updates the rendered list.
  • The memo list must persist after a page refresh.

C2. DOM Manipulation and Event Handling Easy

Build a dynamic list with item management using Vanilla JavaScript.

  • The page must include a text input (<input type="text">) and an "Add" button.
  • Clicking "Add" or pressing Enter adds the input value as a new list item. Empty values must not be added. The input field is cleared after adding.
  • Each item must include a "Done" button and a "Delete" button.
    • Clicking "Done" applies a strikethrough (text-decoration: line-through) to the item text. Clicking again toggles it back.
    • Clicking "Delete" removes the item immediately.
  • Display the current total item count and completed item count at the top of the list in real time.

C3. Dynamic JSON Rendering and Filtering Normal

Build a page that fetches a local JSON file and dynamically renders its content using Vanilla JavaScript and the Fetch API.

  • Fetch the provided posts.json file at /module_a/c3/posts.json using the Fetch API. The file contains an array of objects with the keys id, title, body, and category. (20 items total)
  • Display a loading spinner (CSS animation) while fetching, and remove it when the fetch completes.
  • Render all items as cards. Each card must display id, title, body, and category.
  • Implement a search input that filters cards in real time by title. (Case-insensitive; updates immediately on each keystroke)
  • If the Fetch request fails, display the error message "Failed to load data." on the screen.

Provided file: posts.json (pre-placed in the competitor's working directory at /module_a/c3/)

C4. Form Validation Normal

Implement real-time form validation using Vanilla JavaScript.

  • Build a registration form with the following fields: Name, Email, Password, Confirm Password
  • Validation rules for each field:
    • Name: Required, at least 2 characters
    • Email: Required, must contain both @ and .
    • Password: Required, at least 8 characters, must contain both letters and numbers
    • Confirm Password: Required, must match the Password field exactly
  • When focus leaves a field (blur event), display an error message below that field if the validation rule is not met. Remove the error message immediately once the condition is satisfied.
  • The "Submit" button must only be enabled when all fields are valid. Clicking it should trigger alert("Registration complete.").

C5. IntersectionObserver and Deferred Rendering Hard

Implement infinite scroll and deferred rendering using IntersectionObserver.

  • Define an array of 50 dummy items in JavaScript. Each item must have id, title, and color. (color is an arbitrary hex color value in #RRGGBB format)
  • On initial load, render 10 items. Each item consists of a 200px-tall color <div> and its title text. The first 10 items should display their color value as the background color immediately.
  • Place a sentinel element (<div id="sentinel">) at the bottom of the list. When the sentinel enters the viewport, automatically render the next 10 items.
  • While new items are being added, insert a loading spinner element directly before the sentinel to display it, and remove it once rendering is complete. (Simulate async behavior using setTimeout with 600ms)
  • Once all 50 items have been rendered, stop observing the sentinel (observer.unobserve) and display the message "All items loaded."
  • New items should be added to the DOM with their color <div> initially set to #cccccc (grey). Use a separate IntersectionObserver instance to watch each <div>, and replace the background color with the real color from the element's data-color attribute the moment it enters the viewport.

🛢️ D. Backend — PHP / MySQL

Provided files: posts_dump.sql for D4 and data_dump.sql for D5 are pre-placed in each task's working directory.

D1. PDO-based CRUD API Easy

Build a REST API to handle data using PHP and MySQL (PDO).

  • Create an items table using the structure below. Submit the table creation SQL as table.sql.
    • id (INT, PK, AUTO_INCREMENT), title (VARCHAR 100, NOT NULL), content (TEXT), created_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
  • Implement the following 4 endpoints in a single file api.php, branching by HTTP method ($_SERVER['REQUEST_METHOD']).
    • GET /module_a/d1/api.php → Return all items as a JSON array
    • POST /module_a/d1/api.php → Add a new item. Body (JSON): {"title": "...", "content": "..."}. Read the request body using php://input and parse it with json_decode(). On success, return the inserted row as JSON.
    • PUT /module_a/d1/api.php?id={id} → Update title and content. Body (JSON): {"title": "...", "content": "..."}. Read the request body using php://input and parse it with json_decode(). On success, return the updated row as JSON.
    • DELETE /module_a/d1/api.php?id={id} → Delete the item. On success, return {"message": "deleted"}.
  • For PUT/DELETE requests with a non-existent id, return HTTP status 404 and {"error": "Not found"}.
  • All responses must include a Content-Type: application/json header.

D2. File Upload Handling Easy

Implement image file upload functionality using PHP.

  • In upload.php, implement both a file upload HTML form (GET) and the upload processing logic (POST). Set the form's enctype to multipart/form-data.
  • Upload conditions: only jpg, jpeg, png, gif extensions are allowed; file size must be 2MB or less.
  • Save files that pass validation to the uploads/ directory using the naming format {time()}_{original_filename}. If the uploads/ directory does not exist, create it manually.
  • On successful upload, display the uploaded image using an <img> tag.
  • For validation failures, display the appropriate error message:
    • Invalid extension: "File type not allowed."
    • Size exceeded: "File size exceeds 2MB."

D3. Session-based Authentication System Normal

Implement user registration, login, and logout using PHP sessions and MySQL.

  • users table: id (INT, PK, AUTO_INCREMENT), email (VARCHAR 100, UNIQUE), password (VARCHAR 255), name (VARCHAR 50), created_at (TIMESTAMP DEFAULT CURRENT_TIMESTAMP)
  • register.php: On GET, render an HTML registration form. On POST, check for duplicate emails and save the password hashed with password_hash(), then redirect immediately to login.php without displaying a success message. If the email is already in use, display the error "This email is already registered." above the form.
  • login.php: On GET, render an HTML login form. On POST, verify the password with password_verify(). On success, store user_id, name, and email in the session and redirect to mypage.php. On failure, display the error "Incorrect email or password." above the form.
  • logout.php: On GET, destroy the session with session_destroy() and redirect to login.php.
  • mypage.php: If user_id is not in the session, redirect to login.php. If logged in, display the message "Welcome, {name}!" and a logout link.

D4. Pagination Normal

Implement server-side pagination using PHP and MySQL (PDO).

  • Create the posts table yourself, then import the provided SQL dump (posts_dump.sql). Table structure: id, title, content, created_at
  • In index.php, display 10 posts per page.
  • The current page is determined by the URL query string ?page={n}, defaulting to 1. Use LIMIT and OFFSET in your SQL query to retrieve only the data for the current page. If page is less than 1 or exceeds the total number of pages, redirect to page 1.
  • Display pagination links at the bottom of the page. Show all page numbers, highlight the current page with an active style, and include Previous/Next buttons. Disable the Previous button on the first page and the Next button on the last page.
  • Each post item must show the title and registration date. Clicking the title navigates to view.php?id={id}, which displays the full content of that post.

D5. Multi-table Aggregate Queries Hard

Implement a statistics API using multi-table JOINs and aggregate queries.

  • Create all 3 tables yourself, then import the provided SQL dump (data_dump.sql). Tables must be created in the order userspostscomments (to satisfy foreign key dependencies).
    • users (id, name, created_at)
    • posts (id, user_id — references users.id, title, category, view_count, created_at)
    • comments (id, post_id — references posts.id, created_at)
  • In a single file stats.php, branch on the type query string and return the following 3 responses:
    • GET /module_a/d5/stats.php?type=daily → Return the number of new posts per day for the past 7 days, sorted by date ascending. Response format: [{"date": "2026-04-06", "count": 5}, ...]
    • GET /module_a/d5/stats.php?type=category → Return the total post count and average view count per category, sorted by post count descending. Response format: [{"category": "tech", "post_count": 12, "avg_views": 340}, ...]
    • GET /module_a/d5/stats.php?type=top → Return the top 5 posts by comment count, sorted by comment count descending. Response format: [{"post_id": 3, "title": "...", "author": "Alice Johnson", "comment_count": 18}, ...]
  • All queries must use PDO Prepared Statements.
  • For unknown type values, return HTTP 400 and {"error": "Invalid type"}.

4. Submission Guidelines

Upload all deliverables to the server directory /module_a/. Each task's output must be saved in a subdirectory named after the task ID. (e.g., /module_a/a1/, /module_a/b1/, /module_a/c1/, /module_a/d1/)


5. Marking Scheme — Total 25 Points

Category Task Points
A. Design A1. Layer Compositing and Text Placement 0.5
A2. Selection and Layer Compositing 0.5
A3. Color Correction and Layer Mask 1.5
A4. Text Effect and Glow 1.5
A5. Text Warp and Filter Effects 2.0
B. Layout B1. Flexbox Card Layout 0.5
B2. Sticky Header and CSS Interaction 0.5
B3. CSS Grid Two-Column Layout 1.5
B4. CSS Animations and Transitions 1.5
B5. CSS Grid and Advanced Selectors 2.0
C. Frontend C1. localStorage-based Memo App 0.5
C2. DOM Manipulation and Event Handling 0.5
C3. Dynamic JSON Rendering and Filtering 1.5
C4. Form Validation 1.5
C5. IntersectionObserver and Deferred Rendering 2.0
D. Backend D1. PDO-based CRUD API 0.5
D2. File Upload Handling 0.5
D3. Session-based Authentication System 1.5
D4. Pagination 1.5
D5. Multi-table Aggregate Queries 3.0
Total 25