Skip to main content

간단한 일반 상식 퀴즈 웹 서비스 만들기

1. 사전 작업: ChatGPT에게 어떤 퀴즈 웹 서비스를 만들지 물어보기

지난번과 마찬 가지로 ChatGPT에게 아래와 같이 어떤 퀴즈 서비스를 만들면 좋을지 ChatGPT에게 물어보았습니다.

ChatGPT프롬프트
I'm trying to build simple quiz web service, suggest quiz applications. 

아래와 같이 다양한 퀴즈 어플리케이션의 종류를 알려줍니다. ChatGPT프롬프트 응답값 - 퀴즈 어플리케이션의 종류

다양한 퀴즈 어플리케이션이 있는데 오늘은 간단한 일반 상식 퀴즈 웹 서비스를 만들어 보겠습니다.

2. 일반 상식 퀴즈 웹 서비스를 위한 프롬프트 요청

코드 및 가이드 작성은 ChatGPT대신 동일한 GPT4를 사용하는 Playground 를 통해 진행 합니다. 이유는 system 과 assistant 를 쉽게 지정 할수 있고 길이도 더 길게 설정 할수 있기 때문입니다. gpt4 버전의 OpenAI Playgound에서 아래와 같이 프롬프트를 요청합니다.

Playgound에서는 OpenAI API 와 동일하게 User외에도 System과 Assistant 프롬프트를 지원합니다. System 프롬프트는 상황을 설정해주고 Assistant 프롬프트는 원하는 프롬프트에 필요한 정보를 제공 해주고 학습시키는 보조자 역할을 합니다.

  • System 프롬프트
System
act as a experienced frontend developer
  • User 프롬프트

User 프롬프트는 아래 요구 사항으로 간단한 일반 상식 퀴즈를 만들어 줄것을 지시 합니다. 자세한 기능 요구 사항은 Quiz List, Quiz Detail 2개의 페이지로 구성 되어 있고 Quiz List 페이지에서는 Quiz Topic 별로 Quiz List를 보여주고 Quiz Topic을 클릭하면 Quiz Detail 페이지로 이동하여 Quiz를 풀고 결과를 보여주는 기능을 구현 하고자 합니다.

User
I’m trying to build a simple General Knowledge Quiz web service, give me step by step instruction with code example with the following requirements. 
- using html, css, basic javascript
- design & css: modern style design, responsive, material UI (mui)
- 2 pages: Quiz List, Quiz Detail
- Features: quiz list by topic, Quiz page for each topic (quiz, quiz result, back to List)
- output markdown code
- 답변은 한글로

프롬프트를 요청 하면 아래와 같이 코드 작성 하는 방법을 알려줍니다. ChatGPT프롬프트 응답값 - 퀴즈 어플리케이션 코드 작성 하기

3. 토마토 타이머 코드 작성 하기

안녕하세요! 기본 웹 서비스를 만들어보고자 하는 것이 좋은 생각입니다. HTML, CSS, Material-UI 및 기본 JavaScript를 사용하여 원하는 프로젝트를 생성해 보겠습니다. 다음과 같이 진행해주세요.

1단계: 프로젝트 설정

먼저 프로젝트를 설정하려면 index.html, styles.css, script.js 세 가지 파일을 만들어야 합니다.

2단계: HTML 구조 설정

index.html:

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<title>General Knowledge Quiz</title>
</head>
<body>
<div id="app">
<!-- Quiz List -->
<div id="quiz-list" class="container">
<h1>퀴즈 목록</h1>
<div class="row">
<!-- 각 퀴즈 카드가 이곳에 삽입됩니다. -->
</div>
</div>

<!-- Quiz Detail -->
<div id="quiz-detail" class="container" style="display: none;">
<h1 id="quiz-title">퀴즈 제목</h1>
<div id="quiz-questions">
<!-- 각 질문이 이곳에 삽입됩니다. -->
</div>
<button id="submit-quiz">제출하기</button>
<button id="back-to-list">목록으로 돌아가기</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

3단계: CSS 스타일 설정

styles.css:

body {
font-family: 'Roboto', sans-serif;
background-color: #f5f5f5;
}

.container {
max-width: 800px;
margin: 0 auto;
padding-top: 2rem;
}

h1 {
text-align: center;
margin-bottom: 2rem;
}

