Exemplo n.º 1
0
def register_result(result0, sym, state, keep_provenance=False):
    """
    Enters the quantity that was just calculated into the database

    :param result0: quantity Q()
    :param sym: name of the quantity
    :param state: contains known quantities as ordered dict, along with flags and output
    """
    if not keep_provenance:
        result0.provenance = []
        result0.name = sym[:]
    if hasattr(result0, 'depth'):
        del result0.depth
    if sym in state and '__allowupdate__' not in state.flags:
        state.printit(
            '<div style="color: green;">Warning: Updated value of \\(%s\\)</div><br>'
            % (latex_name(sym)))
    state[sym] = result0
    if '__fracunits__' not in state.flags:
        for u in result0.units:
            if u.denominator != 1:  #oddly, ints have and floats don't
                state.printit(
                    '<div style="color: green;">Warning: Units have non-integer exponents %s</div><br>'
                    % u)
    if "__checkunits__" in state.flags:
        if len(sym) == 1 or sym[1] in "_0123456789[" or sym[0] == "[":
            if sym[0] in typicalunits and result0.units != typicalunits[
                    sym[0]][0]:
                state.printit(
                    '<div style="color: green;">Warning: \\(%s\\) looks like a %s, but units are strange</div><br>'
                    % (latex_name(sym), typicalunits[sym[0]][1]))
Exemplo n.º 2
0
def show_work(result, sym, flags, error=False, addon="", skipsteps=False):
    """
    Shows the steps in getting from formula to calculated value. This function is called not only by calc(),
    but also by convert_units() and deal_with_errors() to show steps in calculations.

    :param result: value and provenance of the quantity Q()
    :param sym: name of the quantity
    :param flags: Switches that determine how much detail is shown
    :param error: True if used to show an error in a step of a calculation
    :param addon: Used when called from convert_units(ConversionIn)
    :param skipsteps: True when intermediate steps are to be skipped
    :return: tuple containing detailed output, brief output
    """
    output = []
    logput = []
    math = not 'plain math' in flags
    if math:
        writer = quantities.latex_writer
        if not "__latex__" in flags:
            logput.append('''<span style="color:navy; cursor:pointer; font-size:15pt;" onclick="insertAtCaret('commands','%s ', 0)">''' % sym)
            output.append('''<span style="color:navy; cursor:pointer; font-size:15pt;" onclick="insertAtCaret('commands','%s ', 0)">''' % sym)
    else:
        writer = quantities.ascii_writer
    subs = latex_subs if math else None
    d = result.setdepth()
    if math:
        template1 = "\(%s = %s%s\)<br>"
        template2 = "<br>\(\\ \\ \\ =%s%s\)<br>"
    else:
        template1 = "%s = %s%s" if d <= 0 else "%s = \n   = %s%s"
        template2 = "   = %s%s"
    task = result.steps(-1, writer, subs, ())  # task
    if '__hidenumbers__' in flags:
        task = result.steps(-1, quantities.latex_writer, subs)
    name = latex_name(sym) if math else sym
    output.append(template1 % (name, task, addon))
    logput.append(template1 % (name, task, addon))
    if not skipsteps:
        for dd in range(1, d + 1):
            if dd == 1:
                first = result.steps(dd, writer, subs, flags)
                if '__hidenumbers__' in flags:
                    first = result.steps(dd, quantities.latex_writer, subs, {'__hidenumbers__'})
                if first != task:
                    output.append(template2 % (first, addon))
            else:
                output.append(template2 % (result.steps(dd, writer, subs, flags), addon))  # intermediate steps
    result_str = result.steps(0, writer, subs, flags)  # result
    if '__hideunits__' in flags:
        task = result.steps(-1, writer, subs, flags)
    if result_str != task and not error and not ('__hidenumbers__' in flags and d == 0):
        logput.append(template2 % (result_str, addon))
        output.append(template2 % (result_str, addon))
    if math and not '__latex__' in flags:
        logput.append('<br></span>')
        output.append('<br></span>')
    return output, logput
Exemplo n.º 3
0
def consume_identifier(charlist):
    cl2 = []
    charlist.pop(0)
    while charlist:
        if charlist[0] == " ":
            charlist.pop(0)
            break
        cl2.append(charlist.pop(0))
    return "\\(%s\\)" % latex_name("".join(cl2))
