IT1-CODE-POCKET
問題を解くための設定画面
PythonまたはDNCL選択画面
プロジェクト概要
IT1-CODE-POCKETは、共通テスト「情報Ⅰ」第3問で扱われるプログラミング・アルゴリズム分野の学習を補助するために開発したWebアプリです。スマートフォンで短時間でも取り組めるよう、PythonモードとDNCLモードのクイズ、難易度別の出題、問題数選択、解説表示、間違えた問題の復習機能を実装しました。 単なるクイズ画面だけでなく、共通テスト用プログラム表記の解説ページ、重要アルゴリズムの解説ページ、プライバシーポリシーやお問い合わせページも用意し、公開サイトとして運用できる構成にしています。
開発目的
- 共通テスト「情報Ⅰ」第3問の学習をスマートフォンで手軽に行えるようにするため
- PythonとDNCLの両方に対応した演習環境を作るため
- クイズ、解説、復習を組み合わせて学習しやすい流れを作るため
- 静的サイトでも実用的な学習アプリを実装するため
- 独自ドメイン、SEO、OGP、AdSense対応まで含めた公開運用を経験するため
使用技術
プログラミング言語
JavaScript
フロントエンド
HTML5
CSS3
Vanilla JavaScript
Tailwind CSS CDN
バックエンド / 外部サービス
GitHub Pages
Cloudflare
Google Search Console
Google AdSense
Google Forms
localStorage
主な機能
- Python / DNCL の言語モード選択
- 基礎 / 標準 / 発展の難易度選択
- 5問 / 10問 / 20問 / 40問の問題数選択
- ランダム出題と同一セッション内の重複防止
- 回答後の正誤判定と解説表示
- 中断したクイズの保存と再開
- 間違えた問題だけを復習する機能
- 復習で正解した問題を復習リストから自動削除
- テーマ切り替え(シンプル、クールブラック、ポップ)
- 共通テスト用プログラム表記の解説ページ
- 重要アルゴリズムの解説ページ
- SNS共有ボタン
- OGP / favicon / app icon 対応
- サイトマップ、robots.txt、ads.txt対応
システム構成
バックエンドを持たない静的Webアプリとして構成しています。問題データと画面制御はJavaScriptで管理し、クイズの中断データや復習リスト、テーマ設定はブラウザのlocalStorageに保存します。GitHub Pagesで公開し、独自ドメインとHTTPSはCloudflareおよびGitHub Pagesの設定で運用しています。
データフロー
ユーザーが言語モード、難易度、問題数を選択
↓ スタート
条件に合う問題を抽出し、ランダムに並び替え
↓ 出題
ユーザーが選択肢を回答
↓ 判定
正解ならスコア加算、不正解なら復習リストへ保存
↓ 解説表示
次の問題へ進む、または結果画面を表示
↓ 必要に応じて
中断データを保存、または復習リストから再演習
工夫した点
- スマートフォンで片手操作しやすい画面構成にした
- クイズ中のヘッダー操作を「中断」「戻る」に整理した
- 中断データと復習リストを独立して管理し、片方の操作でもう片方が消えないようにした
- 復習・再開ボタンをヘッダー内に表示し、必要な時だけアクセスできるようにした
- PythonとDNCLで問題数や難易度のバランスを取るようにした
- DNCL表記がPython風になりすぎないよう、記号や用語を調整した
- 選択肢のインデントやラベル幅を調整し、コード選択肢を読みやすくした
- テーマ切り替え時の一瞬の表示ズレを防ぐため、初期テーマ反映用スクリプトを用意した
- OGP、favicon、SNS共有、sitemap、robots.txt、ads.txtまで整備し、公開サイトとして扱えるようにした
技術的ハイライト
1. ランダム出題と問題数制御
function shuffleQuestions(questions) {
const shuffled = [...questions];
for (let i = shuffled.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
}
return shuffled;
}
function startQuiz() {
const targetQuestions = QUESTIONS.filter(q =>
q.langMode === state.langMode && q.difficulty === state.difficulty
);
if (targetQuestions.length === 0) {
alert('該当する問題がありません。言語モードまたは難易度を変更してください。');
return;
}
state.questions = shuffleQuestions(targetQuestions).slice(0, Math.min(state.questionCount, targetQuestions.length));
state.quizMode = 'normal';
state.currentIndex = 0;
state.score = 0;
state.answered = false;
state.selectedIndex = null;
closeLearningStatusModal();
showScreen('screen-quiz');
renderQuestion();
saveSession();
updateHeaderStats();
}
2. localStorageを使った中断・復習データ管理
const SESSION_KEY = 'quiz-saved-session-v1';
const REVIEW_KEY = 'quiz-review-question-ids-v1';
function saveSession() {
if (!state.questions.length) return;
if (state.quizMode === 'review') return;
const session = {
langMode: state.langMode,
difficulty: state.difficulty,
questionCount: state.questionCount,
quizMode: state.quizMode,
questionIds: state.questions.map(q => q.id),
currentIndex: state.currentIndex,
score: state.score,
answered: state.answered,
selectedIndex: state.selectedIndex,
savedAt: new Date().toISOString()
};
localStorage.setItem(SESSION_KEY, JSON.stringify(session));
updateResumeCard();
updateHeaderStats();
}
function addReviewQuestion(questionId) {
saveReviewQuestionIds([...getReviewQuestionIds(), questionId]);
}
function removeReviewQuestion(questionId) {
saveReviewQuestionIds(getReviewQuestionIds().filter(id => id !== questionId));
}
3. テーマのちらつきを防ぐ初期化処理
(function initThemeBeforePaint() {
try {
const theme = localStorage.getItem('quiz-theme');
if (['simple', 'cool', 'pop'].includes(theme)) {
document.documentElement.setAttribute('data-theme', theme);
}
} catch {
// localStorage が使えない環境では初期テーマのまま表示する。
}
})();
開発情報
開発形態
個人開発
役割
企画、設計、UI作成、問題作成、フロントエンド実装、公開設定、SEO対応、AdSense準備
制作期間
約1〜2週間
開発時の注意事項
本プロジェクトは、学習支援およびポートフォリオ掲載を目的として開発しました。公開サイトとして運用するため、学習内容の扱い、個人情報、外部サービス、広告審査に関する点に配慮しています。
学習コンテンツとしての配慮
- 共通テスト本番での出題を保証する表現は避けた
- 「問われやすい」ではなく「学んでおくと理解に役立つ」という表現に調整した
- PythonとDNCLの表記が混ざらないように見直した
- 解説文や選択肢の見やすさを優先して調整した
個人情報・データ保存への配慮
- クイズの中断データや復習リストはlocalStorageに保存し、サーバーへ送信しない設計にした
- お問い合わせはGoogleフォームを利用し、プライバシーポリシーで取り扱いを明記した
- ログイン機能や個人識別を前提としない構成にした
公開・広告運用への配慮
- 独自ドメインとHTTPSで公開できるようにした
- sitemap.xmlとrobots.txtを用意した
- OGP、favicon、app iconを設定した
- AdSenseコードとads.txtを設置した
- プライバシーポリシー、お問い合わせ、利用規約・免責事項、このサイトについてのページを用意した
謝辞
- MDN Web Docs: HTML、CSS、JavaScriptの仕様確認
- Google Search Console: サイト公開後のインデックス確認
- Google AdSense: 広告審査およびads.txt設定
- Cloudflare: DNS管理と独自ドメイン運用
- GitHub Pages: 静的サイトのホスティング