feat(math6): Глава 1, волна 3 — §7–§10 (деление, период, преобразования)

§7 деление на натуральное (тренажёр + восстанови делимое);
§8 деление на десятичную (демонстратор переноса запятой + тренажёр);
§9 конечная/бесконечная (классификатор по множителям 2·5 + период через
долгое деление с отслеживанием остатков, выбор десятичной записи);
§10 сопоставление десятичная↔обыкновенная (DnD) + вычисление выражений.
Шпаргалки/типсы/глоссарий §7–§10. Тесты 11/11.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-06-02 15:03:30 +03:00
parent dd0d63d25a
commit 826e7b04f2
2 changed files with 270 additions and 4 deletions
+17
View File
@@ -104,6 +104,23 @@ test('ch1 Волна 2: интерактивы §4–§6 монтируются
assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | '));
});
test('ch1 Волна 3: интерактивы §7–§10 монтируются без ошибок', async () => {
const { doc, errors } = await loadDom('math_6_ch1.html');
const win = doc.defaultView;
win.goTo('p7'); await wait(80);
assert.ok(doc.querySelector('#p7-q') && doc.querySelector('#p7-rq'), 'тренажёры деления §7');
win.goTo('p8'); await wait(80);
assert.ok(doc.querySelector('#p8-pick [data-k]'), 'выбор примеров §8');
assert.ok(doc.querySelector('#p8-out').textContent.indexOf('=') >= 0, 'демонстратор переноса запятой §8');
win.goTo('p9'); await wait(80);
assert.ok(doc.querySelector('#p9-iv1 [data-fin]'), 'классификатор §9');
assert.ok(doc.querySelectorAll('#p9-dopts [data-o]').length === 3, 'варианты десятичной §9');
win.goTo('p10'); await wait(80);
assert.ok(doc.querySelectorAll('#p10-pool .dnd-chip').length === 5, 'сопоставление дробей §10');
assert.ok(doc.querySelector('#p10-q'), 'выражения §10');
assert.deepEqual(errors, [], 'нет ошибок: ' + errors.join(' | '));
});
test('навигация и прогресс: переход на § и отметка прочтения', async () => {
const { doc, errors } = await loadDom('math_6_ch1.html');
const win = doc.defaultView;
+253 -4
View File
@@ -494,6 +494,228 @@ function buildP6(){
})();
}
/* ===================== § 7. ДЕЛЕНИЕ НА НАТУРАЛЬНОЕ ЧИСЛО ===================== */
function _gcd(a,b){ a=Math.abs(a);b=Math.abs(b); while(b){ var t=b; b=a%b; a=t; } return a||1; }
function _finite(p,q){ var g=_gcd(p,q); q=q/g; while(q%2===0)q/=2; while(q%5===0)q/=5; return q===1; }
function _fracDec(p,q){ var ip=Math.floor(p/q), rem=p%q; if(rem===0)return String(ip); var dg='',seen={},pos=0,ps=-1;
while(rem!==0){ if(seen[rem]!==undefined){ ps=seen[rem]; break; } seen[rem]=pos; rem*=10; dg+=Math.floor(rem/q); rem%=q; pos++; }
if(rem===0) return ip+','+dg; return ip+','+dg.slice(0,ps)+'('+dg.slice(ps)+')'; }
function buildP7(){
var box=document.getElementById('p7-body'); var h='';
h+=makeCard('rule','Деление десятичной дроби на натуральное число','7.1',
'<p>Делят «уголком», как натуральные числа. Как только заканчивается <b>целая</b> часть делимого, в частном ставят <b>запятую</b> и продолжают деление.</p>'
+'<p>Если делимое меньше делителя, целая часть частного равна $0$. Если деление «не заканчивается» — дописывают нули к делимому.</p>');
h+=makeCard('example','Примеры','7.2',
'<p>$7{,}2 \\div 3 = 2{,}4$ &nbsp;·&nbsp; $1 \\div 4 = 0{,}25$ &nbsp;·&nbsp; $9{,}6 \\div 8 = 1{,}2$</p>');
h+='<div class="wg" id="p7-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Тренажёр деления</div></div>'
+'<div class="wg-help">Раздели десятичную дробь на натуральное число. Ответ — десятичная дробь.</div>'
+'<div class="score-display"><span>Пример <b id="p7-i">1</b> / 6</span><span>Очки: <b id="p7-s">0</b> / 6</span></div>'
+'<div id="p7-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p7-a" class="tinp" style="width:130px;text-align:center" placeholder="ответ"><button class="btn primary" id="p7-go">Проверить</button></div>'
+'<div class="feedback" id="p7-fb"></div></div>';
h+='<div class="wg" id="p7-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Восстанови делимое</div></div>'
+'<div class="wg-help">Известны частное и делитель. Найди делимое (проверка делением наоборот).</div>'
+'<div class="score-display"><span>Пример <b id="p7-ri">1</b> / 5</span><span>Очки: <b id="p7-rs">0</b> / 5</span></div>'
+'<div id="p7-rq" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p7-ra" class="tinp" style="width:130px;text-align:center" placeholder="делимое"><button class="btn primary" id="p7-rgo">Проверить</button></div>'
+'<div class="feedback" id="p7-rfb"></div></div>';
h+=secNav('p6','p8')+readBtn('p7');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var r=_rnum(_pick([1,1,2])), n=_ri(2,9), dr=_dec(r), a=_mant(r,dr)*n/Math.pow(10,dr); cur={a:a,n:n,r:r}; }
function show(){ if(i>=6){ document.getElementById('p7-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p7-iv1');bumpProgress('p7',30);}else if(score>=3){addXp(8,'p7-iv1');bumpProgress('p7',16);} return; }
gen(); document.getElementById('p7-i').textContent=i+1;
document.getElementById('p7-q').innerHTML='Вычисли $'+_kf(cur.a)+' \\div '+cur.n+'$'; renderMath(document.getElementById('p7-q'));
document.getElementById('p7-a').value=''; document.getElementById('p7-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p7-fb'), v=parseFloat(document.getElementById('p7-a').value.replace(',','.').trim());
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.r)<1e-9){ score++; feedback(fb,true,'✓ Верно: $'+_kf(cur.r)+'$.'); } else feedback(fb,false,'✗ Нет. Правильно: $'+_kf(cur.r)+'$.');
document.getElementById('p7-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p7-go').addEventListener('click',go);
document.getElementById('p7-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show();
})();
(function(){
var i=0,score=0,cur=null;
function gen(){ var r=_rnum(_pick([1,2])), n=_ri(2,9), dr=_dec(r), a=_mant(r,dr)*n/Math.pow(10,dr); cur={a:a,n:n,r:r}; }
function show(){ if(i>=5){ document.getElementById('p7-rq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; if(score>=4){addXp(15,'p7-iv2');bumpProgress('p7',30);}else if(score>=2){addXp(8,'p7-iv2');bumpProgress('p7',16);} return; }
gen(); document.getElementById('p7-ri').textContent=i+1;
document.getElementById('p7-rq').innerHTML='Частное $'+_kf(cur.r)+'$, делитель $'+cur.n+'$. Чему равно делимое?'; renderMath(document.getElementById('p7-rq'));
document.getElementById('p7-ra').value=''; document.getElementById('p7-rfb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p7-rfb'), v=parseFloat(document.getElementById('p7-ra').value.replace(',','.').trim());
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.a)<1e-9){ score++; feedback(fb,true,'✓ Верно: $'+_kf(cur.a)+' \\div '+cur.n+' = '+_kf(cur.r)+'$.'); } else feedback(fb,false,'✗ Нет. Делимое: $'+_kf(cur.a)+'$.');
document.getElementById('p7-rs').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p7-rgo').addEventListener('click',go);
document.getElementById('p7-ra').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show();
})();
}
/* ===================== § 8. ДЕЛЕНИЕ НА ДЕСЯТИЧНУЮ ДРОБЬ ===================== */
function buildP8(){
var box=document.getElementById('p8-body'); var h='';
h+=makeCard('rule','Деление на десятичную дробь','8.1',
'<p>Чтобы разделить на десятичную дробь, в <b>делимом и делителе</b> переносят запятую вправо на столько знаков, сколько их после запятой у <b>делителя</b>. Получается деление на <b>натуральное</b> число.</p>'
+'<p>$4{,}5 \\div 0{,}5 = 45 \\div 5 = 9$ &nbsp;·&nbsp; $1{,}2 \\div 0{,}03 = 120 \\div 3 = 40$.</p>');
h+=makeCard('example','Почему так можно','8.2',
'<p>Деление — это дробь. Умножив делимое и делитель на одно и то же число ($10$, $100$…), значение дроби не меняется: $\\dfrac{4{,}5}{0{,}5}=\\dfrac{45}{5}=9$.</p>');
h+='<div class="wg" id="p8-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Превращаем в деление на натуральное</div></div>'
+'<div class="wg-help">Выбери пример — увидишь, как перенос запятой превращает делитель в натуральное число.</div>'
+'<div id="p8-pick" style="display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-bottom:10px"></div>'
+'<div id="p8-out" class="qbox"></div></div>';
h+='<div class="wg" id="p8-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Тренажёр деления</div></div>'
+'<div class="wg-help">Раздели на десятичную дробь. Ответ — целое или десятичная дробь.</div>'
+'<div class="score-display"><span>Пример <b id="p8-i">1</b> / 6</span><span>Очки: <b id="p8-s">0</b> / 6</span></div>'
+'<div id="p8-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p8-a" class="tinp" style="width:130px;text-align:center" placeholder="ответ"><button class="btn primary" id="p8-go">Проверить</button></div>'
+'<div class="feedback" id="p8-fb"></div></div>';
h+=secNav('p7','p9')+readBtn('p8');
box.innerHTML=h; renderMath(box);
function mk(R,b){ var db=_dec(b), a=_mant(R,0)*_mant(b,db)/Math.pow(10,db); return {a:a,b:b,R:R,k:db,a2:_mant(a, _dec(a)), }; }
(function(){
var EX=[[9,0.5],[40,0.03],[6,0.25],[12,1.5],[8,0.2],[15,0.4]];
var pick=document.getElementById('p8-pick'), out=document.getElementById('p8-out');
pick.innerHTML=EX.map(function(e,k){ return '<button class="btn'+(k===0?' primary':'')+'" data-k="'+k+'">$'+_kf(_round(e[0]*e[1], _dec(e[1])))+' \\div '+_kf(e[1])+'$</button>'; }).join('');
function render(k){ var R=EX[k][0], b=EX[k][1], db=_dec(b), a=_round(R*b,db); var a2=_round(a*Math.pow(10,db), Math.max(0,_dec(a)-db)), b2=Math.round(b*Math.pow(10,db));
out.innerHTML='<div style="font-size:1.3rem;font-weight:800;color:var(--pri2)">$'+_kf(a)+' \\div '+_kf(b)+' = '+a2+' \\div '+b2+' = '+R+'$</div>'
+'<div style="font-size:.88rem;color:var(--muted);margin-top:6px">Переносим запятую на '+db+' '+(db===1?'знак':'знака')+' вправо у обоих чисел.</div>'; renderMath(out); }
pick.querySelectorAll('[data-k]').forEach(function(b){ b.addEventListener('click',function(){ pick.querySelectorAll('button').forEach(function(x){x.classList.remove('primary');}); b.classList.add('primary'); render(+b.getAttribute('data-k')); }); });
render(0);
})();
(function(){
var i=0,score=0,cur=null, BS=[0.5,0.2,0.25,0.4,0.05,1.5,0.8,0.3];
function gen(){ var R=_ri(2,30), b=_pick(BS), db=_dec(b), a=_round(R*b,db); cur={a:a,b:b,R:R}; }
function show(){ if(i>=6){ document.getElementById('p8-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p8-iv2');bumpProgress('p8',30);}else if(score>=3){addXp(8,'p8-iv2');bumpProgress('p8',16);} return; }
gen(); document.getElementById('p8-i').textContent=i+1;
document.getElementById('p8-q').innerHTML='Вычисли $'+_kf(cur.a)+' \\div '+_kf(cur.b)+'$'; renderMath(document.getElementById('p8-q'));
document.getElementById('p8-a').value=''; document.getElementById('p8-fb').style.display='none'; }
function go(){ if(i>=6)return; var fb=document.getElementById('p8-fb'), v=parseFloat(document.getElementById('p8-a').value.replace(',','.').trim());
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur.R)<1e-9){ score++; feedback(fb,true,'✓ Верно: $'+cur.R+'$.'); } else feedback(fb,false,'✗ Нет. Правильно: $'+cur.R+'$.');
document.getElementById('p8-s').textContent=score; i++; setTimeout(show,1200); }
document.getElementById('p8-go').addEventListener('click',go);
document.getElementById('p8-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show();
})();
}
/* ===================== § 9. КОНЕЧНЫЕ И БЕСКОНЕЧНЫЕ ДРОБИ ===================== */
function buildP9(){
var box=document.getElementById('p9-body'); var h='';
h+=makeCard('theory','Конечные и бесконечные десятичные дроби','9.1',
'<p>Обыкновенную дробь обращают в десятичную <b>делением</b> числителя на знаменатель. Иногда деление заканчивается — получается <b>конечная</b> дробь ($\\tfrac{3}{4}=0{,}75$).</p>'
+'<p>Иногда цифры начинают <b>повторяться</b> без конца — это <b>бесконечная периодическая</b> дробь. Повторяющуюся группу (период) пишут в скобках: $\\tfrac{1}{3}=0{,}(3)$, $\\tfrac{1}{6}=0{,}1(6)$.</p>');
h+=makeCard('rule','Когда дробь конечная','9.2',
'<p>Несократимая обыкновенная дробь обращается в <b>конечную</b> десятичную тогда и только тогда, когда в разложении её знаменателя есть только множители <b>2 и 5</b>.</p>'
+'<p>$\\tfrac{7}{20}$ — конечная ($20=2^2\\cdot5$); $\\tfrac{5}{6}$ — бесконечная ($6=2\\cdot3$).</p>');
h+='<div class="wg" id="p9-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Конечная или бесконечная?</div></div>'
+'<div class="wg-help">Реши, обращается ли дробь в конечную десятичную (проверь множители знаменателя).</div>'
+'<div class="score-display"><span>Вопрос <b id="p9-i">1</b> / 6</span><span>Очки: <b id="p9-s">0</b> / 6</span></div>'
+'<div id="p9-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap"><button class="btn primary" data-fin="1">Конечная</button><button class="btn primary" data-fin="0">Бесконечная</button></div>'
+'<div class="feedback" id="p9-fb"></div></div>';
h+='<div class="wg" id="p9-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Запиши десятичную дробь</div></div>'
+'<div class="wg-help">Выбери верную десятичную запись дроби (период — в скобках).</div>'
+'<div class="score-display"><span>Вопрос <b id="p9-di">1</b> / 5</span><span>Очки: <b id="p9-ds">0</b> / 5</span></div>'
+'<div id="p9-dq" class="qbox"></div><div id="p9-dopts" style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap"></div>'
+'<div class="feedback" id="p9-dfb"></div></div>';
h+=secNav('p8','p10')+readBtn('p9');
box.innerHTML=h; renderMath(box);
(function(){
var i=0,score=0,cur=null;
function gen(){ var q=_ri(2,16), p=_ri(1,q-1), g=_gcd(p,q); p/=g; q/=g; cur={p:p,q:q,fin:_finite(p,q)}; }
function show(){ if(i>=6){ document.getElementById('p9-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 6'; if(score>=5){addXp(15,'p9-iv1');bumpProgress('p9',30);}else if(score>=3){addXp(8,'p9-iv1');bumpProgress('p9',16);} return; }
gen(); document.getElementById('p9-i').textContent=i+1;
document.getElementById('p9-q').innerHTML='Дробь $\\dfrac{'+cur.p+'}{'+cur.q+'}$ — какая десятичная?'; renderMath(document.getElementById('p9-q'));
document.getElementById('p9-fb').style.display='none'; }
function ans(f){ if(i>=6)return; var fb=document.getElementById('p9-fb'); var correct=cur.fin?1:0;
if(f===correct){ score++; feedback(fb,true,'✓ Верно — $\\dfrac{'+cur.p+'}{'+cur.q+'} = '+_fracDec(cur.p,cur.q).replace(/,/g,'{,}')+'$.'); } else feedback(fb,false,'✗ Нет. $\\dfrac{'+cur.p+'}{'+cur.q+'} = '+_fracDec(cur.p,cur.q).replace(/,/g,'{,}')+'$ — '+(cur.fin?'конечная':'бесконечная')+'.');
document.getElementById('p9-s').textContent=score; i++; setTimeout(show,1500); }
document.querySelectorAll('#p9-iv1 [data-fin]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-fin')); }); }); show();
})();
(function(){
var POOL=[[1,2],[1,4],[3,4],[1,5],[1,8],[3,8],[1,3],[2,3],[1,6],[5,6],[1,9],[7,10]];
var i=0,score=0,cur=null;
function gen(){ var f=_pick(POOL), correct=_fracDec(f[0],f[1]); var opts=[correct];
while(opts.length<3){ var g=_pick(POOL), s=_fracDec(g[0],g[1]); if(opts.indexOf(s)<0)opts.push(s); }
for(var j=opts.length-1;j>0;j--){ var k=_ri(0,j); var t=opts[j];opts[j]=opts[k];opts[k]=t; }
cur={f:f,correct:correct,opts:opts}; }
function show(){ if(i>=5){ document.getElementById('p9-dq').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; document.getElementById('p9-dopts').innerHTML=''; if(score>=4){addXp(15,'p9-iv2');bumpProgress('p9',30);}else if(score>=2){addXp(8,'p9-iv2');bumpProgress('p9',16);} return; }
gen(); document.getElementById('p9-di').textContent=i+1;
document.getElementById('p9-dq').innerHTML='$\\dfrac{'+cur.f[0]+'}{'+cur.f[1]+'} = ?$'; renderMath(document.getElementById('p9-dq'));
document.getElementById('p9-dopts').innerHTML=cur.opts.map(function(o){ return '<button class="btn primary" data-o="'+o+'">$'+o.replace(/,/g,'{,}')+'$</button>'; }).join('');
document.querySelectorAll('#p9-dopts [data-o]').forEach(function(b){ b.addEventListener('click',function(){ ans(b.getAttribute('data-o')); }); }); renderMath(document.getElementById('p9-dopts'));
document.getElementById('p9-dfb').style.display='none'; }
function ans(o){ if(i>=5)return; var fb=document.getElementById('p9-dfb');
if(o===cur.correct){ score++; feedback(fb,true,'✓ Верно!'); } else feedback(fb,false,'✗ Нет. Правильно: '+cur.correct.replace('.',','));
document.getElementById('p9-ds').textContent=score; i++; setTimeout(show,1300); }
show();
})();
}
/* ===================== § 10. ПРЕОБРАЗОВАНИЯ ВЫРАЖЕНИЙ ===================== */
function buildP10(){
var box=document.getElementById('p10-body'); var h='';
h+=makeCard('rule','Обыкновенные и десятичные вместе','10.1',
'<p>Десятичную дробь переводят в обыкновенную «по разрядам» и сокращают: $0{,}4=\\dfrac{4}{10}=\\dfrac{2}{5}$.</p>'
+'<p>Обыкновенную дробь переводят в десятичную делением (если она конечная). В смешанном выражении удобно привести всё к <b>одному виду</b>.</p>');
h+=makeCard('example','Пример','10.2',
'<p>$0{,}2 + \\dfrac{1}{4} = \\dfrac{1}{5} + \\dfrac{1}{4} = \\dfrac{9}{20} = 0{,}45$, или сразу $0{,}2 + 0{,}25 = 0{,}45$.</p>');
h+='<div class="wg" id="p10-iv1"><div class="wg-header"><span class="wg-badge">Интерактив 1</span><div class="wg-title">Сопоставь дробь и десятичную</div></div>'
+'<div class="wg-help">Перетащи каждую десятичную дробь к равной ей обыкновенной (или нажми карточку, потом — ящик).</div>'
+'<div class="dnd-hint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 11V6a3 3 0 0 1 6 0v5"/><path d="M9 11h6v8a4 4 0 0 1-8 0z"/></svg> 5 десятичных — 5 ящиков</div>'
+'<div id="p10-pool"></div>'
+'<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:10px;margin-top:8px">'
+'<div class="drop-box"><h5 data-cat="a">$\\frac{1}{2}$</h5><div class="drop-items" data-cat="a"></div></div>'
+'<div class="drop-box"><h5 data-cat="b">$\\frac{1}{4}$</h5><div class="drop-items" data-cat="b"></div></div>'
+'<div class="drop-box"><h5 data-cat="c">$\\frac{1}{5}$</h5><div class="drop-items" data-cat="c"></div></div>'
+'<div class="drop-box"><h5 data-cat="d">$\\frac{3}{4}$</h5><div class="drop-items" data-cat="d"></div></div>'
+'<div class="drop-box"><h5 data-cat="e">$\\frac{1}{8}$</h5><div class="drop-items" data-cat="e"></div></div></div>'
+'<div class="actions"><button class="btn primary" id="p10-check">Проверить</button><button class="btn" id="p10-reset">Сначала</button></div>'
+'<div class="feedback" id="p10-fb"></div></div>';
h+='<div class="wg" id="p10-iv2"><div class="wg-header"><span class="wg-badge">Интерактив 2</span><div class="wg-title">Вычисли значение выражения</div></div>'
+'<div class="wg-help">Приведи к удобному виду и запиши ответ десятичной дробью.</div>'
+'<div class="score-display"><span>Пример <b id="p10-i">1</b> / 5</span><span>Очки: <b id="p10-s">0</b> / 5</span></div>'
+'<div id="p10-q" class="qbox"></div>'
+'<div style="display:flex;gap:10px;justify-content:center;align-items:center;flex-wrap:wrap"><input type="text" id="p10-a" class="tinp" style="width:130px;text-align:center" placeholder="ответ"><button class="btn primary" id="p10-go">Проверить</button></div>'
+'<div class="feedback" id="p10-afb"></div></div>';
h+=secNav('p9','app')+readBtn('p10');
box.innerHTML=h; renderMath(box);
(function(){
var items=[{id:'i1',cat:'a',html:'$0{,}5$'},{id:'i2',cat:'b',html:'$0{,}25$'},{id:'i3',cat:'c',html:'$0{,}2$'},{id:'i4',cat:'d',html:'$0{,}75$'},{id:'i5',cat:'e',html:'$0{,}125$'}];
var sorter=setupSorter({ poolId:'p10-pool', scopeSelector:'#p10-iv1', items:items, cats:['a','b','c','d','e'], columnLayout:false });
document.getElementById('p10-check').addEventListener('click',function(){ var fb=document.getElementById('p10-fb');
var all=items.every(function(it){ return sorter.placed[it.id]===it.cat; });
var placed=items.filter(function(it){ return sorter.placed[it.id]; }).length;
if(all){ feedback(fb,true,'✓ Все 5 равенств верны! +12 XP'); addXp(12,'p10-iv1'); bumpProgress('p10',35); }
else if(placed<items.length){ feedback(fb,false,'✗ Размести все 5 карточек.'); }
else{ var c=items.filter(function(it){ return sorter.placed[it.id]===it.cat; }).length; feedback(fb,false,'✗ Верно '+c+' из 5. Попробуй ещё.'); } });
document.getElementById('p10-reset').addEventListener('click',function(){ sorter.reset(); document.getElementById('p10-fb').style.display='none'; });
})();
(function(){
var EX=[['0{,}5 + \\dfrac{1}{4}',0.75],['\\dfrac{1}{2} + 0{,}25',0.75],['0{,}2 + \\dfrac{1}{4}',0.45],['\\dfrac{3}{4} - 0{,}25',0.5],['0{,}6 + \\dfrac{1}{5}',0.8],['\\dfrac{1}{8} + 0{,}375',0.5],['0{,}5 \\cdot \\dfrac{1}{2}',0.25],['\\dfrac{1}{4} + 0{,}1',0.35]];
var i=0,score=0,cur=null,used=[];
function gen(){ var e; do{ e=_pick(EX); }while(used.length<EX.length && used.indexOf(e)>=0); used.push(e); cur=e; }
function show(){ if(i>=5){ document.getElementById('p10-q').innerHTML='<b>Готово!</b> Результат: '+score+' / 5'; if(score>=4){addXp(15,'p10-iv2');bumpProgress('p10',30);}else if(score>=2){addXp(8,'p10-iv2');bumpProgress('p10',16);} return; }
gen(); document.getElementById('p10-i').textContent=i+1;
document.getElementById('p10-q').innerHTML='Вычисли $'+cur[0]+'$'; renderMath(document.getElementById('p10-q'));
document.getElementById('p10-a').value=''; document.getElementById('p10-afb').style.display='none'; }
function go(){ if(i>=5)return; var fb=document.getElementById('p10-afb'), v=parseFloat(document.getElementById('p10-a').value.replace(',','.').trim());
if(isNaN(v)){ feedback(fb,false,'Введи число.'); return; }
if(Math.abs(v-cur[1])<1e-9){ score++; feedback(fb,true,'✓ Верно: $'+_kf(cur[1])+'$.'); } else feedback(fb,false,'✗ Нет. Правильно: $'+_kf(cur[1])+'$.');
document.getElementById('p10-s').textContent=score; i++; setTimeout(show,1300); }
document.getElementById('p10-go').addEventListener('click',go);
document.getElementById('p10-a').addEventListener('keydown',function(e){ if(e.key==='Enter')go(); }); show();
})();
}
/* ===================== ДАННЫЕ САЙДБАРА / ГЛОССАРИЯ ===================== */
var SIDEBARS = {
p1:{ title:'Шпаргалка § 1', rows:[
@@ -525,7 +747,27 @@ var SIDEBARS = {
p6:{ title:'Шпаргалка § 6', rows:[
['Умножение','как натуральные числа'],
['Запятая','знаков = сумма знаков множителей'],
['$1{,}2\\cdot 0{,}3$','$12\\cdot3=36$, 2 знака → $0{,}36$'] ]}
['$1{,}2\\cdot 0{,}3$','$12\\cdot3=36$, 2 знака → $0{,}36$'] ]},
p7:{ title:'Шпаргалка § 7', rows:[
['Деление на натур.','делим уголком'],
['Запятая в частном','когда кончилась целая часть'],
['Не делится','дописываем нули'],
['$1\\div4$','$=0{,}25$'] ]},
p8:{ title:'Шпаргалка § 8', rows:[
['Делитель — дробь','переносим запятую вправо'],
['На сколько','на число знаков делителя'],
['У обоих','и у делимого, и у делителя'],
['$4{,}5\\div0{,}5$','$=45\\div5=9$'] ]},
p9:{ title:'Шпаргалка § 9', rows:[
['Конечная','деление заканчивается'],
['Бесконечная','цифры периода в скобках'],
['Признак конечной','знаменатель — только 2 и 5'],
['$\\frac13$','$=0{,}(3)$'] ]},
p10:{ title:'Шпаргалка § 10', rows:[
['Десятичная → обыкн.','по разрядам и сократить'],
['Обыкн. → десятичная','делением (если конечная)'],
['В выражении','привести к одному виду'],
['$0{,}4$','$=\\frac{2}{5}$'] ]}
};
var TIPS = [
{ sec:'p1', html:'Число цифр после запятой = числу нулей в знаменателе. У $0{,}305$ три цифры → знаменатель $1000$.' },
@@ -533,7 +775,11 @@ var TIPS = [
{ sec:'p3', html:'Чтобы отметить десятые, дели единичный отрезок на 10. $1{,}7$ — это $1$ и ещё $7$ маленьких делений.' },
{ sec:'p4', html:'Перед сложением «лесенкой» допиши нули: $7$ это $7{,}0$, тогда $7{,}0-2{,}3$ считается легко.' },
{ sec:'p5', html:'Считай нули множителя: у $1000$ их три → запятая прыгает на 3 знака. Умножаем — вправо, делим — влево.' },
{ sec:'p6', html:'Сначала перемножь без запятых. Потом отсчитай справа столько знаков, сколько их после запятой у обоих множителей вместе.' }
{ sec:'p6', html:'Сначала перемножь без запятых. Потом отсчитай справа столько знаков, сколько их после запятой у обоих множителей вместе.' },
{ sec:'p7', html:'Запятую в частном ставят ровно тогда, когда переходят от целой части делимого к дробной. Не делится нацело — припиши нули.' },
{ sec:'p8', html:'Считай знаки <b>только у делителя</b>. Перенеси запятую на столько знаков вправо и у делимого, и у делителя — делитель станет целым.' },
{ sec:'p9', html:'Чтобы понять, конечная ли дробь, разложи знаменатель на множители. Только 2 и 5 — конечная; есть 3, 7, … — бесконечная.' },
{ sec:'p10', html:'Если все десятичные конечные — переведи дроби в десятичные и считай в десятичных. Иначе приводи к обыкновенным с общим знаменателем.' }
];
var GLOSSARY = [
{ term:'десятичная дробь', def:'Дробь со знаменателем $10,100,1000,\\ldots$, записанная через запятую.', sec:'p1', aliases:['десятичная дробь','десятичной дроби','десятичные дроби','десятичных дробей','десятичную дробь'] },
@@ -542,9 +788,12 @@ var GLOSSARY = [
{ term:'координата', def:'Число, показывающее расстояние точки от начала в единичных отрезках.', sec:'p3', aliases:['координата','координату','координаты','координатой'] },
{ term:'округление', def:'Замена числа близким с меньшим числом разрядов по правилу: следующая цифра $\\ge5$ — разряд увеличивают.', sec:'p2', aliases:['округление','округления','округлить','округлении'] },
{ term:'множитель', def:'Число, которое умножают. В произведении число знаков после запятой равно сумме знаков множителей.', sec:'p6', aliases:['множитель','множителя','множители','множителей'] },
{ term:'произведение', def:'Результат умножения. $1{,}2\\cdot 0{,}3 = 0{,}36$.', sec:'p6', aliases:['произведение','произведения','произведении'] }
{ term:'произведение', def:'Результат умножения. $1{,}2\\cdot 0{,}3 = 0{,}36$.', sec:'p6', aliases:['произведение','произведения','произведении'] },
{ term:'частное', def:'Результат деления. В $a\\div b$ число $a$ — делимое, $b$ — делитель.', sec:'p7', aliases:['частное','частного','частном'] },
{ term:'периодическая дробь', def:'Бесконечная десятичная дробь, в которой группа цифр (период) повторяется: $0{,}(3)$.', sec:'p9', aliases:['периодическая дробь','периодической дроби','период','периода','периодом'] },
{ term:'конечная дробь', def:'Десятичная дробь с конечным числом знаков после запятой ($0{,}75$).', sec:'p9', aliases:['конечная дробь','конечной дроби','конечная десятичная'] }
];
var BUILDERS = { p1:buildP1, p2:buildP2, p3:buildP3, p4:buildP4, p5:buildP5, p6:buildP6 };
var BUILDERS = { p1:buildP1, p2:buildP2, p3:buildP3, p4:buildP4, p5:buildP5, p6:buildP6, p7:buildP7, p8:buildP8, p9:buildP9, p10:buildP10 };
Object.assign(window.M6, { sidebars:SIDEBARS, tips:TIPS, glossary:GLOSSARY, builders:BUILDERS });
</script>