Exemplo n.º 4
0
def consume_identifier(charlist):
    cl2 = []
    charlist.pop(0)
    while charlist:
        if charlist[0] == " ":
            charlist.pop(0)
            break
        cl2.append(charlist.pop(0))
    space = '' if charlist and charlist[0] in '.,?)' else ' '
    return "\\(%s\\)" % latex_name("".join(cl2)) + space
Exemplo n.º 5
0
def convert_units(input_type, command, quant, units, state):
    """
    Shows the quantity in different units, either once only ('in') or from now on ('using')

    :param input_type: Whether conversion is with "using" or "in"
    :param command: user input
    :param quant: Q() to be converted
    :param units: requested units
    :param state: contains known quantities as ordered dict, along with flags and output
    :raise CalcError: if requested units are unknown
    """
    flags2 = set(i for i in state.flags if i != '__hideunits__')
    if input_type == ConversionUsing:
        prefu = units.split()
        for p in prefu:
            if p not in unitquant:
                raise CalcError(
                    "PQCalc does not recognize the unit '%s', so 'using' does not work. Try 'in' instead." % p)
        try:
            q = state[quant.strip()] + Q(0.0)
        except KeyError:
            raise CalcError("The quantity '%s' is not defined yet. Check for typos." % quant.strip())
        q.name = ""
        q.provenance = None
        outp, _ = show_work(q, quant, flags2)
        output = (outp[:-1])
        state[quant.strip()].prefu = set(prefu)
        q = state[quant.strip()] + Q(0.0)
        outp, _ = show_work(q, quant, flags2)
        output.extend(outp[-2 if not 'plain math' in state.flags else -1:])
    else:
        tmp = interpret(units, state)
        try:
            qq = state[quant.strip()] / tmp
        except KeyError:
            raise CalcError("The quantity '%s' is not defined yet. Check for typos." % quant.strip())
        addon = ("\mathrm{\ %s}" % quantities.latex_name(units)) if state.mob != "ipud" else units
        output, _ = show_work(qq, quant, flags2, addon=addon)
    state.printit('\n'.join(output))
Exemplo n.º 6
0
def markup_all_but_math(line):
    """

    :param line: String containing the comment
    :return: String with variables and chemistry marked-up in LateX
    """
    interpretation = []
    for item in (it for word in split_at_punctuation(line)
                 for it in autodetect(word)):
        if item[0] == "!":
            interpretation.append('\\(\\ce{%s}\\)' % item[1])
        elif item[0] == "{":
            interpretation.append(format_image(item[1]))
        elif item[0] == "N":
            if 'E' in item[1] or 'e' in item[1]:
                numbertext = '\\(' + latex_number(item[1]) + '\\)'
            else:
                numbertext = item[1]
            interpretation.append(clickable(item[1], numbertext))
        elif item[0] == "i":
            numbertext = item[1]
            if not '.' in numbertext:
                numbertext = numbertext.rstrip() + '.'
            interpretation.append(clickable(numbertext, item[1]))
        elif item[0] == "_":
            try:
                delim = ' ' if item[1].endswith(' ') else ''
                interpretation.append(
                    clickable(
                        item[1],
                        '\\(%s\\)%s' % (latex_name(item[1].rstrip()), delim)))
            except:
                interpretation.append(item[1])
        else:
            interpretation.append(format_natural_language(item[1]))
    return ''.join(interpretation)
Exemplo n.º 7
0
def create_unknown(sym, state):
    state.printnlog('''<span style="color:navy; font-size:15pt; cursor:pointer" onclick="insertAtCaret('commands','%s ', 0)">''' % sym)
    state.printnlog("\(%s =\\ ?\)<br>" % latex_name(sym))
    state.printnlog('<br></span>')
Exemplo n.º 8
0
def create_unknown(sym, state):
    state.printnlog(
        '''<span title="%s" style="color:navy; font-size:12pt; cursor:pointer" onclick="insertAtCaret('commands','%s = ', 0)">'''
        % (pronounce(sym), sym))
    state.printnlog("\(%s =\\ ?\)<br>" % latex_name(sym))
    state.printnlog('<br></span>')
