Example #1
0
def query_which_route(query: Query, session: Session, result: Result):
    """ Which routes stop at a given bus stop """
    stop_name = cast(str, result.stop_name)  # 'Einarsnes', 'Fiskislóð'...

    if stop_name in {"þar", "þangað"}:
        # Referring to a bus stop mentioned earlier
        ctx = query.fetch_context()
        if ctx and "bus_stop" in ctx:
            stop_name = cast(str, ctx["bus_stop"])
            result.qkey = stop_name
        else:
            answer = voice_answer = "Ég veit ekki við hvaða stað þú átt."
            response = dict(answer=answer)
            return response, answer, voice_answer

    bus_noun = result.bus_noun  # 'strætó', 'vagn', 'leið'...
    stops = straeto.BusStop.named(stop_name, fuzzy=True)
    if not stops:
        a = [stop_name, "þekkist ekki."]
        va = ["Ég", "þekki", "ekki", "biðstöðina", stop_name.capitalize()]
    else:
        routes = set()
        if query.location:
            straeto.BusStop.sort_by_proximity(stops, query.location)
        stop = stops[0]
        for route_id in stop.visits.keys():
            number = straeto.BusRoute.lookup(route_id).number
            routes.add(number)
        va = [bus_noun, "númer"]
        a = va[:]
        nroutes = len(routes)
        cnt = 0
        for rn in sorted(routes, key=lambda t: int(t)):
            if cnt:
                sep = "og" if cnt + 1 == nroutes else ","
                va.append(sep)
                a.append(sep)
            # We convert inflectable numbers to their text equivalents
            # since the speech engine can't be relied upon to get the
            # inflection of numbers right
            va.append(numbers_to_neutral(rn))
            a.append(rn)
            cnt += 1
        tail = ["stoppar á", to_dative(stop.name)]
        va.extend(tail)
        a.extend(tail)
        # Store a location coordinate and a bus stop name in the context
        query.set_context({"location": stop.location, "bus_stop": stop.name})

    voice_answer = correct_spaces(" ".join(va) + ".")
    answer = correct_spaces(" ".join(a))
    answer = cap_first(answer)
    response = dict(answer=answer)
    return response, answer, voice_answer
Example #2
0
def QWhatIsEntity(node: Node, params: ParamList, result: Result) -> None:
    result.qtype = "WhatIs"
    result.qkey = result._nominative
Example #3
0
def calc_arithmetic(query: Query, result: Result) -> Optional[AnswerTuple]:
    """ Calculate the answer to an arithmetic query """
    operator = result.operator
    nums = result.numbers
    desc = result.desc

    if "error_context_reference" in result:
        # Used 'það' or 'því' without context
        return gen_answer("Ég veit ekki til hvers þú vísar.")

    # Ensure that we have the right number of
    # number args for the operation in question
    assert _OP_NUM_ARGS[operator] == len(nums)

    # Global namespace for eval
    # Block access to all builtins
    eval_globals: Dict[str, Any] = {"__builtins__": None}

    # Square root calculation
    if operator == "sqrt":
        if len(str(nums[0])) > 100:
            return gen_answer("Þessi tala er of há.")
        # Allow sqrt function in eval namespace
        eval_globals["sqrt"] = math.sqrt
        s = "sqrt({0})".format(nums[0])

    # Pow
    elif operator == "pow":
        # Cap max pow
        if nums[1] > 50:
            return gen_answer("Þetta er of hátt veldi.")
        # Allow pow function in eval namespace
        eval_globals["pow"] = pow
        s = "pow({0},{1})".format(nums[0], nums[1])

    # Percent
    elif operator == "percent":
        s = "({0} * {1}) / 100.0".format(nums[0], nums[1])

    # Fraction
    elif operator == "fraction":
        s = "{0} * {1}".format(nums[0], nums[1])

    # Add VAT to sum
    elif operator == "with_vat":
        s = "{0} * {1}".format(nums[0], _VAT_MULT)

    # Subtract VAT from sum
    elif operator == "without_vat":
        s = "{0} / {1}".format(nums[0], _VAT_MULT)

    # Addition, subtraction, multiplication, division
    elif operator in _STD_OPERATORS:
        math_op = _STD_OPERATORS[operator]

        # Check for division by zero
        if math_op == "/" and nums[1] == 0:
            return gen_answer("Það er ekki hægt að deila með núlli.")

        s = "{0} {1} {2}".format(nums[0], math_op, nums[1])
    else:
        logging.warning("Unknown operator: {0}".format(operator))
        return None

    # Set arithmetic expression as query key
    result.qkey = s

    # Run eval on expression
    res: float = eval(s, eval_globals, {})

    if isinstance(res, float):
        # Convert result to Icelandic decimal format
        answer = iceformat_float(res)
    else:
        answer = str(res)

    response = dict(answer=answer, result=res)
    voice_answer = "{0} er {1}".format(desc, answer)

    return response, answer, voice_answer