Spaces:
Sleeping
Sleeping
| /** | |
| * ジャンルマスターデータ | |
| * | |
| * 中学受験4教科のジャンル分類を定義 | |
| * | |
| * @version 1.0.0 | |
| * @date 2025-12-07 | |
| */ | |
| // ============================================================================ | |
| // ジャンルマスターデータ | |
| // ============================================================================ | |
| /** | |
| * 中学受験4教科のジャンル分類マスターデータ | |
| * @constant {Object} | |
| */ | |
| var GENRE_MASTER = { | |
| // 国語(8ジャンル) | |
| jp: { | |
| subject_id: 'jp', | |
| subject_name: '国語', | |
| genres: [ | |
| { | |
| id: 'JP01', | |
| name: '漢字・語彙', | |
| description: '読み書き、四字熟語、慣用句、ことわざ' | |
| }, | |
| { | |
| id: 'JP02', | |
| name: '文法・言葉のきまり', | |
| description: '品詞、敬語、文の成分、修飾関係' | |
| }, | |
| { | |
| id: 'JP03', | |
| name: '物語文読解', | |
| description: '心情理解、場面把握、人物関係' | |
| }, | |
| { | |
| id: 'JP04', | |
| name: '説明文・論説文読解', | |
| description: '要旨、段落構成、筆者の主張' | |
| }, | |
| { | |
| id: 'JP05', | |
| name: '随筆文読解', | |
| description: '筆者の体験・感想の読み取り' | |
| }, | |
| { | |
| id: 'JP06', | |
| name: '詩・韻文', | |
| description: '詩、短歌、俳句、表現技法' | |
| }, | |
| { | |
| id: 'JP07', | |
| name: '記述問題', | |
| description: '理由説明、要約、意見記述' | |
| }, | |
| { | |
| id: 'JP08', | |
| name: '知識・文学史', | |
| description: '作家、作品名、文学的常識' | |
| } | |
| ] | |
| }, | |
| // 算数(10ジャンル) | |
| math: { | |
| subject_id: 'math', | |
| subject_name: '算数', | |
| genres: [ | |
| { | |
| id: 'MA01', | |
| name: '計算', | |
| description: '四則演算、分数・小数、逆算' | |
| }, | |
| { | |
| id: 'MA02', | |
| name: '数の性質', | |
| description: '約数・倍数、素因数分解、規則性' | |
| }, | |
| { | |
| id: 'MA03', | |
| name: '割合・比', | |
| description: '割合、比、百分率、歩合' | |
| }, | |
| { | |
| id: 'MA04', | |
| name: '速さ', | |
| description: '旅人算、通過算、流水算、時計算' | |
| }, | |
| { | |
| id: 'MA05', | |
| name: '文章題(その他)', | |
| description: '濃度、仕事算、ニュートン算、差集め算' | |
| }, | |
| { | |
| id: 'MA06', | |
| name: '平面図形', | |
| description: '面積、角度、相似、合同' | |
| }, | |
| { | |
| id: 'MA07', | |
| name: '立体図形', | |
| description: '体積、表面積、展開図、切断' | |
| }, | |
| { | |
| id: 'MA08', | |
| name: '場合の数・確率', | |
| description: '順列、組み合わせ、確率' | |
| }, | |
| { | |
| id: 'MA09', | |
| name: 'グラフ・表', | |
| description: '統計、変化のグラフ、ダイヤグラム' | |
| }, | |
| { | |
| id: 'MA10', | |
| name: '特殊算', | |
| description: 'つるかめ算、消去算、過不足算' | |
| } | |
| ] | |
| }, | |
| // 理科(12ジャンル) | |
| sci: { | |
| subject_id: 'sci', | |
| subject_name: '理科', | |
| genres: [ | |
| { | |
| id: 'SC01', | |
| name: '力・運動', | |
| description: 'てこ、滑車、ばね、浮力、振り子' | |
| }, | |
| { | |
| id: 'SC02', | |
| name: '電気', | |
| description: '回路、抵抗、電磁石、発熱' | |
| }, | |
| { | |
| id: 'SC03', | |
| name: '光・音・熱', | |
| description: '反射、屈折、レンズ、音の性質' | |
| }, | |
| { | |
| id: 'SC04', | |
| name: '物質の性質', | |
| description: '金属、気体、密度、状態変化' | |
| }, | |
| { | |
| id: 'SC05', | |
| name: '水溶液', | |
| description: '酸・アルカリ、中和、溶解度' | |
| }, | |
| { | |
| id: 'SC06', | |
| name: '燃焼・化学変化', | |
| description: '燃焼、酸化還元、化合' | |
| }, | |
| { | |
| id: 'SC07', | |
| name: '植物', | |
| description: 'つくり、光合成、蒸散、分類' | |
| }, | |
| { | |
| id: 'SC08', | |
| name: '動物', | |
| description: 'からだのつくり、行動、分類' | |
| }, | |
| { | |
| id: 'SC09', | |
| name: '人体', | |
| description: '消化、呼吸、血液循環、感覚器官' | |
| }, | |
| { | |
| id: 'SC10', | |
| name: '天体', | |
| description: '太陽、月、星座、地球の運動' | |
| }, | |
| { | |
| id: 'SC11', | |
| name: '気象', | |
| description: '天気、気温、湿度、雲、季節風' | |
| }, | |
| { | |
| id: 'SC12', | |
| name: '地学', | |
| description: '地層、岩石、火山、地震' | |
| } | |
| ] | |
| }, | |
| // 社会(10ジャンル) | |
| soc: { | |
| subject_id: 'soc', | |
| subject_name: '社会', | |
| genres: [ | |
| { | |
| id: 'SO01', | |
| name: '日本地理(国土・自然)', | |
| description: '地形、気候、都道府県' | |
| }, | |
| { | |
| id: 'SO02', | |
| name: '日本地理(産業)', | |
| description: '農業、工業、水産業、商業' | |
| }, | |
| { | |
| id: 'SO03', | |
| name: '世界地理', | |
| description: '大陸、国、貿易、環境問題' | |
| }, | |
| { | |
| id: 'SO04', | |
| name: '歴史(古代〜平安)', | |
| description: '旧石器〜平安時代' | |
| }, | |
| { | |
| id: 'SO05', | |
| name: '歴史(鎌倉〜室町)', | |
| description: '武士の台頭、文化' | |
| }, | |
| { | |
| id: 'SO06', | |
| name: '歴史(安土桃山〜江戸)', | |
| description: '統一、鎖国、元禄・化政文化' | |
| }, | |
| { | |
| id: 'SO07', | |
| name: '歴史(明治〜現代)', | |
| description: '近代化、戦争、戦後' | |
| }, | |
| { | |
| id: 'SO08', | |
| name: '公民(政治・憲法)', | |
| description: '三権分立、選挙、人権' | |
| }, | |
| { | |
| id: 'SO09', | |
| name: '公民(経済・国際)', | |
| description: '経済の仕組み、国際機関、SDGs' | |
| }, | |
| { | |
| id: 'SO10', | |
| name: '時事問題', | |
| description: '直近1〜2年のニュース' | |
| } | |
| ] | |
| } | |
| }; | |
| // ============================================================================ | |
| // ヘルパー関数 | |
| // ============================================================================ | |
| /** | |
| * ジャンルIDからジャンル情報を取得 | |
| * | |
| * @param {string} genreId - ジャンルID(例: 'JP01', 'MA05') | |
| * @returns {Object|null} - ジャンル情報 { id, name, description, subject_id, subject_name } または null | |
| * | |
| * @example | |
| * var genre = getGenreById('JP01'); | |
| * // => { id: 'JP01', name: '漢字・語彙', description: '...', subject_id: 'jp', subject_name: '国語' } | |
| */ | |
| function getGenreById(genreId) { | |
| if (!genreId || typeof genreId !== 'string') { | |
| return null; | |
| } | |
| var upperGenreId = genreId.toUpperCase(); | |
| // 全教科を検索 | |
| var subjects = ['jp', 'math', 'sci', 'soc']; | |
| for (var i = 0; i < subjects.length; i++) { | |
| var subjectId = subjects[i]; | |
| var subjectData = GENRE_MASTER[subjectId]; | |
| var genres = subjectData.genres; | |
| for (var j = 0; j < genres.length; j++) { | |
| var genre = genres[j]; | |
| if (genre.id === upperGenreId) { | |
| // ジャンル情報に教科情報を追加して返却 | |
| return { | |
| id: genre.id, | |
| name: genre.name, | |
| description: genre.description, | |
| subject_id: subjectData.subject_id, | |
| subject_name: subjectData.subject_name | |
| }; | |
| } | |
| } | |
| } | |
| return null; | |
| } | |
| /** | |
| * 教科のジャンル一覧を取得 | |
| * | |
| * @param {string} subjectId - 教科ID(jp, math, sci, soc) | |
| * @returns {Array} - ジャンル配列(見つからない場合は空配列) | |
| * | |
| * @example | |
| * var genres = getGenresBySubject('jp'); | |
| * // => [{ id: 'JP01', name: '漢字・語彙', ... }, ...] | |
| */ | |
| function getGenresBySubject(subjectId) { | |
| if (!subjectId || typeof subjectId !== 'string') { | |
| return []; | |
| } | |
| var subjectData = GENRE_MASTER[subjectId.toLowerCase()]; | |
| if (!subjectData) { | |
| return []; | |
| } | |
| return subjectData.genres; | |
| } | |
| /** | |
| * 全ジャンル数を取得 | |
| * | |
| * @returns {number} - 総ジャンル数(40) | |
| * | |
| * @example | |
| * var total = getTotalGenreCount(); | |
| * // => 40 | |
| */ | |
| function getTotalGenreCount() { | |
| var count = 0; | |
| var subjects = ['jp', 'math', 'sci', 'soc']; | |
| for (var i = 0; i < subjects.length; i++) { | |
| var subjectId = subjects[i]; | |
| count += GENRE_MASTER[subjectId].genres.length; | |
| } | |
| return count; | |
| } | |
| /** | |
| * ジャンルIDの検証 | |
| * | |
| * @param {string} genreId - ジャンルID | |
| * @returns {boolean} - 有効なジャンルIDかどうか | |
| * | |
| * @example | |
| * isValidGenreId('JP01'); // => true | |
| * isValidGenreId('XX99'); // => false | |
| */ | |
| function isValidGenreId(genreId) { | |
| return getGenreById(genreId) !== null; | |
| } | |
| /** | |
| * Dify用のジャンルリストを生成(問題生成プロンプト用) | |
| * | |
| * @param {string} subjectId - 教科ID(jp, math, sci, soc) | |
| * @returns {string} - ジャンルリストの文字列(改行区切り) | |
| * | |
| * @example | |
| * var list = getGenreListForDify('jp'); | |
| * // => "JP01: 漢字・語彙(読み書き、四字熟語、慣用句、ことわざ)\n..." | |
| */ | |
| function getGenreListForDify(subjectId) { | |
| var genres = getGenresBySubject(subjectId); | |
| if (genres.length === 0) { | |
| return ''; | |
| } | |
| var lines = []; | |
| for (var i = 0; i < genres.length; i++) { | |
| var genre = genres[i]; | |
| var line = genre.id + ': ' + genre.name + '(' + genre.description + ')'; | |
| lines.push(line); | |
| } | |
| return lines.join('\n'); | |
| } | |
| // ============================================================================ | |
| // テスト関数(GASエディタで実行可能) | |
| // ============================================================================ | |
| /** | |
| * GenreMaster.jsのテスト関数 | |
| * GASエディタで実行して動作確認 | |
| */ | |
| function testGenreMaster() { | |
| Logger.log('=== GenreMaster.js テスト開始 ==='); | |
| // テスト1: ジャンル総数 | |
| var totalCount = getTotalGenreCount(); | |
| Logger.log('テスト1: 総ジャンル数 = ' + totalCount + ' (期待値: 40)'); | |
| // テスト2: ジャンルID検索 | |
| var genre1 = getGenreById('JP01'); | |
| Logger.log('テスト2: getGenreById("JP01") = ' + JSON.stringify(genre1)); | |
| var genre2 = getGenreById('MA05'); | |
| Logger.log('テスト2: getGenreById("MA05") = ' + JSON.stringify(genre2)); | |
| // テスト3: 教科別ジャンル取得 | |
| var jpGenres = getGenresBySubject('jp'); | |
| Logger.log('テスト3: 国語ジャンル数 = ' + jpGenres.length + ' (期待値: 8)'); | |
| var mathGenres = getGenresBySubject('math'); | |
| Logger.log('テスト3: 算数ジャンル数 = ' + mathGenres.length + ' (期待値: 10)'); | |
| var sciGenres = getGenresBySubject('sci'); | |
| Logger.log('テスト3: 理科ジャンル数 = ' + sciGenres.length + ' (期待値: 12)'); | |
| var socGenres = getGenresBySubject('soc'); | |
| Logger.log('テスト3: 社会ジャンル数 = ' + socGenres.length + ' (期待値: 10)'); | |
| // テスト4: ジャンルID検証 | |
| var valid1 = isValidGenreId('JP01'); | |
| Logger.log('テスト4: isValidGenreId("JP01") = ' + valid1 + ' (期待値: true)'); | |
| var valid2 = isValidGenreId('XX99'); | |
| Logger.log('テスト4: isValidGenreId("XX99") = ' + valid2 + ' (期待値: false)'); | |
| // テスト5: Dify用ジャンルリスト生成 | |
| var jpList = getGenreListForDify('jp'); | |
| Logger.log('テスト5: 国語ジャンルリスト(最初の100文字):'); | |
| Logger.log(jpList.substring(0, 100) + '...'); | |
| Logger.log('=== GenreMaster.js テスト完了 ==='); | |
| } | |