Exemplo n.º 9
0
def convert_units(input_type, command, quant, units, state):
    """
    Shows the quantity in different units, either once only ('in') or from now on ('using')

    :param input_type: Whether conversion is with "using" or "in"
    :param command: user input
    :param quant: Q() to be converted
    :param units: requested units
    :param state: contains known quantities as ordered dict, along with flags and output
    :raise CalcError: if requested units are unknown
    """
    flags2 = set(i for i in state.flags if i != '__hideunits__')
    if input_type == ConversionUsing:
        print(repr(state[quant.strip()]))
        if units in ['°ΔC', '°aC']:
            prefu = [units]
            q = state[quant.strip()] + Q(0.0)
            if units == '°aC' and unitquant['K'].units != q.units:
                raise CalcError(
                    "Only quantities in kelvin may be converted to celsius")
        else:
            prefu = units.split()
            for p in prefu:
                if p not in unitquant:
                    raise CalcError(
                        "PQCalc does not recognize the unit '%s', so 'using' does not work. Try 'in' instead."
                        % p)
            try:
                q = state[quant.strip()] + Q(0.0)
            except KeyError:
                raise CalcError(
                    "The quantity '%s' is not defined yet. Check for typos." %
                    quant.strip())
        q.name = ''
        q.provenance = None
        q.comment = ''
        outp, _ = show_work(q, quant, flags2)
        output = (outp[:-1])
        state[quant.strip()].prefu = set(prefu)
        q_old = state[quant.strip()]
        if q_old.provenance:  # when called by calc2
            q_old.name = ''
            q_old.provenance = None
        q = q_old + Q(0.0)
        q.comment = ''
        outp, _ = show_work(q, quant, flags2)
        output.extend(outp[-2 if not 'plain math' in state.flags else -1:])
        q = state[quant.strip()] + Q(0.0)
        q.name = ""
        q.provenance = None
        _, logp = show_work(q, quant, flags2)
        state.printit('\n'.join(output))
        state.logit('\n'.join(logp))
        print(repr(state[quant.strip()]))
    else:
        tmp = interpret(units, state, warning=False)
        try:
            qq = state[quant.strip()] / tmp
        except KeyError:
            raise CalcError(
                "The quantity '%s' is not defined yet. Check for typos." %
                quant.strip())
        addon = (
            "\mathrm{\ %s}" %
            quantities.latex_name(units)) if state.mob != "ipud" else units
        work = show_work(qq, quant, flags2, addon=addon)
        state.printwork(work)
Exemplo n.º 10
0
def show_work(result, sym, flags, error=False, addon="", skipsteps=False):
    """
    Shows the steps in getting from formula to calculated value. This function is called not only by calc(),
    but also by convert_units() and deal_with_errors() to show steps in calculations.

    :param result: value and provenance of the quantity Q()
    :param sym: name of the quantity
    :param flags: Switches that determine how much detail is shown
    :param error: True if used to show an error in a step of a calculation
    :param addon: Used when called from convert_units(ConversionIn)
    :param skipsteps: True when intermediate steps are to be skipped
    :return: tuple containing detailed output, brief output
    """
    output = []
    logput = []
    math = not 'plain math' in flags
    if math:
        writer = quantities.latex_writer
        if not "__latex__" in flags:
            logput.append(
                '''<span title='%s' style="color:navy; cursor:pointer; font-size:12pt;" onclick="insertAtCaret('commands','%s ', 0)">'''
                % (pronounce(sym, result.units), sym))
            output.append(
                '''<span title='%s' style="color:navy; cursor:pointer; font-size:12pt;" onclick="insertAtCaret('commands','%s ', 0)">'''
                % (pronounce(sym, result.units), sym))
    else:
        writer = quantities.ascii_writer
    subs = latex_subs if math else None
    d = result.setdepth()
    if math:
        template1 = "\(%s = %s%s\)%s<br>"
        template2 = "<br>\(\\ \\ \\ =%s%s\)<br>"
    else:
        template1 = "%s = %s%s%s" if d <= 0 else "%s = %s\n   = %s%s"
        template2 = "   = %s%s"
    task = result.steps(-1, writer, subs, ())  # task
    if '__hidenumbers__' in flags:
        task = result.steps(-1, quantities.latex_writer, subs)
    name = latex_name(sym) if math else sym
    output.append(template1 %
                  (name, task, addon, markup_comment(result.comment)))
    logput.append(template1 %
                  (name, task, addon, markup_comment(result.comment)))
    if not skipsteps:
        for dd in range(1, d + 1):
            if dd == 1:

                first = result.steps(dd, writer, subs, flags)
                if '__hidenumbers__' in flags:
                    first = result.steps(dd, quantities.latex_writer, subs,
                                         {'__hidenumbers__'})
                if first != task:
                    output.append(template2 % (first, addon))
            else:
                output.append(template2 % (result.steps(
                    dd, writer, subs, flags), addon))  # intermediate steps
    result_str = result.steps(0, writer, subs, flags)  # result
    if '__hideunits__' in flags:
        task = result.steps(-1, writer, subs, flags)
    if result_str != task and not error and not ('__hidenumbers__' in flags
                                                 and d == 0):
        logput.append(template2 % (result_str, addon))
        output.append(template2 % (result_str, addon))
    if math and not '__latex__' in flags:
        logput.append('<br></span>')
        output.append('<br></span>')
    return output, logput