.row {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}

.quiz-card {
max-width: 300px;
margin-bottom: 2rem;
padding: 1rem;
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
cursor: pointer;
}

.quiz-card h3 {
margin: 0;
text-align: center;
}

.quiz-question {
margin-bottom: 1rem;
}

.quiz-options {
display: flex;
flex-direction: column;
}

.quiz-option {
margin-bottom: 1rem;
}

4단계: JavaScript 코드 작성

script.js:

document.addEventListener('DOMContentLoaded', function() {
const quizList = document.getElementById('quiz-list');
const quizDetail = document.getElementById('quiz-detail');
const backButton = document.getElementById('back-to-list');
const submitButton = document.getElementById('submit-quiz');

// 퀴즈 목록 데이터
const quizzes = [
{
title: '퀴즈 1',
questions: [
// 질문과 선택지를 추가
]
},
// 다른 퀴즈들을 추가
];

function createQuizCard(quiz, index) {
const card = document.createElement('div');
card.setAttribute('class', 'quiz-card');
card.innerHTML = `<h3>${quiz.title}</h3>`;
card.addEventListener('click', () => showQuizDetail(index));
return card;
}

function showQuizDetail(index) {
quizList.style.display = 'none';
quizDetail.style.display = 'block';
// 퀴즈 세부 사항을 채우고 이벤트 리스너를 설정합니다.
}

function hideQuizDetail() {
quizDetail.style.display = 'none';
quizList.style.display = 'block';
}

// 퀴즈 목록을 생성하고 페이지에 삽입
for (const [index, quiz] of quizzes.entries()) {
const card = createQuizCard(quiz, index);
quizList.querySelector('.row').appendChild(card);
}

backButton.addEventListener('click', hideQuizDetail);
submitButton.addEventListener('click', () => {
// 퀴즈 결과를 계산하고 표시
});
});

위 코드를 사용하면 요구 사항에 따라 기본적인 퀴즈 웹 서비스를 만들 수 있습니다. 질문 및 선택지 데이터를 채우고 필요한 기능을 추가하여 프로젝트를 완료하세요.

4. 코드 개선하기

위의 코드로도 동작을 하지만 아직 부족한 부분이 있어 아래와 같이 코드를 개선해보겠습니다.

4.1 퀴즈 내용 채우기

먼저 위의 코드에는 퀴즈 내용이 없어 퀴즈 내용을 채워달라고 합니다.

User
give me 퀴즈 카드 examples and quiz list to fill out <!-- 각 퀴즈 카드가 이곳에 삽입됩니다. --> and  <!-- 각 질문이 이곳에 삽입됩니다. -->

프롬프트를 요청 하면 아래와 같이 코드를 작성 해줍니다. ChatGPT프롬프트 응답값 - 퀴즈 내용 채우기

퀴즈 카드 예시와 퀴즈 질문 목록을 작성해드리겠습니다.

script.js:

// 퀴즈 목록 데이터
const quizzes = [
{
title: '역사 퀴즈',
questions: [
{
question: '고려시대의 수도는 어디인가요?',
options: ['서울', '경주', '강릉', '가야'],
answer: 0
},
{
question: '세종대왕이 창제한 한글의 원래 이름은 무엇인가요?',
options: ['훈민정음', '훈민한글', '옛글', '고대한글'],
answer: 0
}
]
},
{
title: '과학 퀴즈',
questions: [
{
question: '물이 끓는 온도는 몇 도인가요?',
options: ['0도', '50도', '100도', '150도'],
answer: 2
},
{
question: '태양계에서 가장 큰 행성은 어느 행성인가요?',
options: ['지구', '화성', '목성', '토성'],
answer: 2
}
]
}
];

위의 quizzes 배열에 퀴즈 카드 예시와 퀴즈 질문 목록을 작성했습니다. 이제 퀴즈 세부 사항을 채우는 함수를 작성해 보겠습니다.

script.js:

function createQuizQuestion(question, index) {
const questionElement = document.createElement('div');
questionElement.setAttribute('class', 'quiz-question');
questionElement.innerHTML = `<h4>Q${index + 1}: ${question.question}</h4>`;

const optionsElement = document.createElement('div');
optionsElement.setAttribute('class', 'quiz-options');

question.options.forEach((option, i) => {
const optionElement = document.createElement('label');
optionElement.innerHTML = `
<input type="radio" name="question-${index}" value="${i}">
<span>${option}</span>
`;
optionsElement.appendChild(optionElement);
});

questionElement.appendChild(optionsElement);
return questionElement;
}

