Math Worksheets

Stephen Lukacs (2) iquanta.org/instruct/python
this is a test of the American Broadcast System. This is only a test.. .
"""
reference: https://iquanta.org/instruct/python ::: Math 2: Practice Worksheetss, Math Worksheets ::: Stephen Lukacs, Ph.D. ©2022-10-31
"""
<page_scripts>
<style>
@media print {
    @page { size:8.5in 11in; margin: 0.5in; padding: 0in; }
    html, body { color: black; }
    p.pagebreak { page-break-after: always; }
    nav, div#titles, div#head, div#header, span.noprt, div#footer div#footer_text_center:first-child, pre#code, div#header99, div#source99 { display: none; }

    div.body { all: initial; width: 100%; height: 100%; margin: 0px; padding: 0px; }
    div.mt { float: none; border: 0px solid #555; background-color: white; -webkit-transform: rotate(90deg); -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); -o-transform: rotate(90deg); filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3); }
    }
@media screen {
    }
    div#header9 { font-size: 16pt; }
    input[type="text"] { width: 43px; border-radius: 5px; }
    input[type="submit"] { padding: 6px 30px; border-radius: 10px; }
    table.g { margin:auto; width: 100%; }
    table.g td { margin:auto; width: auto; text-align: left; font-size: 20pt; line-height: 29.2pt; }
    
    table.mt { width: 100%; height: 100%; margin: 0px; padding: 0px; }
    table.mt td { text-align: center; padding: 2px 2px; border: 1px solid black; font-size: 18pt; }
</style>

<script type="text/python">
import browser.timer
from browser import document
from browser.html import A, B, U, BR, DIV, P, SPAN, SUP, TABLE, TR, TH, TD
from datetime import datetime
from random import randint, choice, sample, uniform
from math import log10 as log, floor, ceil

def prime_integers(maximum):
    lst = [ ]
    for i in range(2, maximum+1):
        for j in range(2, i):
            if (i % j) == 0:
                break
        else:
            lst.append(i)
    return lst

def reduce_fraction(numerator, denominator):
    n, d = numerator, denominator
    for p in prime_integers(d):
        while ((n % p) == 0) and ((d % p) == 0):
            n, d = n/p, d/p
    return n, d

def stringify_primes(primes):
    #primes is a dict of k=prime:v=exponent
    ni = 1
    for k, v in primes.items():
       ni *= k**v
    pstr = f"{ni}=1&sdot;"
    for i, (k, v) in enumerate(sorted(primes.items())):
       pstr += f'{k}{"<sup>"+str(v)+"</sup>" if (v > 1) else ""}&sdot;'
    pstr = pstr[:-6]
    return pstr, ni

def factorize(n, full_report=False):
    ni = n
    factors = [ ]
    for i in prime_integers(n):
       while ((n % i) == 0):
          factors.append(i)
          n = n / i
    primes = { }
    for p in factors:
        if p in primes:
            primes[p] += 1
        else:
            primes[p] = 1
    if full_report:
       return stringify_primes(primes)[0], primes, factors
    else:
       return stringify_primes(primes)[0]

def gcf_lcm(lst, report=0):
    #https://calcworkshop.com/fractions/gcf-lcm/
    #GCF -> "Fewest in Common" -> used to simplify the result of a fraction.
    #LCM -> "Most of Each" -> used to find the common denominator in adding/subtracting fractions.
    dct = { 'pstr':{ }, 'primes':{ }}
    for l in lst:
        f = factorize(l, True)
        dct['pstr'][l] = f[0]
        dct['primes'][l] = f[1]
    factors_in_common = set(dct['primes'][lst[0]]).intersection(*[set(p) for p in dct['primes'].values()])
    gcf = { k:float('inf') for k in factors_in_common }
    for l in lst:
        for k, v in dct['primes'][l].items():
            if (k in gcf) and (v < gcf[k]):
                gcf[k] = v
    factors_of_each = set().union(*[set(p) for p in dct['primes'].values()])
    lcm = { k:0 for k in factors_of_each }
    for l in lst:
        for k, v in dct['primes'][l].items():
            if (k in lcm) and (v > lcm[k]):
                lcm[k] = v
    if (report == 2):
        ss = P(f'list of integers: {lst}')
        ss <= BR() + B('primes: ') + SPAN([dct['pstr'][l]+B('&emsp;|&emsp;') for l in lst])
        ss <= BR() + 'gc'+B(U('f')) + ' (' + B(U('fewest')) + ' in common) = ' + stringify_primes(gcf)[0]
        ss <= BR() + 'lc'+B(U('m')) + ' (' + B(U('most')) + ' of each) = ' + stringify_primes(lcm)[0]
        return ss
    elif (report == 1):
        components = '&emsp;<br/>&emsp;'.join([' <span class="noprt" style="">'+dct['pstr'][l]+'</span>' for l in lst])
        return f'{lst} &rarr; <span class="noprt"><b>gcf</b>={stringify_primes(gcf)[0]}, <b>lcm</b>={stringify_primes(lcm)[0]}</span><br/>&emsp;{components}'
    else:
        return stringify_primes(gcf)[1], stringify_primes(lcm)[1]

def float_to_mantissa_exponential(f, sig_figs=None):
    exponential = int(floor(log(abs(f)))) if (f != 0.) else 0
    mantissa = f/(10**exponential)
    if sig_figs:
        return (mantissa, exponential, ('{:.'+str(sig_figs-1)+'f}x10<sup>{}</sup>').format(mantissa, exponential))
    else:
        return (mantissa, exponential)

def show_result(event):
    btn = event.target
    itime = datetime.now()
    integer_list, primes = range(2, 32), prime_integers(33)
    basei = int(document['basei'].value) if (document['basei'].value.find(',') == -1) else [int(s) for s in document['basei'].value.replace(' ', "").split(',')]
    base_range, basef, xrange, negatives, operation, lines = document['base_range'].value,  int(document['basef'].value), int(document['range'].value), document['negative'].checked,  document['operation'].value, int(document['lines'].value)
    print(f"base: [{basei},{basef}], range: {xrange}, negatives: {negatives}, operation: {operation}, lines: {lines}")
    t = TABLE(Class="g")
    #bos...create blocks
    if (operation in ('factorize',)):
       td = TD([A("help", href="https://calcworkshop.com/fractions/gcf-lcm/", target="help_gcf_lcm"), ': ', B('GCF  &rarr;'), ' "Fewest in Common" (simplify) | ', B('LCM &rarr;'), ' "Most of Each" (common denominator)'], colspan="2")
       td.style.fontSize = '16pt'
       td.style.textAlign = 'center'
       t <= TR(td)
       lines = int(lines / 3)
    elif (operation in ('dlong',)):
       lines = int(lines / 5)
    elif (operation in ('+-long',)):
       lines = int(lines / 6)
    #eos...create blocks
    #bos...create columns
    if (operation in ('+-long','dd','dlong','pmfr','mdfr','factorize',)):
        columns = 2
    elif (operation in ('fr',)):
        columns = 3
    else:
        columns = 4
    #eos...create columns
    for i, r in enumerate(range(lines)):
        tr = [ ]
        for j, c in enumerate(range(columns)):
            xbase = basef if (base_range == '=') else randint(basei, basef)
            a = xbase if not negatives or (negatives and randint(0,1)) else -xbase
            b = randint(-xrange if negatives else 0, xrange)
            if (operation == '+-long'):
                a = randint(1e12,9e12)
                b = 2**63-1
                while (b > a):
                    b = randint(1e12,9e12)
                xoperation = '+' if (uniform(0.,1.) < 0.35) else '-'
                z = eval(f'{a} {xoperation} {b}')
                td = TD(f'{a}<br/>{xoperation}{b}<hr style="border:2px solid black;"/> <span class="noprt">{z}</span><br/> <br/>')
                td.style.fontSize = '52pt'
                td.style.lineHeight = '48pt'
                td.style.textAlign = 'right'
                if (j == 0):
                    td.style.paddingRight = '48px'
                #td.style.border = '1px solid blue'
                tr.append(td)
            elif (operation == 'factorize'):
                nums = [ ]
                while (len(nums) < xrange):
                    x = choice(integer_list)
                    if (x not in primes):
                        nums.append(x)
                nums = sorted(nums)
                tr.append(TD(gcf_lcm(nums, 1)))
            elif (operation == 'fr'):
                multiplier = randint(2, 4)
                num = randint(1, xrange)
                den = randint(num, xrange) * multiplier
                num = num * multiplier
                z = reduce_fraction(num, den)
                factor1 = den / z[1]
                #factor2 = gcf_lcm([num, den])[0] #should be equal to factor1
                zd = num / float(den)
                tr.append(TD(f'{num} / {den} = <span class="noprt"><b>{int(factor1)}</b>: {z[0]:.0f} / {z[1]:.0f} = {zd:.3f}</span>'))
            elif (operation == 'dd'):
                ea, eb = randint(0, 1), randint(2, 4)
                a, b = uniform(-9.99 if negatives else 1., 9.99)*10**ea, uniform(-9.99 if negatives else 1., 9.99)*10**eb
                fa, fb = randint(1, 2), randint(1, 3)
                sa, sb = f'{a:.{fa}f}', f'{b:.{fb}f}'
                sfa = ea + fa + 1
                z = b / a
                sfz = int(log(z)) + 1
                if (sfa > sfz):
                    sfz = sfa - sfz
                    tr.append(TD(f'{sb} / {sa} = <span class="noprt">{z:.{sfz}f}</span>'))
                else:
                    sfz = sfa
                    mez = float_to_mantissa_exponential(z, sfz)[2]
                    tr.append(TD(f'{sb} / {sa} = <span class="noprt">{z:.{sfz-1}e} = {mez}</sup></span>'))
            elif (operation == 'dshort'):
                b *= a
                z = b / float(a)
                tr.append(TD(f'{b} / {a} = <span class="noprt">{z:.0f}</span>'))
            elif (operation == 'dlong'):
                b = ceil(b * uniform(0.7, 1.9) * a)
                z, zi, zr = b / float(a), int(b / a), b % a
                tr.append(TD(f'{b} / {a} = <span class="noprt">{zi} r{zr}/{a} = {z:.2f}</span>{" <br/>"*5}'))
            else:
                order = randint(0, 1)
                if (operation == 'x'):
                    x = randint(0,2)
                    xoperation = '⋅' if (x == 2) else ('*' if (x == 1) else 'x')
                else:
                    xoperation = operation
                if negatives:
                    if order:
                        x = f'{a} {xoperation} ({b})' if (b < 0) else f'{a} {xoperation} {b}'
                    else:
                        x = f'{b} {xoperation} ({a})' if (a < 0) else f'{b} {xoperation} {a}'
                else:
                    x = f'{a} {xoperation} {b}' if order else f'{b} {xoperation} {a}'
                z = eval(x.replace('x', "*").replace('⋅', "*"))
                tr.append(TD(x+f' = <span class="noprt">{z}</span>'))
        t <= TR(tr)
    document['body'].clear()
    #document['body'] <= str(primes)
    document['body'] <= t
    ftime = datetime.now()
    document['time_span'].text = f"{(ftime - itime).total_seconds()}s"
    return

def rerange(event):
    obj = event.target
    print(obj.value)
    document['msg'].clear()
    document['range'].value = '13'
    if (obj.value == 'factorize'):
        document['range'].value = 2
    elif (obj.value in ('x', 'dshort', 'dlong',)):
        document['range'].value = '20'
    elif (obj.value in ('pmfr','mdfr',)):
        document['msg'].innerHTML = 'Under Construction'
    return

def update_time():
    now = datetime.now().strftime("%A, %B %d, %Y @ <b>%H:%M:%S</b>")
    document['clock'].innerHTML = now
    return now

brython_version = '.'.join([str(i) for i in __BRYTHON__.implementation[:3]])
print(f'brython version: {brython_version} ___ Math 2: Practices ___ iquanta.org/instruct/python ___ client-side sjlukacs implementation')
browser.timer.set_interval(update_time, 200)
document['operation'].bind('change', rerange)
document['return'].bind('click', show_result)
#bos...multiplication_table...
if 1:
    itime = datetime.now()
    t = TABLE(Class="mt")
    for i in range(1, 21):
        tr = [ ]
        for j in range(1, 21):
            td = TD(f'{i*j}')
            if (i == j):
                td.style.fontWeight = "bolder"
                td.style.border = "3px solid black"
            if ((i % 2) == 0):
                td.style.backgroundColor = "#ffff80"
            if (j <= i):
                if ((j % 2) == 0):
                    #if ((i % 2) == 0):
                    #    td.style.backgroundColor = "#cccc00"
                    #else:
                        td.style.backgroundColor = "#aaa"
            tr.append(td)
        t <= TR(tr)
    document['body'].clear()
    document['body'] <= DIV(t, Class="mt")
    ftime = datetime.now()
    document['time_span'].text = f"{(ftime - itime).total_seconds()}s"
#eos...multiplication_table
print(eval('-5-8'), 'should be -13 ___', eval('-5 - (-5)'), 'should be 0')
</script>
</page_scripts>

<header>
<h3 style="text-align:left;"><span id="clock"></span>&emsp;|&emsp;<span id="time_span"></span> .. .</h3>
Base: <input type="text" id="basei" value="2" /> <select id="base_range"><option value="=">only</option><option value=">">upto</option></select> <input type="text" id="basef" value="5" />
Range: <input type="text" id="range" value="13" />
Lines: <input type="text" id="lines" value="26" />&emsp;
<input type="checkbox" id="negative" unchecked style="position:relative; vertical-align:middle; transform:scale(1.25);" /> Negatives?&emsp;
Operation: <select id="operation">
    <option value="+">(+) Addition</option>
    <option value="-">(-) Subtraction</option>
    <option value="+-long">+/- (Long)</option>
    <option value="x">Multiply</option>
    <option value="dshort">Division (Short)</option>
    <option value="dlong">Division (Long)</option>
    <option value="factorize">GCF & LCM</option>
    <option value="fr">Reducing Fractions</option>
    <option value="pmfr">+/- Fractions</option>
    <option value="mdfr">x/&div; Fractions</option>
    <option value="dd">Decimal Division</option>
</select>
<input type="submit" id="return" name="return" value="Refresh"/>&emsp;<span id="msg"></span>&emsp;<span style="font-weight:bold;"><a href='/instruct/static/pdf/multiplication_tables_20x.pdf' target="mt20x">PDF</a></span>
</header>

<body>
this is a test of the American Broadcast System.  This is only a test.. .
</body>