Exemplo n.º 11
0
def show_work(result, sym, flags, error=False, addon="", skipsteps=False):
    """
    Shows the steps in getting from formula to calculated value. This function is called not only by calc(),
    but also by convert_units() and deal_with_errors() to show steps in calculations.

    :param result: value and provenance of the quantity Q()
    :param sym: name of the quantity
    :param flags: Switches that determine how much detail is shown
    :param error: True if used to show an error in a step of a calculation
    :param addon: Used when called from convert_units(ConversionIn)
    :param skipsteps: True when intermediate steps are to be skipped
    :return: tuple containing detailed output, brief output
    """
    output = []
    logput = []
    math = not 'plain math' in flags
    if math:
        writer = quantities.latex_writer
        if not "__latex__" in flags:
            logput.append('''<span style="cursor:pointer" onclick="insertAtCaret('commands','%s ', 0)">''' % sym)
            output.append('''<span style="cursor:pointer" onclick="insertAtCaret('commands','%s ', 0)">''' % sym)
    else:
        writer = quantities.ascii_writer
    subs = {"%s / %s": "\\dfrac{%s}{%s}",
            "%s * %s": "%s \\cdot %s",
            "%s ^ %s": "{%s}^{%s}",
            "exp(%s)": "e^{%s}",
            "log(%s)": "\\mathrm{log}(%s)",
            "ln(%s)": "\\mathrm{ln}(%s)",
            "sin(%s)": "\\mathrm{sin}(%s)",
            "cos(%s)": "\\mathrm{cos}(%s)",
            "tan(%s)": "\\mathrm{tan}(%s)",
            "sqrt(%s)": "\\sqrt{%s}",
            "quadn(%s": "\\mathrm{quadn}(%s",
            "quadp(%s": "\\mathrm{quadp}(%s",
            "average(%s": "\\mathrm{average(%s",
            "minimum(%s": "\\mathrm{minimum(%s",
            "maximum(%s": "\\mathrm{maximum(%s",
            "absolute(%s": "\\mathrm{absolute(%s",
            "moredigits(%s)": "\\mathrm{moredigits}(%s)",
            "uncertainty(%s)": "\\mathrm{uncertainty}(%s)",
    } if math else None
    d = result.setdepth()
    if math:
        template1 = "\(%s = %s%s\)<br>"
        template2 = "<br>\(\\ \\ \\ =%s%s\)<br>"
    else:
        template1 = "%s = %s%s" if d <= 0 else "%s = \n   = %s%s"
        template2 = "   = %s%s"
    flaugs = dict(uncert=("__showuncert__" in flags), hideunits=("__hideunits__" in flags),
                  hidenumbers=("__hidenumbers__" in flags))
    task = result.steps(-1, writer, subs, flaugs)  # task
    if flaugs['hidenumbers']:
        task = result.steps(-1, quantities.latex_writer, subs)
    name = latex_name(sym) if math else sym
    output.append(template1 % (name, task, addon))
    logput.append(template1 % (name, task, addon))
    if not skipsteps:
        for dd in range(1, d + 1):
            if dd == 1:
                first = result.steps(dd, writer, subs, flaugs)
                if flaugs['hidenumbers']:
                    first = result.steps(dd, quantities.latex_writer, subs, dict(hidenumbers=True))
                if first != task:
                    output.append(template2 % (first, addon))
            else:
                output.append(template2 % (result.steps(dd, writer, subs, flaugs), addon))  # intermediate steps
    result_str = result.steps(0, writer, subs, flaugs)  # result
    if result_str != task and not error and not (flaugs['hidenumbers'] and d == 0):
        logput.append(template2 % (result_str, addon))
        output.append(template2 % (result_str, addon))
    if math and not '__latex__' in flags:
        logput.append('<br></span>')
        output.append('<br></span>')
    return output, logput