function showQuizDetail(index) {
quizList.style.display = 'none';
quizDetail.style.display = 'block';

const quiz = quizzes[index];
document.getElementById('quiz-title').textContent = quiz.title;

const quizQuestions = document.getElementById('quiz-questions');
quizQuestions.innerHTML = '';

quiz.questions.forEach((question, i) => {
const questionElement = createQuizQuestion(question, i);
quizQuestions.appendChild(questionElement);
});
}

이제 위의 코드를 사용하면 퀴즈 카드와 퀴즈 목록을 채울 수 있습니다. 퀴즈 결과 계산 및 표시 기능을 추가하여 프로젝트를 완료하세요.

4.2 퀴즈 결과 계산 및 표시 기능을 추가

위에서 퀴즈 결과 계산 및 표시 기능을 추가 하여 프로젝트를 완료하라고 되어 있으니 이번에는 퀴즈 결과 계산 및 표시 기능을 추가하는 방법을 알려달라고 합니다.

User
퀴즈 결과 계산,  표시 기능을 추가 하는 방법 알려줘

프롬프트를 요청 하면 아래와 같이 코드를 작성 해줍니다. ChatGPT프롬프트 응답값 - 퀴즈 결과 계산,  표시 기능을 추가

퀴즈 결과 계산 및 표시 기능을 추가하려면 다음 단계를 따르세요.

1) 결과 계산 함수 작성

script.js:

function calculateQuizResult() {
const quiz = quizzes[currentQuizIndex]; // 현재 퀴즈에 대한 정보를 가져옵니다.
let correctAnswers = 0;

quiz.questions.forEach((question, index) => {
const selectedOption = document.querySelector(`input[name="question-${index}"]:checked`);

if (selectedOption && parseInt(selectedOption.value) === question.answer) {
correctAnswers++;
}
});

return {
totalQuestions: quiz.questions.length,
correctAnswers: correctAnswers
};
}

2) 결과 표시 함수 작성

script.js:

function showQuizResult(result) {
const resultMessage = `정답 수: ${result.correctAnswers} / ${result.totalQuestions}`;
alert(resultMessage);
}

3) 퀴즈 제출 버튼 이벤트 리스너에 결과 계산 및 표시 함수 추가

script.js:

submitButton.addEventListener('click', () => {
const result = calculateQuizResult();
showQuizResult(result);
});

이제 퀴즈를 제출하면 결과가 계산되어 경고창으로 표시됩니다. 필요에 따라 결과 표시 방식을 변경할 수 있습니다. 예를 들어, 결과 페이지를 만들거나 페이지에 직접 결과를 표시하려면 HTML 및 CSS를 추가하고 결과 표시 함수를 수정하세요.

4.3 script.js 재작성 요청

위에서 정리한 개선 사항들을 반영하다보면 script.js가 안돌아 갈수도 있습니다. 이럴 때는 코드를 리뷰 해달라고 하거나 재작성을 요청 해볼 수 있습니다. 이번에는 script.js를 재작성하는 방법을 알려달라고 해보겠습니다.

User
show complete script.js

ChatGPT프롬프트 응답값 - script.js 재작성 요청

다음은 완성된 script.js 파일입니다.

document.addEventListener('DOMContentLoaded', function() {
const quizList = document.getElementById('quiz-list');
const quizDetail = document.getElementById('quiz-detail');
const backButton = document.getElementById('back-to-list');
const submitButton = document.getElementById('submit-quiz');

let currentQuizIndex = 0; // 현재 퀴즈 인덱스를 저장

// 퀴즈 목록 데이터
const quizzes = [
{
title: '역사 퀴즈',
questions: [
{
question: '고려시대의 수도는 어디인가요?',
options: ['서울', '경주', '강릉', '가야'],
answer: 0
},
{
question: '세종대왕이 창제한 한글의 원래 이름은 무엇인가요?',
options: ['훈민정음', '훈민한글', '옛글', '고대한글'],
answer: 0
}
]
},
{
title: '과학 퀴즈',
questions: [
{
question: '물이 끓는 온도는 몇 도인가요?',
options: ['0도', '50도', '100도', '150도'],
answer: 2
},
{
question: '태양계에서 가장 큰 행성은 어느 행성인가요?',
options: ['지구', '화성', '목성', '토성'],
answer: 2
}
]
}
];

function createQuizCard(quiz, index) {
const card = document.createElement('div');
card.setAttribute('class', 'quiz-card');
card.innerHTML = `<h3>${quiz.title}</h3>`;
card.addEventListener('click', () => showQuizDetail(index));
return card;
}

function createQuizQuestion(question, index) {
const questionElement = document.createElement('div');
questionElement.setAttribute('class', 'quiz-question');
questionElement.innerHTML = `<h4>Q${index + 1}: ${question.question}</h4>`;

const optionsElement = document.createElement('div');
optionsElement.setAttribute('class', 'quiz-options');

question.options.forEach((option, i) => {
const optionElement = document.createElement('label');
optionElement.innerHTML = `
<input type="radio" name="question-${index}" value="${i}">
<span>${option}</span>
`;
optionsElement.appendChild(optionElement);
});

questionElement.appendChild(optionsElement);
return questionElement;
}

function showQuizDetail(index) {
currentQuizIndex = index; // 현재 퀴즈 인덱스를 저장
quizList.style.display = 'none';
quizDetail.style.display = 'block';

const quiz = quizzes[index];
document.getElementById('quiz-title').textContent = quiz.title;

const quizQuestions = document.getElementById('quiz-questions');
quizQuestions.innerHTML = '';

quiz.questions.forEach((question, i) => {
const questionElement = createQuizQuestion(question, i);
quizQuestions.appendChild(questionElement);
});
}

function hideQuizDetail() {
quizDetail.style.display = 'none';
quizList.style.display = 'block';
}

function calculateQuizResult() {
const quiz = quizzes[currentQuizIndex]; // 현재 퀴즈에 대한 정보를 가져옵니다.
let correctAnswers = 0;

quiz.questions.forEach((question, index) => {
const selectedOption = document.querySelector(`input[name="question-${index}"]:checked`);

if (selectedOption && parseInt(selectedOption.value) === question.answer) {
correctAnswers++;
}
});

return {
totalQuestions: quiz.questions.length,
correctAnswers: correctAnswers
};
}

function showQuizResult(result) {
const resultMessage = `정답 수: ${result.correctAnswers} / ${result.totalQuestions}`;
alert(resultMessage);
}

// 퀴즈 목록을 생성하고 페이지에 삽입
for (const [index, quiz] of quizzes.entries()) {
const card = createQuizCard(quiz, index);
quizList.querySelector('.row').appendChild(card);
}

backButton.addEventListener('click', hideQuizDetail);
submitButton.addEventListener('click', () => {
const result = calculateQuizResult();
showQuizResult(result);
});
});

이제 이 스크립트를 사용하면 퀴즈 카드가 표시되고, 퀴즈 세부 정보를 볼 수 있으며, 퀴즈 결과를 계산하고 표시할 수 있습니다. 이 코드를 script.js 파일에 붙여 넣으세요. 이전에 제공한 index.htmlstyles.css 파일과 함께 사용하세요.

5. 코드 Codepen에 업로드 및 Netlify를 이용한 배포

완성된 코드를 Codepen에 작성하고 Netlify를 이용하여 배포해보겠습니다. HTML, CSS 및 JavaScript 섹션을 작성 하셨다면 CodePen 저장 및 내보내기Netlify에 배포를 참고 하셔서 배포 하실수 있습니다.

위의 순서로 따라서 만들어보니 정말 간단하게 아래와 같은 간단한 퀴즈 페이지가 만들어졌습니다.

퀴즈 웹서비스 - 퀴즈 목록 퀴즈 웹서비스 - 퀴즈 상세

7. 마치며

지금까지 간단한 일반 상식 퀴즈 웹사이트를 만들어보면서 출시 까지 해보았는데 도움이 되셨나요? 간단한 일반 상식 퀴즈 웹서비스를 만들어본 경험을 통해 코딩에 더 흥미를 가지는 계기가 되었으면 좋겠습니다.

참고로 완성된 소스 코드는 GitHub 링크에서 확인 하실수 있습니다.