From f623b9395440f3c1eccf3cb5d5b9afd82a944b6c Mon Sep 17 00:00:00 2001 From: vthorsteinsson Date: Tue, 13 Oct 2026 22:20:29 +0000 Subject: [PATCH 1/3] Clean up ruff findings from its 0.16 default rule set Ruff 0.16 enabled pyupgrade, RUF, SIM and other rule families by default, which the `ruff>=0.15` lint dependency picks up: 213 findings in unchanged code (CI runs only mypy and pytest, so it stayed green). - Apply ruff's safe autofixes: PEP 585/604 annotations (`list[str]`, `X | None`) and `collections.abc` imports, valid since the 3.10 floor. - Keep the bound TypeVar on `Tok.from_txt`/`from_token` instead of the autofix's `typing_extensions.Self`: Tokenizer has no runtime dependencies and `typing.Self` needs Python 3.11. - Annotate the `Abbreviations` class tables as `ClassVar`, use tuple `startswith`/`endswith`, `yield from`, implicit format fields, and `datetime.date` for date validation. - `noqa` FURB166: its suggested `base=0` would break `&#x...;` escapes. - Ignore SIM102: nested ifs mirror the token matching logic, and several sit in elif chains where collapsing them would change behaviour. - Update CLAUDE.md: the 3.9 annotation advice was stale. No behaviour change: token output digests on the large test set are identical, and clean installs on CPython 3.10 and PyPy 3.11 work. Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 6 +- pyproject.toml | 1 + src/tokenizer/__init__.py | 32 ++--- src/tokenizer/abbrev.py | 33 ++--- src/tokenizer/definitions.py | 80 ++++++------ src/tokenizer/main.py | 25 ++-- src/tokenizer/tokenizer.py | 231 +++++++++++++++++------------------ 7 files changed, 193 insertions(+), 215 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 19eb2e0..d6bc3ca 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -86,8 +86,10 @@ The tokenizer recognizes 30+ token types including: ## Type Checking - The project uses type annotations in all code and tries to avoid Any types -- Python 3.9 is supported so type annotations should adhere to 3.9-compatible syntax -- Python 3.10 is the oldest supported CPython baseline +- Python 3.10 is the oldest supported CPython baseline, so PEP 604 unions (`X | None`) and + builtin generics (`list[str]`) are fine, but `typing.Self` (3.11) is not +- Tokenizer has no runtime dependencies: never import `typing_extensions` (ruff's + autofix may try to) ## Development Environment diff --git a/pyproject.toml b/pyproject.toml index 54c29e7..d1eea96 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -118,6 +118,7 @@ extend-select = [ ignore = [ "F405", # Name may be undefined, or defined from star imports "E731", # Do not assign a lambda expression, use a def + "SIM102", # Nested ifs mirror the token matching logic; keep them ] [tool.ruff.lint.isort] diff --git a/src/tokenizer/__init__.py b/src/tokenizer/__init__.py index 6ef72f2..05094ee 100644 --- a/src/tokenizer/__init__.py +++ b/src/tokenizer/__init__.py @@ -64,34 +64,34 @@ __version__ = importlib.metadata.version(__name__) __all__ = ( - "__author__", - "__copyright__", - "__version__", + "EM_DASH", + "EN_DASH", + "TOK", + "TP_CENTER", + "TP_LEFT", + "TP_NONE", + "TP_RIGHT", + "TP_WORD", "Abbreviations", "BIN_Tuple", "BIN_TupleList", - "calculate_indexes", "ConfigError", + "Tok", + "TokenStream", + "__author__", + "__copyright__", + "__version__", + "calculate_indexes", "correct_spaces", "detokenize", - "EM_DASH", - "EN_DASH", "generate_raw_tokens", "mark_paragraphs", - "normalized_text_from_tokens", "normalized_text", + "normalized_text_from_tokens", "paragraphs", "parse_tokens", "split_into_sentences", "text_from_tokens", - "Tok", - "TOK", - "tokenize_without_annotation", "tokenize", - "TokenStream", - "TP_CENTER", - "TP_LEFT", - "TP_NONE", - "TP_RIGHT", - "TP_WORD", + "tokenize_without_annotation", ) diff --git a/src/tokenizer/abbrev.py b/src/tokenizer/abbrev.py index f5a7eda..51701a0 100644 --- a/src/tokenizer/abbrev.py +++ b/src/tokenizer/abbrev.py @@ -34,9 +34,10 @@ """ from collections import defaultdict +from collections.abc import Iterator import importlib.resources as importlib_resources from threading import Lock -from typing import Dict, Generic, Iterator, List, Optional, Set, TypeVar +from typing import ClassVar, Generic, TypeVar from .definitions import BIN_Tuple @@ -56,7 +57,7 @@ class OrderedSet(Generic[_T]): def __init__(self) -> None: # Insertions are ordered in Python 3.7+ dicts - self._dict: Dict[_T, None] = {} + self._dict: dict[_T, None] = {} def add(self, item: _T) -> None: """Add an item at the end of the ordered set""" @@ -81,35 +82,35 @@ class Abbreviations: initialized from the config file""" # Dictionary of abbreviations and their meanings - DICT: Dict[str, OrderedSet[BIN_Tuple]] = defaultdict(OrderedSet) + DICT: ClassVar[dict[str, OrderedSet[BIN_Tuple]]] = defaultdict(OrderedSet) # Wrong versions of abbreviations - WRONGDICT: Dict[str, OrderedSet[BIN_Tuple]] = defaultdict(OrderedSet) + WRONGDICT: ClassVar[dict[str, OrderedSet[BIN_Tuple]]] = defaultdict(OrderedSet) # All abbreviation meanings - MEANINGS: Set[str] = set() + MEANINGS: ClassVar[set[str]] = set() # Single-word abbreviations, i.e. those with only one dot at the end - SINGLES: Set[str] = set() + SINGLES: ClassVar[set[str]] = set() # Set of abbreviations without periods, e.g. "td", "osfrv" - WRONGSINGLES: Set[str] = set() + WRONGSINGLES: ClassVar[set[str]] = set() # Potential sentence finishers, i.e. those with a dot at the end, # marked with an asterisk in the config file - FINISHERS: Set[str] = set() + FINISHERS: ClassVar[set[str]] = set() # Abbreviations that should not be seen as such at the end of sentences, # marked with an exclamation mark in the config file - NOT_FINISHERS: Set[str] = set() + NOT_FINISHERS: ClassVar[set[str]] = set() # Abbreviations that should not be seen as such at the end of sentences, but # are allowed in front of person names; marked with a hat ^ in the config file - NAME_FINISHERS: Set[str] = set() + NAME_FINISHERS: ClassVar[set[str]] = set() # Wrong versions of abbreviations with possible corrections # wrong version : [correction1, correction2, ...] - WRONGDOTS: Dict[str, List[str]] = defaultdict(list) + WRONGDOTS: ClassVar[dict[str, list[str]]] = defaultdict(list) # Word forms that should never be interpreted as abbreviations - NOT_ABBREVIATIONS: Set[str] = set() + NOT_ABBREVIATIONS: ClassVar[set[str]] = set() # Ensure that only one thread initializes the abbreviations _lock = Lock() @staticmethod - def add(abbrev: str, meaning: str, gender: str, fl: Optional[str] = None) -> None: + def add(abbrev: str, meaning: str, gender: str, fl: str | None = None) -> None: """Add an abbreviation to the dictionary. Called from the config file handler.""" # Check for sentence finishers @@ -148,7 +149,7 @@ def add(abbrev: str, meaning: str, gender: str, fl: Optional[str] = None) -> Non "Only abbreviations ending with periods " "can be marked as name finishers" ) - if abbrev.endswith("!") or abbrev.endswith("*") or abbrev.endswith("^"): + if abbrev.endswith(("!", "*", "^")): raise ConfigError( "!, * and ^ modifiers are mutually exclusive on abbreviations" ) @@ -214,7 +215,7 @@ def add(abbrev: str, meaning: str, gender: str, fl: Optional[str] = None) -> Non i1 = indices[0] i2 = indices[1] i3 = indices[2] - wabbrevs: List[str] = [] + wabbrevs: list[str] = [] # 1 and 2 removed wabbrevs.append(abbrev[:i1] + abbrev[i1 + 1 : i2] + abbrev[i2 + 1 :]) # 1 and 3 removed @@ -263,7 +264,7 @@ def has_abbreviation(meaning: str) -> bool: return meaning in Abbreviations.MEANINGS @staticmethod - def get_meaning(abbrev: str) -> Optional[list[BIN_Tuple]]: + def get_meaning(abbrev: str) -> list[BIN_Tuple] | None: """Look up meaning(s) of abbreviation, if available.""" m = Abbreviations.DICT.get(abbrev) if not m: diff --git a/src/tokenizer/definitions.py b/src/tokenizer/definitions.py index fdeed44..2c4ef4d 100644 --- a/src/tokenizer/definitions.py +++ b/src/tokenizer/definitions.py @@ -28,28 +28,22 @@ """ +from collections.abc import Callable, Mapping, Sequence import re from typing import ( - Callable, - List, - Mapping, NamedTuple, - Optional, - Sequence, - Tuple, - Union, cast, ) -BeginTuple = Tuple[int, Optional[int]] -PunctuationTuple = Tuple[int, str] -NumberTuple = Tuple[float, Optional[List[str]], Optional[List[str]]] -DateTimeTuple = Tuple[int, int, int] -MeasurementTuple = Tuple[str, float] -TimeStampTuple = Tuple[int, int, int, int, int, int] -AmountTuple = Tuple[float, str, Optional[List[str]], Optional[List[str]]] -TelnoTuple = Tuple[str, str] -CurrencyTuple = Tuple[str, Optional[List[str]], Optional[List[str]]] +BeginTuple = tuple[int, int | None] +PunctuationTuple = tuple[int, str] +NumberTuple = tuple[float, list[str] | None, list[str] | None] +DateTimeTuple = tuple[int, int, int] +MeasurementTuple = tuple[str, float] +TimeStampTuple = tuple[int, int, int, int, int, int] +AmountTuple = tuple[float, str, list[str] | None, list[str] | None] +TelnoTuple = tuple[str, str] +CurrencyTuple = tuple[str, list[str] | None, list[str] | None] class BIN_Tuple(NamedTuple): @@ -74,29 +68,29 @@ def __repr__(self) -> str: class PersonNameTuple(NamedTuple): name: str - gender: Optional[str] - case: Optional[str] + gender: str | None + case: str | None PersonNameList = Sequence[PersonNameTuple] # All possible contents of the Tok.val attribute -ValType = Union[ - None, - int, # YEAR, ORDINAL - str, # USERNAME - BeginTuple, # S_BEGIN - PunctuationTuple, # PUNCTUATION, NUMWLETTER - MeasurementTuple, # MEASUREMENT - TelnoTuple, # TELNO - DateTimeTuple, # DATE, TIME - TimeStampTuple, # TIMESTAMP - NumberTuple, # PERCENT, NUMBER - AmountTuple, # AMOUNT - CurrencyTuple, # CURRENCY - BIN_TupleList, # WORD - PersonNameList, # PERSON -] +ValType = ( + None + | int # YEAR, ORDINAL + | str # USERNAME + | BeginTuple # S_BEGIN + | PunctuationTuple # PUNCTUATION, NUMWLETTER + | MeasurementTuple # MEASUREMENT + | TelnoTuple # TELNO + | DateTimeTuple # DATE, TIME + | TimeStampTuple # TIMESTAMP + | NumberTuple # PERCENT, NUMBER + | AmountTuple # AMOUNT + | CurrencyTuple # CURRENCY + | BIN_TupleList # WORD + | PersonNameList # PERSON +) # This seems to be needed as a workaround for Pylance/Pyright _escape = cast(Callable[[str], str], re.escape) @@ -190,7 +184,7 @@ class PersonNameTuple(NamedTuple): PUNCTUATION = ( LEFT_PUNCTUATION + CENTER_PUNCTUATION + RIGHT_PUNCTUATION + NONE_PUNCTUATION ) -PUNCTUATION_REGEX = "[{0}]".format("|".join(re.escape(p) for p in PUNCTUATION)) +PUNCTUATION_REGEX = "[{}]".format("|".join(re.escape(p) for p in PUNCTUATION)) # Punctuation types: left, center or right of word @@ -460,7 +454,7 @@ class PersonNameTuple(NamedTuple): SINGLECHAR_FRACTIONS = "↉⅒⅑⅛⅐⅙⅕¼⅓½⅖⅔⅜⅗¾⅘⅝⅚⅞" # Derived unit : (base SI unit, conversion factor/function) -SI_UNITS: Mapping[str, tuple[str, Union[float, Callable[[float], float]]]] = { +SI_UNITS: Mapping[str, tuple[str, float | Callable[[float], float]]] = { # Distance "m": ("m", 1.0), "mm": ("m", 1.0e-3), @@ -575,7 +569,7 @@ class PersonNameTuple(NamedTuple): sorted(SI_UNITS.keys(), key=len, reverse=True), ) ) -SI_UNITS_REGEX = re.compile(r"({0})".format(SI_UNITS_REGEX_STRING), re.UNICODE) +SI_UNITS_REGEX = re.compile(rf"({SI_UNITS_REGEX_STRING})", re.UNICODE) CURRENCY_REGEX_STRING = r"|".join( map( @@ -591,18 +585,18 @@ class PersonNameTuple(NamedTuple): # Icelandic-style number, followed by a unit NUM_WITH_UNIT_REGEX1 = re.compile( - r"([-+]?\d+(\.\d\d\d)*(,\d+)?)({0})".format(UNIT_REGEX_STRING), re.UNICODE + rf"([-+]?\d+(\.\d\d\d)*(,\d+)?)({UNIT_REGEX_STRING})", re.UNICODE ) # English-style number, followed by a unit NUM_WITH_UNIT_REGEX2 = re.compile( - r"([-+]?\d+(,\d\d\d)*(\.\d+)?)({0})".format(UNIT_REGEX_STRING), re.UNICODE + rf"([-+]?\d+(,\d\d\d)*(\.\d+)?)({UNIT_REGEX_STRING})", re.UNICODE ) # One or more digits, followed by a unicode vulgar fraction char (e.g. '2½') # and a unit (SI, percent or currency symbol) NUM_WITH_UNIT_REGEX3 = re.compile( - r"(\d+)([\u00BC-\u00BE\u2150-\u215E])({0})".format(UNIT_REGEX_STRING), re.UNICODE + rf"(\d+)([\u00BC-\u00BE\u2150-\u215E])({UNIT_REGEX_STRING})", re.UNICODE ) @@ -688,7 +682,7 @@ def roman_to_int(s: str) -> int: # Amount abbreviations including 'kr' for the ISK # Corresponding abbreviations are found in Abbrev.conf -AMOUNT_ABBREV: Mapping[str, Union[int, float]] = { +AMOUNT_ABBREV: Mapping[str, int | float] = { "kr.": 1, "kr": 1, "krónur": 1, @@ -1042,7 +1036,7 @@ def roman_to_int(s: str) -> int: # Regex to recognise domain names MIN_DOMAIN_LENGTH = 4 # E.g. "t.co" DOMAIN_REGEX = re.compile( - r"({0})({1}*)$".format( + r"({})({}*)$".format( r"|".join(r"\w\." + d for d in map(_escape, TOP_LEVEL_DOMAINS)), PUNCTUATION_REGEX, ), @@ -1178,7 +1172,7 @@ def roman_to_int(s: str) -> int: # Note that we place a further constraint on the token so that # it must contain at least one digit to qualify as a molecular formula ELEMENTS_REGEX = r"|".join(ELEMENTS) -MOLECULE_REGEX = re.compile(r"^(({0})+\d*)+".format(ELEMENTS_REGEX)) +MOLECULE_REGEX = re.compile(rf"^(({ELEMENTS_REGEX})+\d*)+") MOLECULE_FILTER = re.compile(r"\d") diff --git a/src/tokenizer/main.py b/src/tokenizer/main.py index 61ecf30..2b63b94 100755 --- a/src/tokenizer/main.py +++ b/src/tokenizer/main.py @@ -36,19 +36,13 @@ """ import argparse +from collections.abc import Callable, Iterable, Iterator from functools import partial import json import sys from typing import ( Any, - Callable, - Dict, - Iterable, - Iterator, - List, TextIO, - Tuple, - Union, cast, ) @@ -160,7 +154,7 @@ def main() -> None: """Main function, called when the tokenize command is invoked""" args = parser.parse_args() - options: Dict[str, bool] = {} + options: dict[str, bool] = {} def quote(s: str) -> str: """Return the string s within double quotes, and with any contained @@ -173,8 +167,7 @@ def spanquote(lst: Iterable[int]) -> str: def gen(f: TextIO) -> Iterator[str]: """Generate the lines of text in the input file""" - for line in f: - yield line + yield from f def val(t: Tok, quote_word: bool = False) -> Any: """Return the value part of the token t""" @@ -182,7 +175,7 @@ def val(t: Tok, quote_word: bool = False) -> Any: return None if t.kind == TOK.WORD: # Get the full expansion of an abbreviation - mm = cast(List[BIN_Tuple], t.val) + mm = cast(list[BIN_Tuple], t.val) if quote_word: # Return a |-delimited list of possible meanings, # joined into a single string @@ -195,7 +188,7 @@ def val(t: Tok, quote_word: bool = False) -> Any: am = cast(AmountTuple, t.val) if quote_word: # Format as "1234.56|USD" - return '"{0}|{1}"'.format(am[0], am[1]) + return f'"{am[0]}|{am[1]}"' return am[0], am[1] if t.kind == TOK.S_BEGIN: return None @@ -215,7 +208,7 @@ def val(t: Tok, quote_word: bool = False) -> Any: TOK.MEASUREMENT, }: # Return a |-delimited list of numbers - vv = cast(Tuple[Any, ...], t.val) + vv = cast(tuple[Any, ...], t.val) return quote("|".join(str(v) for v in vv)) if quote_word and isinstance(t.val, str): return quote(t.val) @@ -253,14 +246,14 @@ def val(t: Tok, quote_word: bool = False) -> Any: # Configure our JSON dump function json_dumps = partial(json.dumps, ensure_ascii=False, separators=(",", ":")) - curr_sent: List[str] = [] + curr_sent: list[str] = [] tsep = "" if args.original else " " # token separator for t in tokenize(gen(args.infile), **options): if args.csv: # Output the tokens in CSV format, one line per token if t.txt: print( - "{0},{1},{2},{3},{4}".format( + "{},{},{},{},{}".format( t.kind, quote(t.txt), val(t, quote_word=True) or '""', @@ -274,7 +267,7 @@ def val(t: Tok, quote_word: bool = False) -> Any: print('0,"","","",""', file=args.outfile) elif args.json: # Output the tokens in JSON format, one line per token - d: Dict[str, Union[str, List[int]]] = {"k": TOK.descr[t.kind]} + d: dict[str, str | list[int]] = {"k": TOK.descr[t.kind]} if t.txt: d["t"] = t.txt v = val(t) diff --git a/src/tokenizer/tokenizer.py b/src/tokenizer/tokenizer.py index 84b0e95..4094ed1 100644 --- a/src/tokenizer/tokenizer.py +++ b/src/tokenizer/tokenizer.py @@ -39,28 +39,19 @@ """ from collections import deque +from collections.abc import Callable, Iterable, Iterator, Mapping import datetime import re +from re import Match from typing import ( Any, - Callable, - Deque, - Iterable, - Iterator, - List, - Mapping, - Match, - Optional, - Tuple, - Type, TypeVar, - Union, cast, ) import unicodedata from .abbrev import Abbreviations -from .definitions import * # noqa: F403 +from .definitions import * _T = TypeVar("_T", bound="Tok") @@ -110,10 +101,10 @@ class Tok: def __init__( self, kind: int, - txt: Optional[str], + txt: str | None, val: ValType, - original: Optional[str] = None, - origin_spans: Optional[list[int]] = None, + original: str | None = None, + origin_spans: list[int] | None = None, lazy_origin_spans: bool = False, lazy_origin_offset: int = 0, ) -> None: @@ -125,24 +116,25 @@ def __init__( self.val: ValType = val # The full original source string behind this token. # If this is None then we're not tracking origins. - self.original: Optional[str] = original + self.original: str | None = original # _origin_spans contains an integer for each character in 'txt'. # Each such integer index maps the corresponding character # (which may have substitutions) to its index in 'original'. # This is required to preserve 'original' correctly when splitting. - self._origin_spans: Optional[list[int]] = origin_spans + self._origin_spans: list[int] | None = origin_spans # Most raw tokens have a simple identity origin map. Avoid allocating # list(range(len(txt))) until a caller or mutating operation needs it. self._lazy_origin_spans: bool = lazy_origin_spans self._lazy_origin_offset: int = lazy_origin_offset @classmethod - def from_txt(cls: Type[_T], txt: str) -> _T: + # typing.Self needs Python 3.11, so we use a bound TypeVar instead + def from_txt(cls: type[_T], txt: str) -> _T: # noqa: PYI019 """Create a token from text""" return cls(TOK.RAW, txt, None, txt, lazy_origin_spans=True) @classmethod - def from_token(cls: Type[_T], t: "Tok") -> _T: + def from_token(cls: type[_T], t: "Tok") -> _T: # noqa: PYI019 """Create a new Tok instance by copying from a previously existing one""" return cls( t.kind, @@ -155,7 +147,7 @@ def from_token(cls: Type[_T], t: "Tok") -> _T: ) @property - def origin_spans(self) -> Optional[list[int]]: + def origin_spans(self) -> list[int] | None: """Return origin spans, materializing the identity map lazily.""" if self._lazy_origin_spans: self._origin_spans = [ @@ -166,7 +158,7 @@ def origin_spans(self) -> Optional[list[int]]: return self._origin_spans @origin_spans.setter - def origin_spans(self, value: Optional[list[int]]) -> None: + def origin_spans(self, value: list[int] | None) -> None: self._origin_spans = value self._lazy_origin_spans = False self._lazy_origin_offset = 0 @@ -237,7 +229,7 @@ def person_names(self) -> PersonNameList: return [] return cast(PersonNameList, self.val) or [] - def split(self, pos: int) -> Tuple["Tok", "Tok"]: + def split(self, pos: int) -> tuple["Tok", "Tok"]: """Split this token into two at 'pos'. The first token returned will have 'pos' characters and the second one will have the rest. @@ -312,7 +304,7 @@ def split(self, pos: int) -> Tuple["Tok", "Tok"]: return ltk, rtk - def substitute(self, span: Tuple[int, int], new: str) -> None: + def substitute(self, span: tuple[int, int], new: str) -> None: """Substitute a span with a single or empty character 'new'.""" if self._lazy_origin_spans and new == "" and span[0] == 0: self.txt = self.txt[span[1] :] @@ -322,11 +314,11 @@ def substitute(self, span: Tuple[int, int], new: str) -> None: self.txt = self.txt[: span[0]] + new + self.txt[span[1] :] if origin_spans is not None: # Remove origin entries that correspond to characters that are gone. - self.origin_spans = origin_spans[: span[0] + len(new)] + origin_spans[ - span[1] : - ] + self.origin_spans = ( + origin_spans[: span[0] + len(new)] + origin_spans[span[1] :] + ) - def substitute_longer(self, span: Tuple[int, int], new: str) -> None: + def substitute_longer(self, span: tuple[int, int], new: str) -> None: """Substitute a span with a potentially longer string""" # This tracks origin differently from the regular @@ -417,7 +409,7 @@ def concatenate( self_origin_spans = self.origin_spans or [] other_origin_spans = other.origin_spans or [] - separator_origin_spans: List[int] = ( + separator_origin_spans: list[int] = ( [len(self_original)] * len(separator) if len(other_origin_spans) > 0 else [] ) new_origin_spans = ( @@ -429,12 +421,12 @@ def concatenate( return Tok(new_kind, new_txt, new_val, new_original, new_origin_spans) @property - def as_tuple(self) -> Tuple[Any, ...]: + def as_tuple(self) -> tuple[Any, ...]: """Return the contents of this token as a generic tuple, suitable e.g. for serialization""" return (self.kind, self.txt, self.val) - def __getitem__(self, i: int) -> Union[int, str, ValType]: + def __getitem__(self, i: int) -> int | str | ValType: """Backwards compatibility for when Tok was a namedtuple.""" if i == 0: return self.kind @@ -637,7 +629,7 @@ class TOK: # Token constructors @staticmethod - def Punctuation(t: Union[Tok, str], normalized: Optional[str] = None) -> Tok: + def Punctuation(t: Tok | str, normalized: str | None = None) -> Tok: tp = TP_CENTER # Default punctuation type if normalized is None: if isinstance(t, str): @@ -658,7 +650,7 @@ def Punctuation(t: Union[Tok, str], normalized: Optional[str] = None) -> Tok: return t @staticmethod - def Time(t: Union[Tok, str], h: int, m: int, s: int) -> Tok: + def Time(t: Tok | str, h: int, m: int, s: int) -> Tok: if isinstance(t, str): return Tok(TOK.TIME, t, (h, m, s)) t.kind = TOK.TIME @@ -666,7 +658,7 @@ def Time(t: Union[Tok, str], h: int, m: int, s: int) -> Tok: return t @staticmethod - def Date(t: Union[Tok, str], y: int, m: int, d: int) -> Tok: + def Date(t: Tok | str, y: int, m: int, d: int) -> Tok: if isinstance(t, str): return Tok(TOK.DATE, t, (y, m, d)) t.kind = TOK.DATE @@ -674,7 +666,7 @@ def Date(t: Union[Tok, str], y: int, m: int, d: int) -> Tok: return t @staticmethod - def Dateabs(t: Union[Tok, str], y: int, m: int, d: int) -> Tok: + def Dateabs(t: Tok | str, y: int, m: int, d: int) -> Tok: if isinstance(t, str): return Tok(TOK.DATEABS, t, (y, m, d)) t.kind = TOK.DATEABS @@ -682,7 +674,7 @@ def Dateabs(t: Union[Tok, str], y: int, m: int, d: int) -> Tok: return t @staticmethod - def Daterel(t: Union[Tok, str], y: int, m: int, d: int) -> Tok: + def Daterel(t: Tok | str, y: int, m: int, d: int) -> Tok: if isinstance(t, str): return Tok(TOK.DATEREL, t, (y, m, d)) t.kind = TOK.DATEREL @@ -690,9 +682,7 @@ def Daterel(t: Union[Tok, str], y: int, m: int, d: int) -> Tok: return t @staticmethod - def Timestamp( - t: Union[Tok, str], y: int, mo: int, d: int, h: int, m: int, s: int - ) -> Tok: + def Timestamp(t: Tok | str, y: int, mo: int, d: int, h: int, m: int, s: int) -> Tok: if isinstance(t, str): return Tok(TOK.TIMESTAMP, t, (y, mo, d, h, m, s)) t.kind = TOK.TIMESTAMP @@ -701,7 +691,7 @@ def Timestamp( @staticmethod def Timestampabs( - t: Union[Tok, str], y: int, mo: int, d: int, h: int, m: int, s: int + t: Tok | str, y: int, mo: int, d: int, h: int, m: int, s: int ) -> Tok: if isinstance(t, str): return Tok(TOK.TIMESTAMPABS, t, (y, mo, d, h, m, s)) @@ -711,7 +701,7 @@ def Timestampabs( @staticmethod def Timestamprel( - t: Union[Tok, str], y: int, mo: int, d: int, h: int, m: int, s: int + t: Tok | str, y: int, mo: int, d: int, h: int, m: int, s: int ) -> Tok: if isinstance(t, str): return Tok(TOK.TIMESTAMPREL, t, (y, mo, d, h, m, s)) @@ -720,7 +710,7 @@ def Timestamprel( return t @staticmethod - def Year(t: Union[Tok, str], n: int) -> Tok: + def Year(t: Tok | str, n: int) -> Tok: if isinstance(t, str): return Tok(TOK.YEAR, t, n) t.kind = TOK.YEAR @@ -728,7 +718,7 @@ def Year(t: Union[Tok, str], n: int) -> Tok: return t @staticmethod - def Telno(t: Union[Tok, str], telno: str, cc: str = "354") -> Tok: + def Telno(t: Tok | str, telno: str, cc: str = "354") -> Tok: # The t parameter is the original token text, # while telno has the standard form 'DDD-DDDD' (with hyphen) # cc is the country code @@ -739,7 +729,7 @@ def Telno(t: Union[Tok, str], telno: str, cc: str = "354") -> Tok: return t @staticmethod - def Email(t: Union[Tok, str]) -> Tok: + def Email(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.EMAIL, t, None) t.kind = TOK.EMAIL @@ -748,10 +738,10 @@ def Email(t: Union[Tok, str]) -> Tok: @staticmethod def Number( - t: Union[Tok, str], + t: Tok | str, n: float, - cases: Optional[list[str]] = None, - genders: Optional[list[str]] = None, + cases: list[str] | None = None, + genders: list[str] | None = None, ) -> Tok: # The cases parameter is a list of possible cases for this number # (if it was originally stated in words) @@ -762,7 +752,7 @@ def Number( return t @staticmethod - def NumberWithLetter(t: Union[Tok, str], n: int, c: str) -> Tok: + def NumberWithLetter(t: Tok | str, n: int, c: str) -> Tok: if isinstance(t, str): return Tok(TOK.NUMWLETTER, t, (n, c)) t.kind = TOK.NUMWLETTER @@ -771,10 +761,10 @@ def NumberWithLetter(t: Union[Tok, str], n: int, c: str) -> Tok: @staticmethod def Currency( - t: Union[Tok, str], + t: Tok | str, iso: str, - cases: Optional[list[str]] = None, - genders: Optional[list[str]] = None, + cases: list[str] | None = None, + genders: list[str] | None = None, ) -> Tok: # The cases parameter is a list of possible cases for this currency name # (if it was originally stated in words, i.e. not abbreviated) @@ -786,11 +776,11 @@ def Currency( @staticmethod def Amount( - t: Union[Tok, str], + t: Tok | str, iso: str, n: float, - cases: Optional[list[str]] = None, - genders: Optional[list[str]] = None, + cases: list[str] | None = None, + genders: list[str] | None = None, ) -> Tok: # The cases parameter is a list of possible cases for this amount # (if it was originally stated in words) @@ -802,10 +792,10 @@ def Amount( @staticmethod def Percent( - t: Union[Tok, str], + t: Tok | str, n: float, - cases: Optional[list[str]] = None, - genders: Optional[list[str]] = None, + cases: list[str] | None = None, + genders: list[str] | None = None, ) -> Tok: if isinstance(t, str): return Tok(TOK.PERCENT, t, (n, cases, genders)) @@ -814,7 +804,7 @@ def Percent( return t @staticmethod - def Ordinal(t: Union[Tok, str], n: int) -> Tok: + def Ordinal(t: Tok | str, n: int) -> Tok: if isinstance(t, str): return Tok(TOK.ORDINAL, t, n) t.kind = TOK.ORDINAL @@ -822,7 +812,7 @@ def Ordinal(t: Union[Tok, str], n: int) -> Tok: return t @staticmethod - def Url(t: Union[Tok, str]) -> Tok: + def Url(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.URL, t, None) t.kind = TOK.URL @@ -830,7 +820,7 @@ def Url(t: Union[Tok, str]) -> Tok: return t @staticmethod - def Domain(t: Union[Tok, str]) -> Tok: + def Domain(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.DOMAIN, t, None) t.kind = TOK.DOMAIN @@ -838,7 +828,7 @@ def Domain(t: Union[Tok, str]) -> Tok: return t @staticmethod - def Hashtag(t: Union[Tok, str]) -> Tok: + def Hashtag(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.HASHTAG, t, None) t.kind = TOK.HASHTAG @@ -846,7 +836,7 @@ def Hashtag(t: Union[Tok, str]) -> Tok: return t @staticmethod - def Ssn(t: Union[Tok, str]) -> Tok: + def Ssn(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.SSN, t, None) t.kind = TOK.SSN @@ -854,7 +844,7 @@ def Ssn(t: Union[Tok, str]) -> Tok: return t @staticmethod - def Molecule(t: Union[Tok, str]) -> Tok: + def Molecule(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.MOLECULE, t, None) t.kind = TOK.MOLECULE @@ -862,7 +852,7 @@ def Molecule(t: Union[Tok, str]) -> Tok: return t @staticmethod - def Username(t: Union[Tok, str], username: str) -> Tok: + def Username(t: Tok | str, username: str) -> Tok: if isinstance(t, str): return Tok(TOK.USERNAME, t, username) t.kind = TOK.USERNAME @@ -870,7 +860,7 @@ def Username(t: Union[Tok, str], username: str) -> Tok: return t @staticmethod - def SerialNumber(t: Union[Tok, str]) -> Tok: + def SerialNumber(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.SERIALNUMBER, t, None) t.kind = TOK.SERIALNUMBER @@ -878,7 +868,7 @@ def SerialNumber(t: Union[Tok, str]) -> Tok: return t @staticmethod - def Measurement(t: Union[Tok, str], unit: str, val: float) -> Tok: + def Measurement(t: Tok | str, unit: str, val: float) -> Tok: if isinstance(t, str): return Tok(TOK.MEASUREMENT, t, (unit, val)) t.kind = TOK.MEASUREMENT @@ -886,7 +876,7 @@ def Measurement(t: Union[Tok, str], unit: str, val: float) -> Tok: return t @staticmethod - def Word(t: Union[Tok, str], m: Optional[BIN_TupleList] = None) -> Tok: + def Word(t: Tok | str, m: BIN_TupleList | None = None) -> Tok: # The m parameter is intended for a list of BIN_Tuple instances # fetched from the BÍN database, in 'SHsnid' format if isinstance(t, str): @@ -896,7 +886,7 @@ def Word(t: Union[Tok, str], m: Optional[BIN_TupleList] = None) -> Tok: return t @staticmethod - def Unknown(t: Union[Tok, str]) -> Tok: + def Unknown(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.UNKNOWN, t, None) t.kind = TOK.UNKNOWN @@ -904,7 +894,7 @@ def Unknown(t: Union[Tok, str]) -> Tok: return t @staticmethod - def Person(t: Union[Tok, str], m: Optional[PersonNameList] = None) -> Tok: + def Person(t: Tok | str, m: PersonNameList | None = None) -> Tok: # The m parameter is intended for a list of PersonName tuples: # (name, gender, case) if isinstance(t, str): @@ -914,7 +904,7 @@ def Person(t: Union[Tok, str], m: Optional[PersonNameList] = None) -> Tok: return t @staticmethod - def Entity(t: Union[Tok, str]) -> Tok: + def Entity(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.ENTITY, t, None) t.kind = TOK.ENTITY @@ -922,7 +912,7 @@ def Entity(t: Union[Tok, str]) -> Tok: return t @staticmethod - def Company(t: Union[Tok, str]) -> Tok: + def Company(t: Tok | str) -> Tok: if isinstance(t, str): return Tok(TOK.COMPANY, t, None) t.kind = TOK.COMPANY @@ -945,9 +935,9 @@ def End_Paragraph() -> Tok: @staticmethod def Begin_Sentence( - t: Optional[Tok] = None, + t: Tok | None = None, num_parses: int = 0, - err_index: Optional[int] = None, + err_index: int | None = None, ) -> Tok: if t is None: return Tok(TOK.S_BEGIN, None, (num_parses, err_index)) @@ -956,7 +946,7 @@ def Begin_Sentence( return t @staticmethod - def End_Sentence(t: Optional[Tok] = None) -> Tok: + def End_Sentence(t: Tok | None = None) -> Tok: if t is None: return Tok(TOK.S_END, None, None) t.kind = TOK.S_END @@ -964,7 +954,7 @@ def End_Sentence(t: Optional[Tok] = None) -> Tok: return t @staticmethod - def End_Sentinel(t: Optional[Tok] = None) -> Tok: + def End_Sentinel(t: Tok | None = None) -> Tok: if t is None: return Tok(TOK.X_END, None, None) t.kind = TOK.X_END @@ -972,7 +962,7 @@ def End_Sentinel(t: Optional[Tok] = None) -> Tok: return t @staticmethod - def Split_Sentence(t: Optional[Tok] = None) -> Tok: + def Split_Sentence(t: Tok | None = None) -> Tok: if t is None: return Tok(TOK.S_SPLIT, None, None) t.kind = TOK.S_SPLIT @@ -988,7 +978,7 @@ def __init__(self, token_it: Iterator[Tok], *, lookahead_size: int = 2): self._it: Iterator[Tok] = token_it if lookahead_size <= 0: lookahead_size = 1 - self._lookahead: Deque[Tok] = deque(maxlen=lookahead_size) + self._lookahead: deque[Tok] = deque(maxlen=lookahead_size) self._max_lookahead: int = lookahead_size def __next__(self) -> Tok: @@ -999,7 +989,7 @@ def __next__(self) -> Tok: def __iter__(self): return self - def __getitem__(self, i: int) -> Optional[Tok]: + def __getitem__(self, i: int) -> Tok | None: if 0 <= i < self._max_lookahead: llk = len(self._lookahead) try: @@ -1012,52 +1002,52 @@ def __getitem__(self, i: int) -> Optional[Tok]: pass return None - def txt(self, i: int = 0) -> Optional[str]: + def txt(self, i: int = 0) -> str | None: """Return token.txt for token at index i.""" t = self[i] return t.txt if t else None - def kind(self, i: int = 0) -> Optional[int]: + def kind(self, i: int = 0) -> int | None: """Return token.kind for token at index i.""" t = self[i] return t.kind if t else None - def punctuation(self, i: int = 0) -> Optional[str]: + def punctuation(self, i: int = 0) -> str | None: """Return token.punctuation for token at index i.""" t = self[i] return t.punctuation if t else None - def number(self, i: int = 0) -> Optional[float]: + def number(self, i: int = 0) -> float | None: """Return token.number for token at index i.""" t = self[i] return t.number if t else None - def integer(self, i: int = 0) -> Optional[int]: + def integer(self, i: int = 0) -> int | None: """Return token.integer for token at index i.""" t = self[i] return t.integer if t else None - def ordinal(self, i: int = 0) -> Optional[int]: + def ordinal(self, i: int = 0) -> int | None: """Return token.ordinal for token at index i.""" t = self[i] return t.ordinal if t else None - def has_meanings(self, i: int = 0) -> Optional[bool]: + def has_meanings(self, i: int = 0) -> bool | None: """Return token.has_meanings for token at index i.""" t = self[i] return t.has_meanings if t else None - def meanings(self, i: int = 0) -> Optional[BIN_TupleList]: + def meanings(self, i: int = 0) -> BIN_TupleList | None: """Return token.meanings for token at index i.""" t = self[i] return t.meanings if t else None - def person_names(self, i: int = 0) -> Optional[PersonNameList]: + def person_names(self, i: int = 0) -> PersonNameList | None: """Return token.person_names for token at index i.""" t = self[i] return t.person_names if t else None - def as_tuple(self, i: int = 0) -> Optional[tuple[Any, ...]]: + def as_tuple(self, i: int = 0) -> tuple[Any, ...] | None: """Return token.as_tuple for token at index i.""" t = self[i] return t.as_tuple if t else None @@ -1091,17 +1081,17 @@ def is_valid_date(y: int, m: int, d: int) -> bool: """Returns True if y, m, d is a valid date""" if (1776 <= y <= 2100) and (1 <= m <= 12) and (1 <= d <= DAYS_IN_MONTH[m]): try: - datetime.datetime(year=y, month=m, day=d) + datetime.date(year=y, month=m, day=d) return True except ValueError: pass return False -def parse_digits(tok: Tok, convert_numbers: bool) -> Tuple[Tok, Tok]: +def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: """Parse a raw token starting with a digit""" w = tok.txt - s: Optional[Match[str]] = re.match(r"\d{1,2}:\d\d:\d\d,\d\d(?!\d)", w) + s: Match[str] | None = re.match(r"\d{1,2}:\d\d:\d\d,\d\d(?!\d)", w) g: str n: str if s: @@ -1441,7 +1431,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> Tuple[Tok, Tok]: ) -def html_escape(match: Match[str]) -> Tuple[Tuple[int, int], str]: +def html_escape(match: Match[str]) -> tuple[tuple[int, int], str]: """Regex substitution function for HTML escape codes""" g = match.group(4) if g is not None: @@ -1451,7 +1441,8 @@ def html_escape(match: Match[str]) -> Tuple[Tuple[int, int], str]: if g is not None: # Hex code: '#xABCD' try: - return match.span(), chr(int(g[2:], base=16)) + # g[2:] strips '#x', not a '0x' prefix that base=0 would accept + return match.span(), chr(int(g[2:], base=16)) # noqa: FURB166 except (OverflowError, ValueError): return match.span(), match.group(0) g = match.group(3) @@ -1539,7 +1530,7 @@ def generate_rough_tokens_from_tok(tok: Tok) -> Iterator[Tok]: # This function further splits those tokens into multiple tokens. # Rough tokens are tokens that are separated by white space, i.e. the regex (\\s*). - def shift_span(span: Tuple[int, int], pos: int) -> Tuple[int, int]: + def shift_span(span: tuple[int, int], pos: int) -> tuple[int, int]: """Shift a span by a given amount""" return (span[SPAN_START] + pos, span[SPAN_END] + pos) @@ -1569,7 +1560,7 @@ def shift_span(span: Tuple[int, int], pos: int) -> Tuple[int, int]: def generate_raw_tokens( - text_or_gen: Union[str, Iterable[str]], + text_or_gen: str | Iterable[str], replace_composite_glyphs: bool = True, replace_html_escapes: bool = False, one_sent_per_line: bool = False, @@ -1585,7 +1576,7 @@ def generate_raw_tokens( text_or_gen = [text_or_gen] # Iterate through text_or_gen, which is assumed to yield strings - saved: Optional[Tok] = None + saved: Tok | None = None # The following declaration seems to be required for Pylance big_text: str @@ -1600,7 +1591,7 @@ def generate_raw_tokens( if saved is not None: # The following strange code satisfies Pylance - so: Optional[str] = saved.original + so: str | None = saved.original big_text = (so or "") + big_text saved = None @@ -1885,7 +1876,7 @@ def parse(self, rt: Tok) -> Iterable[Tok]: elif rtxt.startswith("[…]"): punct, rt = rt.split(3) yield TOK.Punctuation(punct) - elif rtxt.startswith("...") or rtxt.startswith("…"): + elif rtxt.startswith(("...", "…")): # Treat >= 3 periods as ellipsis, one piece of punctuation numdots = 0 for c in rtxt: @@ -2140,7 +2131,7 @@ def is_word_with_composites(txt: str) -> bool: ) -def parse_tokens(txt: Union[str, Iterable[str]], **options: Any) -> Iterator[Tok]: +def parse_tokens(txt: str | Iterable[str], **options: Any) -> Iterator[Tok]: """Generator that parses contiguous text into a stream of tokens""" # Obtain individual flags from the options dict @@ -2283,7 +2274,7 @@ def is_abbr_with_period(txt: str) -> bool: return txt not in Abbreviations.DICT return False - def lookup(abbrev: str) -> Optional[list[BIN_Tuple]]: + def lookup(abbrev: str) -> list[BIN_Tuple] | None: """Look up an abbreviation, both in original case and in lower case, and return either None if not found or a meaning list having one entry""" m = Abbreviations.DICT.get(abbrev) @@ -2398,7 +2389,7 @@ def lookup(abbrev: str) -> Optional[list[BIN_Tuple]]: # next_token.txt may be a real number, i.e. 13,40, # which may have been converted from 13.40 # If we now have hh.mm, parse it as such - a = "{0:.2f}".format(next_token.number).split(".") + a = f"{next_token.number:.2f}".split(".") h, m = int(a[0]), int(a[1]) token = TOK.Time( token.concatenate(next_token, separator=" "), @@ -2498,7 +2489,7 @@ def lookup(abbrev: str) -> Optional[list[BIN_Tuple]]: ): # Ordinal, i.e. whole number or Roman numeral followed by period: # convert to an ordinal token - ord_token: Optional[Tok] = token_stream[0] + ord_token: Tok | None = token_stream[0] if ord_token and not ( ord_token.kind in TOK.END or ord_token.punctuation in {"„", '"'} @@ -2671,7 +2662,7 @@ def parse_sentences(token_stream: Iterator[Tok]) -> Iterator[Tok]: exclamation marks, etc.)""" in_sentence = False - token: Optional[Tok] = None + token: Tok | None = None tok_begin_sentence = TOK.Begin_Sentence() tok_end_sentence = TOK.End_Sentence() @@ -2790,14 +2781,14 @@ def parse_sentences(token_stream: Iterator[Tok]) -> Iterator[Tok]: yield tok_end_sentence -def match_stem_list(token: Tok, stems: Mapping[str, float]) -> Optional[float]: +def match_stem_list(token: Tok, stems: Mapping[str, float]) -> float | None: """Find the stem of a word token in given dict, or return None if not found""" if token.kind != TOK.WORD: return None return stems.get(token.txt.lower(), None) -def month_for_token(token: Tok, after_ordinal: bool = False) -> Optional[int]: +def month_for_token(token: Tok, after_ordinal: bool = False) -> int | None: """Return a number, 1..12, corresponding to a month name, or None if the token does not contain a month name""" if not after_ordinal and token.txt in MONTH_BLACKLIST: @@ -2823,7 +2814,7 @@ def parse_phrases_1(token_stream: Iterator[Tok]) -> Iterator[Tok]: if abbrev in Abbreviations.FINISHERS: token = TOK.Word( token.concatenate(next_token), - cast(Optional[list[BIN_Tuple]], token.val), + cast(list[BIN_Tuple] | None, token.val), ) next_token = next(token_stream) @@ -2997,9 +2988,7 @@ def parse_date_and_time(token_stream: Iterator[Tok]) -> Iterator[Tok]: # into DATEREL, hyphen and DATEREL. The guard is deliberately # cheap: only WORD tokens containing a hyphen or an en dash # are examined any further. - if token.kind == TOK.WORD and ( - HYPHEN in token.txt or EN_DASH in token.txt - ): + if token.kind == TOK.WORD and (HYPHEN in token.txt or EN_DASH in token.txt): hchar = HYPHEN if HYPHEN in token.txt else EN_DASH a = token.txt.split(hchar) if ( @@ -3236,7 +3225,7 @@ def parse_phrases_2( # Check for composites: # 'stjórnskipunar- og eftirlitsnefnd' # 'dómsmála-, viðskipta- og iðnaðarráðherra' - tq: List[Tok] = [] + tq: list[Tok] = [] while token.kind == TOK.WORD and next_token.punctuation == COMPOSITE_HYPHEN: # Accumulate the prefix in tq tq.append(token) @@ -3296,7 +3285,7 @@ def parse_phrases_2( yield token -def tokenize(text_or_gen: Union[str, Iterable[str]], **options: Any) -> Iterator[Tok]: +def tokenize(text_or_gen: str | Iterable[str], **options: Any) -> Iterator[Tok]: """Tokenize text in several phases, returning a generator (iterable sequence) of tokens that processes tokens on-demand.""" @@ -3321,7 +3310,7 @@ def tokenize(text_or_gen: Union[str, Iterable[str]], **options: Any) -> Iterator def tokenize_without_annotation( - text_or_gen: Union[str, Iterable[str]], **options: Any + text_or_gen: str | Iterable[str], **options: Any ) -> Iterator[Tok]: """Tokenize without the last pass which can be done more thoroughly if BÍN annotation is available, for instance in GreynirEngine.""" @@ -3329,7 +3318,7 @@ def tokenize_without_annotation( def split_into_sentences( - text_or_gen: Union[str, Iterable[str]], **options: Any + text_or_gen: str | Iterable[str], **options: Any ) -> Iterator[str]: """Shallow tokenization of the input text, which can be either a text string or a generator of lines of text (such as a file). @@ -3351,7 +3340,7 @@ def split_into_sentences( to_text = lambda t: t.original or t.txt else: to_text = lambda t: t.txt - curr_sent: List[str] = [] + curr_sent: list[str] = [] for t in tokenize_without_annotation(text_or_gen, **options): if t.kind in TOK.END: # End of sentence/paragraph @@ -3388,7 +3377,7 @@ def paragraphs(tokens: Iterable[Tok]) -> Iterator[list[tuple[int, list[Tok]]]]: sentence, not including the starting TOK.S_BEGIN or the terminating TOK.S_END tokens.""" - def valid_sent(sent: Optional[list[Tok]]) -> bool: + def valid_sent(sent: list[Tok] | None) -> bool: """Return True if the token list in sent is a proper sentence that we want to process further""" if not sent: @@ -3396,9 +3385,9 @@ def valid_sent(sent: Optional[list[Tok]]) -> bool: # A sentence with only punctuation is not valid return any(t[0] != TOK.PUNCTUATION for t in sent) - sent: List[Tok] = [] # Current sentence + sent: list[Tok] = [] # Current sentence sent_begin = 0 - current_p: List[Tuple[int, List[Tok]]] = [] # Current paragraph + current_p: list[tuple[int, list[Tok]]] = [] # Current paragraph for ix, t in enumerate(tokens): t0 = t[0] @@ -3444,9 +3433,7 @@ def valid_sent(sent: Optional[list[Tok]]) -> bool: # The following regex catches consecutive identical hyphens/dashes r"|(--+|––+|——+)" # --, ––, —— # Finally, space and punctuation - r"|([~\s" - + "".join("\\" + c for c in PUNCTUATION) - + r"])" + r"|([~\s" + "".join("\\" + c for c in PUNCTUATION) + r"])" ) RE_SPLIT = re.compile(RE_SPLIT_STR) @@ -3456,7 +3443,7 @@ def correct_spaces(s: str) -> str: with correct spacing between tokens. NOTE that this function uses a quick-and-dirty approach which may not handle all edge cases!""" - r: List[str] = [] + r: list[str] = [] last = TP_NONE double_quote_count = 0 last_was_word = False # Track if previous non-empty token was a word @@ -3563,7 +3550,7 @@ def detokenize(tokens: Iterable[Tok], normalize: bool = False) -> str: to a correctly spaced string. If normalize is True, punctuation is normalized before assembling the string.""" to_text: Callable[[Tok], str] = normalized_text if normalize else lambda t: t.txt - r: List[str] = [] + r: list[str] = [] last = TP_NONE last_kind = None # Track the previous token kind double_quote_count = 0 @@ -3612,7 +3599,7 @@ def detokenize(tokens: Iterable[Tok], normalize: bool = False) -> str: def calculate_indexes( tokens: Iterable[Tok], last_is_end: bool = False -) -> Tuple[List[int], List[int]]: +) -> tuple[list[int], list[int]]: """Calculate character and byte indexes for a token stream. The indexes are the start positions of each token in the original text that was tokenized. From 9305051e3713ebed938887a4547ad3dc2f191a15 Mon Sep 17 00:00:00 2001 From: vthorsteinsson Date: Tue, 13 Oct 2026 22:20:46 +0000 Subject: [PATCH 2/3] Speed up tokenization ~25% and add a performance bench Profiling with the CPython 3.15 sampling profiler (`profiling.sampling`) showed two low-hanging hot spots in the raw token stages: - `zerowidth_replacement` and `composite_replacement` ran a regex scan on every raw token, although such characters are rare. Check once per text instead, and skip the per-token passes when none are present (a removed zero-width character can bring a composite glyph together, so its presence also enables the composite pass). ~10%. - `parse_digits` tries up to ~25 `re.match(, w)` calls per numeric token, each paying ~220 ns of `re` cache lookup before matching. Precompile all string-pattern regexes in tokenizer.py at module level, and use `str.replace` for the literal `re.sub` calls. ~12%. Token output is byte-identical (digests of kind, txt, val, original and origin_spans over the large test set). Speedup on the large test set: +25% on CPython 3.13, +28% on 3.14, +22% on 3.15. bench/bench.py times five workloads (tokenize with and without annotation, single-string input, split_into_sentences, original=True) and records an output digest per workload; --save/--compare report the speed change and whether output is identical. bench/profile.sh runs the 3.15 sampling profiler with --blocking, which is required here: without it the profiler fails to unwind ~70% of stacks in the generator pipeline and attributes inner stages' work to the next() calls of outer ones. Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 9 ++ bench/.gitignore | 1 + bench/bench.py | 180 +++++++++++++++++++++++++++++++++++++ bench/profile.sh | 61 +++++++++++++ src/tokenizer/tokenizer.py | 120 ++++++++++++++++--------- 5 files changed, 330 insertions(+), 41 deletions(-) create mode 100644 bench/.gitignore create mode 100755 bench/bench.py create mode 100755 bench/profile.sh diff --git a/CLAUDE.md b/CLAUDE.md index d6bc3ca..164d144 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -57,6 +57,15 @@ tokenize test/toktest_large.txt test/toktest_large_out.txt diff test/toktest_large_out.txt test/toktest_large_gold_acceptable.txt ``` +### Performance Bench +```bash +python bench/bench.py --save /tmp/base.json # timings + output digests +python bench/bench.py --compare /tmp/base.json # speed change, "same"/"OUTPUT DIFFERS" +bench/profile.sh tokenize 15 # CPython 3.15 sampling profiler +``` +Profile with `--blocking` (profile.sh does): without it the 3.15 sampler fails to +unwind ~70% of stacks in the generator pipeline and misattributes time. + ## Token Types The tokenizer recognizes 30+ token types including: diff --git a/bench/.gitignore b/bench/.gitignore new file mode 100644 index 0000000..89f9ac0 --- /dev/null +++ b/bench/.gitignore @@ -0,0 +1 @@ +out/ diff --git a/bench/bench.py b/bench/bench.py new file mode 100755 index 0000000..72518bb --- /dev/null +++ b/bench/bench.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python3 +""" +Tokenizer performance bench. + +Times a handful of realistic workloads over the test corpus and prints a +digest of the full token output for each, so that an optimization can be +checked for identical results as well as for speed. + + python bench/bench.py # time all workloads + python bench/bench.py -w tokenize -n 10 # one workload, 10 runs + python bench/bench.py --save base.json # record timings + digests + python bench/bench.py --compare base.json # diff against a recording + python bench/bench.py --loop tokenize -s 20 # busy loop for a profiler + +Profile with the CPython 3.15 sampling profiler, see bench/profile.sh. +""" + +import argparse +from collections import deque +from collections.abc import Callable, Iterable, Iterator +import gc +import hashlib +import json +from pathlib import Path +import sys +import time + +from tokenizer import Tok, split_into_sentences, tokenize +from tokenizer.abbrev import Abbreviations + +ROOT = Path(__file__).resolve().parent.parent +DEFAULT_FILES = [ + ROOT / "test" / "toktest_large.txt", + ROOT / "test" / "Overview.txt", +] + + +def load_lines(files: list[Path], repeat: int) -> list[str]: + lines: list[str] = [] + for f in files: + lines.extend(f.read_text(encoding="utf-8").splitlines(keepends=True)) + return lines * repeat + + +def tok_record(t: Tok) -> str: + return repr((t.kind, t.txt, t.val, t.original, t.origin_spans)) + + +# Each workload maps the input lines to an iterator of strings that +# fully describe its output; timing consumes the iterator unhashed, +# digesting hashes it. +Workload = Callable[[list[str]], Iterator[str]] + + +def w_tokenize(lines: list[str]) -> Iterator[str]: + return map(tok_record, tokenize(lines)) + + +def w_tokenize_noann(lines: list[str]) -> Iterator[str]: + return map(tok_record, tokenize(lines, with_annotation=False)) + + +def w_tokenize_text(lines: list[str]) -> Iterator[str]: + # A single string rather than a line iterator + return map(tok_record, tokenize("".join(lines))) + + +def w_sentences(lines: list[str]) -> Iterator[str]: + return split_into_sentences(lines) + + +def w_sentences_original(lines: list[str]) -> Iterator[str]: + return split_into_sentences(lines, original=True) + + +# For timing we skip tok_record() so that only tokenizer work is measured +TIMED: dict[str, Callable[[list[str]], Iterable[object]]] = { + "tokenize": lambda lines: tokenize(lines), + "tokenize_noann": lambda lines: tokenize(lines, with_annotation=False), + "tokenize_text": lambda lines: tokenize("".join(lines)), + "sentences": lambda lines: split_into_sentences(lines), + "sentences_original": lambda lines: split_into_sentences(lines, original=True), +} +DIGESTED: dict[str, Workload] = { + "tokenize": w_tokenize, + "tokenize_noann": w_tokenize_noann, + "tokenize_text": w_tokenize_text, + "sentences": w_sentences, + "sentences_original": w_sentences_original, +} + + +def time_once(name: str, lines: list[str]) -> float: + fn = TIMED[name] + gc.collect() + t0 = time.perf_counter() + deque(fn(lines), maxlen=0) + return time.perf_counter() - t0 + + +def digest(name: str, lines: list[str]) -> tuple[str, int]: + h = hashlib.sha256() + n = 0 + for rec in DIGESTED[name](lines): + h.update(rec.encode("utf-8")) + h.update(b"\n") + n += 1 + return h.hexdigest()[:16], n + + +def main() -> None: + ap = argparse.ArgumentParser(description=__doc__.split("\n\n")[0]) + ap.add_argument("-w", "--workload", action="append", choices=list(TIMED)) + ap.add_argument( + "-n", "--runs", type=int, default=5, help="timed runs (min is reported)" + ) + ap.add_argument( + "-r", "--repeat", type=int, default=1, help="repeat the corpus N times" + ) + ap.add_argument("-f", "--file", action="append", type=Path, help="input file(s)") + ap.add_argument("--no-digest", action="store_true", help="skip the output digest") + ap.add_argument("--save", type=Path, help="save results as JSON") + ap.add_argument("--compare", type=Path, help="compare with saved JSON") + ap.add_argument( + "--loop", + choices=list(TIMED), + help="run one workload repeatedly (for attaching or running a profiler)", + ) + ap.add_argument( + "-s", "--seconds", type=float, default=15.0, help="duration for --loop" + ) + args = ap.parse_args() + + files = args.file or DEFAULT_FILES + lines = load_lines(files, args.repeat) + nbytes = sum(len(s.encode("utf-8")) for s in lines) + Abbreviations.initialize() # Keep the one-time setup out of the timings + + if args.loop: + deadline = time.perf_counter() + args.seconds + runs = 0 + while time.perf_counter() < deadline: + deque(TIMED[args.loop](lines), maxlen=0) + runs += 1 + print(f"{args.loop}: {runs} runs in {args.seconds:.0f} s", file=sys.stderr) + return + + names = args.workload or list(TIMED) + base = json.loads(args.compare.read_text()) if args.compare else {} + results: dict[str, dict[str, object]] = {} + print( + f"Python {sys.version.split()[0]} " + f"input {nbytes / 1e6:.2f} MB, {len(lines)} lines, {args.runs} runs (min)" + ) + for name in names: + times = [time_once(name, lines) for _ in range(args.runs)] + best = min(times) + res: dict[str, object] = { + "best": best, + "median": sorted(times)[len(times) // 2], + } + line = f"{name:<20} {best * 1000:9.1f} ms {nbytes / best / 1e6:6.2f} MB/s" + if not args.no_digest: + dg, n = digest(name, lines) + res.update(digest=dg, records=n) + line += f" {n:7} recs {dg}" + if name in base: + b = base[name] + line += f" {(float(b['best']) / best - 1) * 100:+6.1f}% speed" + if not args.no_digest and "digest" in b: + line += " same" if b["digest"] == res["digest"] else " OUTPUT DIFFERS" + print(line, flush=True) + results[name] = res + + if args.save: + args.save.write_text(json.dumps(results, indent=2)) + + +if __name__ == "__main__": + main() diff --git a/bench/profile.sh b/bench/profile.sh new file mode 100755 index 0000000..34be7ce --- /dev/null +++ b/bench/profile.sh @@ -0,0 +1,61 @@ +#!/usr/bin/env bash +# Profile a bench workload with the CPython 3.15+ sampling profiler +# (python -m profiling.sampling). Output goes to bench/out/ (gitignored). +# +# bench/profile.sh [workload] [seconds] # default: tokenize 15 +# PY=/path/to/python3.15 bench/profile.sh sentences 30 +# +# Produces: +# .pstats.txt top functions/lines by self time +# .self.txt self time aggregated per function +# .collapsed collapsed stacks (input for other tools) +# .flame.html interactive flamegraph +# .heatmap/ line-level heatmap of the source +# +# --blocking is essential here: the tokenizer is a deep chain of generators, +# and without stopping the process for each sample the profiler fails to +# unwind about 70% of stacks ("Error rate" in the pstats header), which +# misattributes the work of inner generators to the next() calls of outer ones. +set -euo pipefail + +HERE="$(cd "$(dirname "$0")" && pwd)" +WORKLOAD="${1:-tokenize}" +SECONDS_="${2:-15}" +OUT="$HERE/out" +mkdir -p "$OUT" + +if [[ -z "${PY:-}" ]]; then + # A throwaway 3.15 venv with Tokenizer installed in editable mode + VENV="$OUT/venv315" + if [[ ! -x "$VENV/bin/python" ]]; then + uv venv -q --python 3.15 "$VENV" + VIRTUAL_ENV="$VENV" uv pip install -q -e "$HERE/.." + fi + PY="$VENV/bin/python" +fi + +run() { + "$PY" -m profiling.sampling run --blocking -r 2khz "$@" \ + "$HERE/bench.py" --loop "$WORKLOAD" -s "$SECONDS_" +} + +run --sort tottime -l 40 > "$OUT/$WORKLOAD.pstats.txt" +grep -m1 "Error rate" "$OUT/$WORKLOAD.pstats.txt" || true +run --collapsed -o "$OUT/$WORKLOAD.collapsed" +run --flamegraph -o "$OUT/$WORKLOAD.flame.html" +run --heatmap -o "$OUT/$WORKLOAD.heatmap" + +# Self time per function, from the leaf frames of the collapsed stacks +"$PY" - "$OUT/$WORKLOAD.collapsed" > "$OUT/$WORKLOAD.self.txt" <<'EOF' +import collections, re, sys +self_n: collections.Counter[str] = collections.Counter() +total = 0 +for line in open(sys.argv[1]): + stack, n = line.rsplit(" ", 1) + total += int(n) + self_n[re.sub(r":\d+$", "", stack.split(";")[-1])] += int(n) +for fn, n in self_n.most_common(30): + print(f"{n / total * 100:5.1f}% {fn}") +EOF +cat "$OUT/$WORKLOAD.self.txt" +echo "Output in $OUT/" diff --git a/src/tokenizer/tokenizer.py b/src/tokenizer/tokenizer.py index 4094ed1..87f018d 100644 --- a/src/tokenizer/tokenizer.py +++ b/src/tokenizer/tokenizer.py @@ -89,6 +89,37 @@ SINGLE_DASH_OR_DOT_DATE = r"(\d{2})[-.](\d{4})(?!\d)".replace("-", HYPHEN + EN_DASH) +# Precompiled regexes for the hot token parsing paths +TIME_HMS_MS_REGEX = re.compile(r"\d{1,2}:\d\d:\d\d,\d\d(?!\d)") +TIME_HMS_REGEX = re.compile(r"\d{1,2}:\d\d:\d\d(?!\d)") +TIME_HM_REGEX = re.compile(r"\d{1,2}:\d\d(?!\d)") +ISO_DATE_REGEX = re.compile(ISO_DATE) +DMY_DATE_REGEX = re.compile(DMY_DATE) +DAY_MONTH_REGEX = re.compile(r"(\d{2})\.(\d{2})(?!\d)") +SINGLE_DASH_OR_DOT_DATE_REGEX = re.compile(SINGLE_DASH_OR_DOT_DATE) +NUMBER_WITH_LETTER_REGEX = re.compile(r"\d+([a-zA-Z])(?!\w)") +NUMBER_WITH_FRACTION_REGEX = re.compile(r"(\d+)([\u00BC-\u00BE\u2150-\u215E])") +IS_REAL_NUMBER_REGEX = re.compile(r"[\+\-]?\d+(\.\d\d\d)*,\d+(?!\d*\.\d)") +COMMA_DIGITS_REGEX = re.compile(r",\d+") +IS_THOUSANDS_INTEGER_REGEX = re.compile(r"[\+\-]?\d+(\.\d\d\d)+(?!\d)") +DAY_SLASH_MONTH_REGEX = re.compile(r"\d{1,2}/\d{1,2}(?!\d)") +FOUR_DIGITS_REGEX = re.compile(r"\d\d\d\d(?!\d)") +SSN_REGEX = re.compile(r"\d{6}\-\d{4}(?!\d)") +TELNO_HYPHEN_REGEX = re.compile(r"\d\d\d\-\d\d\d\d(?!\d)") +SERIAL_NUMBER_REGEX = re.compile(r"\d+\-\d+(\-\d+)+") +SEVEN_DIGITS_REGEX = re.compile(r"\d\d\d\d\d\d\d(?!\d)") +CHAPTER_NUMBER_REGEX = re.compile(r"\d+\.\d+(\.\d+)+") +EN_REAL_NUMBER_REGEX = re.compile(r"[\+\-]?\d+(,\d\d\d)*\.\d+") +EN_INTEGER_REGEX = re.compile(r"[\+\-]?\d+(,\d\d\d)*(?!\d)") +USERNAME_REGEX = re.compile(r"\@[0-9a-zA-Z_]+(\.[0-9a-zA-Z_]+)*") +EMAIL_REGEX = re.compile(r"[^@\s]+@[^@\s]+(\.[^@\s\.,/:;\"\(\)%#!\?”]+)+") +HASHTAG_REGEX = re.compile(r"#\w") +NUMBER_SIGN_REGEX = re.compile(r"#\d+$") +THREE_DIGITS_REGEX = re.compile(r"^\d\d\d$") +FOUR_DIGITS_ONLY_REGEX = re.compile(r"^\d\d\d\d$") +ONE_SENT_PER_LINE_SPLIT_REGEX = re.compile(r"(\n)") +SENTENCE_SPLIT_REGEX = re.compile(r"(\n\s*\n|^\s+$|\]\]\[\[)") + HYPHEN_OG = f"{HYPHEN}og" HYPHEN_EÐA = f"{HYPHEN}eða" EN_DASH_OG = f"{EN_DASH}og" @@ -1091,7 +1122,7 @@ def is_valid_date(y: int, m: int, d: int) -> bool: def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: """Parse a raw token starting with a digit""" w = tok.txt - s: Match[str] | None = re.match(r"\d{1,2}:\d\d:\d\d,\d\d(?!\d)", w) + s: Match[str] | None = TIME_HMS_MS_REGEX.match(w) g: str n: str if s: @@ -1106,7 +1137,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Time(t, h, m, sec), rest - s = re.match(r"\d{1,2}:\d\d:\d\d(?!\d)", w) + s = TIME_HMS_REGEX.match(w) if s: # Looks like a 24-hour clock, H:M:S g = s.group() @@ -1118,7 +1149,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Time(t, h, m, sec), rest - s = re.match(r"\d{1,2}:\d\d(?!\d)", w) + s = TIME_HM_REGEX.match(w) if s: # Looks like a 24-hour clock, H:M g = s.group() @@ -1129,7 +1160,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Time(t, h, m, 0), rest - s = re.match(ISO_DATE, w) + s = ISO_DATE_REGEX.match(w) if s: # Looks like an ISO format date: YYYY-MM-DD or YYYY/MM/DD g = s.group() @@ -1146,7 +1177,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Date(t, y, m, d), rest - s = re.match(DMY_DATE, w) + s = DMY_DATE_REGEX.match(w) if s: # Looks like a date with day, month and year parts g = s.group() @@ -1171,7 +1202,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Date(t, y, m, d), rest - s = re.match(r"(\d{2})\.(\d{2})(?!\d)", w) + s = DAY_MONTH_REGEX.match(w) if s: # A date in the form dd.mm # (Allowing hyphens here would interfere with for instance @@ -1183,7 +1214,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Daterel(t, y=0, m=m, d=d), rest - s = re.match(SINGLE_DASH_OR_DOT_DATE, w) + s = SINGLE_DASH_OR_DOT_DATE_REGEX.match(w) if s: # A date in the form of mm.yyyy or mm-yyyy g = s.group() @@ -1193,9 +1224,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Daterel(t, y=y, m=m, d=0), rest - # Note: the following must use re.UNICODE to make sure that - # \w matches all Icelandic characters under Python 2 - s = re.match(r"\d+([a-zA-Z])(?!\w)", w, re.UNICODE) + s = NUMBER_WITH_LETTER_REGEX.match(w) if s: # Looks like a number with a single trailing character, e.g. 14b, 33C, 1122f g = s.group() @@ -1285,7 +1314,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Measurement(t, unit, value), rest - s = re.match(r"(\d+)([\u00BC-\u00BE\u2150-\u215E])", w, re.UNICODE) + s = NUMBER_WITH_FRACTION_REGEX.match(w) if s: # One or more digits, followed by a unicode vulgar fraction char (e.g. '2½') g = s.group() @@ -1296,31 +1325,31 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: return TOK.Number(t, val), rest # Can't end with digits.digits - s = re.match(r"[\+\-]?\d+(\.\d\d\d)*,\d+(?!\d*\.\d)", w) + s = IS_REAL_NUMBER_REGEX.match(w) if s: # Icelandic-style real number formatted with decimal comma (,) # and possibly thousands separators (.) # (we need to check this before checking integers) g = s.group() - if re.match(r",\d+", w[len(g) :]): + if COMMA_DIGITS_REGEX.match(w[len(g) :]): # English-style thousand separator multiple times s = None else: - n = re.sub(r"\.", "", g) # Eliminate thousands separators - n = re.sub(",", ".", n) # Convert decimal comma to point + n = g.replace(".", "") # Eliminate thousands separators + n = n.replace(",", ".") # Convert decimal comma to point t, rest = tok.split(s.end()) return TOK.Number(t, float(n)), rest - s = re.match(r"[\+\-]?\d+(\.\d\d\d)+(?!\d)", w) + s = IS_THOUSANDS_INTEGER_REGEX.match(w) if s: # Integer with a '.' thousands separator # (we need to check this before checking dd.mm dates) g = s.group() - n = re.sub(r"\.", "", g) # Eliminate thousands separators + n = g.replace(".", "") # Eliminate thousands separators t, rest = tok.split(s.end()) return TOK.Number(t, int(n)), rest - s = re.match(r"\d{1,2}/\d{1,2}(?!\d)", w) + s = DAY_SLASH_MONTH_REGEX.match(w) if s: # Looks like a date (and not something like 10/2007) g = s.group() @@ -1345,7 +1374,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.Daterel(t, y=0, m=m, d=d), rest - s = re.match(r"\d\d\d\d(?!\d)", w) + s = FOUR_DIGITS_REGEX.match(w) if s: nn = int(s.group()) if 1776 <= nn <= 2100: @@ -1353,7 +1382,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(4) return TOK.Year(t, nn), rest - s = re.match(r"\d{6}\-\d{4}(?!\d)", w) + s = SSN_REGEX.match(w) if s: # Looks like a social security number g = s.group() @@ -1361,7 +1390,7 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(11) return TOK.Ssn(t), rest - s = re.match(r"\d\d\d\-\d\d\d\d(?!\d)", w) + s = TELNO_HYPHEN_REGEX.match(w) if s and w[0] in TELNO_PREFIXES: # Looks like a telephone number telno = s.group() @@ -1373,35 +1402,35 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t, rest = tok.split(s.end()) return TOK.SerialNumber(t), rest - s = re.match(r"\d+\-\d+(\-\d+)+", w) + s = SERIAL_NUMBER_REGEX.match(w) if s: # Multi-component serial number t, rest = tok.split(s.end()) return TOK.SerialNumber(t), rest - s = re.match(r"\d\d\d\d\d\d\d(?!\d)", w) + s = SEVEN_DIGITS_REGEX.match(w) if s and w[0] in TELNO_PREFIXES: # Looks like a telephone number telno = w[0:3] + HYPHEN + w[3:7] t, rest = tok.split(7) return TOK.Telno(t, telno), rest - s = re.match(r"\d+\.\d+(\.\d+)+", w) + s = CHAPTER_NUMBER_REGEX.match(w) if s: # Some kind of ordinal chapter number: 2.5.1 etc. # (we need to check this before numbers with decimal points) g = s.group() # !!! TODO: A better solution would be to convert 2.5.1 to (2,5,1) - n = re.sub(r"\.", "", g) # Eliminate dots, 2.5.1 -> 251 + n = g.replace(".", "") # Eliminate dots, 2.5.1 -> 251 t, rest = tok.split(s.end()) return TOK.Ordinal(t, int(n)), rest - s = re.match(r"[\+\-]?\d+(,\d\d\d)*\.\d+", w) + s = EN_REAL_NUMBER_REGEX.match(w) if s: # English-style real number with a decimal point (.), # and possibly commas as thousands separators (,) g = s.group() - n = re.sub(",", "", g) # Eliminate thousands separators + n = g.replace(",", "") # Eliminate thousands separators # !!! TODO: May want to mark this as an error t, rest = tok.split(s.end()) if convert_numbers: @@ -1410,11 +1439,11 @@ def parse_digits(tok: Tok, convert_numbers: bool) -> tuple[Tok, Tok]: t.substitute_all("x", ".") # Change 'x' to '.' return TOK.Number(t, float(n)), rest - s = re.match(r"[\+\-]?\d+(,\d\d\d)*(?!\d)", w) + s = EN_INTEGER_REGEX.match(w) if s: # Integer, possibly with a ',' thousands separator g = s.group() - n = re.sub(",", "", g) # Eliminate thousands separators + n = g.replace(",", "") # Eliminate thousands separators # !!! TODO: May want to mark this as an error t, rest = tok.split(s.end()) if convert_numbers: @@ -1608,13 +1637,13 @@ def generate_raw_tokens( if one_sent_per_line: # We know there's a single sentence per line # Only split on newline - sentence_split_pattern = r"(\n)" + sentence_split_regex = ONE_SENT_PER_LINE_SPLIT_REGEX else: # Split on empty lines, eventually containing whitespace, # but also on paragraph splits within a line - sentence_split_pattern = r"(\n\s*\n|^\s+$|\]\]\[\[)" + sentence_split_regex = SENTENCE_SPLIT_REGEX - splits = re.split(sentence_split_pattern, big_text) + splits = sentence_split_regex.split(big_text) # We know that splits will contain alternatively useful text and the splitting # pattern, starting and ending with useful text. See the documentation on # re.split. @@ -1634,10 +1663,19 @@ def generate_raw_tokens( text = text[:-2] # Postpone the yield until after the raw token loop paragraph_end += 1 + # Zero-width characters and composite glyphs are rare, so we + # check once per text whether the per-token replacements are + # needed at all. Removing a zero-width character can bring a + # composite glyph together, hence the second condition. + has_zerowidth = ZEROWIDTH_REGEX.search(text) is not None + has_composites = replace_composite_glyphs and ( + has_zerowidth or COMPOSITE_REGEX.search(text) is not None + ) for tok in generate_rough_tokens_from_txt(text): - # Always remove zero-width characters - tok = zerowidth_replacement(tok) - if replace_composite_glyphs: + if has_zerowidth: + # Always remove zero-width characters + tok = zerowidth_replacement(tok) + if has_composites: # Replace composite glyphs with single code points tok = composite_replacement(tok) if replace_html_escapes: @@ -1937,7 +1975,7 @@ def parse(self, rt: Tok) -> Iterable[Tok]: # Username on Twitter or other social media platforms # User names may contain alphabetic characters, digits # and embedded periods (but not consecutive ones) - s = re.match(r"\@[0-9a-zA-Z_]+(\.[0-9a-zA-Z_]+)*", rtxt) + s = USERNAME_REGEX.match(rtxt) if s: g = s.group() username, rt = rt.split(s.end()) @@ -1992,7 +2030,7 @@ def parse_mixed( # Check for valid e-mail # Note: we don't allow double quotes (simple or closing ones) in e-mails # here even though they're technically allowed according to the RFCs - s = re.match(r"[^@\s]+@[^@\s]+(\.[^@\s\.,/:;\"\(\)%#!\?”]+)+", rtxt) + s = EMAIL_REGEX.match(rtxt) if s: email, rt = rt.split(s.end()) yield TOK.Email(email) @@ -2020,7 +2058,7 @@ def parse_mixed( yield TOK.Url(url) ate = True - if rtxt and len(rtxt) >= 2 and re.match(r"#\w", rtxt, re.UNICODE): + if rtxt and len(rtxt) >= 2 and HASHTAG_REGEX.match(rtxt): # Handle hashtags. Eat all text up to next punctuation character # so we can handle strings like "#MeToo-hreyfingin" as two words w = rtxt @@ -2030,7 +2068,7 @@ def parse_mixed( tag += w[0] w = w[1:] tag_tok, rt = rt.split(len(tag)) - if re.match(r"#\d+$", tag): + if NUMBER_SIGN_REGEX.match(tag): # Hash is being used as a number sign, e.g. "#12" yield TOK.Ordinal(tag_tok, int(tag[1:])) else: @@ -2458,8 +2496,8 @@ def lookup(abbrev: str) -> list[BIN_Tuple] | None: token.kind == TOK.NUMBER and (next_token.kind == TOK.NUMBER or next_token.kind == TOK.YEAR) and token.txt[0] in TELNO_PREFIXES - and re.search(r"^\d\d\d$", token.txt) - and re.search(r"^\d\d\d\d$", next_token.txt) + and THREE_DIGITS_REGEX.search(token.txt) + and FOUR_DIGITS_ONLY_REGEX.search(next_token.txt) ): telno = token.txt + HYPHEN + next_token.txt token = TOK.Telno(token.concatenate(next_token, separator=" "), telno) From 7252bd44cccb522bdd4f8dfb75415f2ab0d82a8a Mon Sep 17 00:00:00 2001 From: vthorsteinsson Date: Tue, 13 Oct 2026 22:21:01 +0000 Subject: [PATCH 3/3] Regenerate the large test set gold file and enforce it with a test test/toktest_large_gold_acceptable.txt, documented in the README as the current output of the tokenize command, was last regenerated in January 2020: it is byte-identical to the output of Tokenizer 2.0.0. Releases 2.2.0, 3.0.0 and 3.4.0 changed 592 of its lines (and PR #63 one more), and nothing checked it, so the drift went unnoticed. Running each release tag's own CLI shows no output change from 3.4.0 through 3.6.4. - Regenerate the gold file from the current tokenize output. - Add test/test_large_gold.py, which fails when the CLI output for test/toktest_large.txt differs from the gold file and shows the first differing hunks. - Recompute the [input|gold] line ranges in test/Overview.txt: each gold range now covers all output lines containing text from the input lines. That rule reproduces 127 of the 137 original ranges against the old gold file; the rest were boundary inconsistencies and four typos (e.g. 167913, 18187, a reversed input range and a malformed reference). A dated note in the legend says the #B/#C descriptions date from 2.0.0. - README and CLAUDE.md: describe the test and how to regenerate the gold file after an intended tokenization change. Note that the drift is not uniformly an improvement: against toktest_large_gold_perfect.txt, current output gains 244 perfect lines and loses 215 compared with 2.0.0 (e.g. sentence-final abbreviations now keep their period, and a few sentence splits after abbreviations are missed). Co-Authored-By: Claude Opus 5.5 --- CLAUDE.md | 9 +- README.md | 12 +- test/Overview.txt | 266 ++--- test/test_large_gold.py | 44 + test/toktest_large_gold_acceptable.txt | 1240 +++++++++++------------- 5 files changed, 790 insertions(+), 781 deletions(-) create mode 100644 test/test_large_gold.py diff --git a/CLAUDE.md b/CLAUDE.md index 164d144..5d7abc1 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -52,10 +52,15 @@ echo "Texti hér." | tokenize # Pipe from stdin ``` ### Large Test Set Validation +`test/test_large_gold.py` fails if the CLI output for `test/toktest_large.txt` differs +from `test/toktest_large_gold_acceptable.txt` (the current output, enforced). For an +intended tokenization change, regenerate the gold file and review its diff: ```bash -tokenize test/toktest_large.txt test/toktest_large_out.txt -diff test/toktest_large_out.txt test/toktest_large_gold_acceptable.txt +tokenize test/toktest_large.txt test/toktest_large_gold_acceptable.txt +git diff test/toktest_large_gold_acceptable.txt ``` +`test/Overview.txt` cites line ranges `[input|gold]` in the gold file; they shift +when sentence splitting changes. ### Performance Bench ```bash diff --git a/README.md b/README.md index c6d2257..6205f2a 100644 --- a/README.md +++ b/README.md @@ -686,7 +686,8 @@ The lines test sentence detection, token detection and token classification. For analysis, `test/toktest_large_gold_perfect.txt` contains the expected output of a perfect shallow tokenization, and `test/toktest_large_gold_acceptable.txt` contains the current output of the -shallow tokenization. +shallow tokenization. The test suite (`test/test_large_gold.py`) checks that +the output of the `tokenize` command matches it exactly. The file `test/Overview.txt` (only in Icelandic) contains a description of the test set, including line numbers for each part in both @@ -711,6 +712,15 @@ To compare it to the acceptable behaviour: $ diff test/toktest_large_out.txt test/toktest_large_gold_acceptable.txt > diff.txt ``` +When a change in tokenization is intended, regenerate the gold file and review +its diff before committing it. The line ranges in `test/Overview.txt` that refer +to the gold file may then need updating as well: + +```console +$ tokenize test/toktest_large.txt test/toktest_large_gold_acceptable.txt +$ git diff test/toktest_large_gold_acceptable.txt +``` + The file `test/toktest_normal.txt` contains a running text from recent news articles, containing no edge cases. The gold standard for that file can be found in the file `test/toktest_normal_gold_expected.txt`. diff --git a/test/Overview.txt b/test/Overview.txt index 89d4255..56a706a 100644 --- a/test/Overview.txt +++ b/test/Overview.txt @@ -27,356 +27,356 @@ Skammstafanir\setningastaða [SS,TS,TF] [4-89] #A: Hefur ekki áhrif á grunntókun. #B: Sama #C: Sama - Óþekktar/erlendar skammstafanir [SS, TS, TF] [47-55|62-77] + Óþekktar/erlendar skammstafanir [SS, TS, TF] [47-55|62-74] #A: Nær að skipta rétt í setningar þó aftast í setningu. #B: Þekkir algengar erlendar skammstafanir, annað er ekki hægt að tækla. Skiptir rétt í setningar að mestu, ef lágstafur á eftir. Getur ekki ef t.d. á eftir kemur sérnafn. Ef næsta setning byrjar á tölu skiptir hún því ekki upp. #C: Sama - Orð sem lítur út eins og skammstöfun aftast í setningu [SS, TS, TF] [56-57|78-82] + Orð sem lítur út eins og skammstöfun aftast í setningu [SS, TS, TF] [56-57|75-79] #A: Skiptir setningum rétt, annar munur sést ekki í grunntókun. #B: Skiptir að mestu rétt út frá há-/lágstaf. Ef sérnafn kemur á eftir, skiptir setningu. Ef næsta setning hefst á tölu, skiptir ekki upp. #C: Sama - Rangar skammstafanir án punkta [SS, TS, TF] [58-84|83-120] - Var með einum punkti [SS, TS, TF] [58-64|83-91] + Rangar skammstafanir án punkta [SS, TS, TF] [58-84|80-115] + Var með einum punkti [SS, TS, TF] [58-64|80-88] #A: Skiptir setningum rétt þegar aftast í setningu (enda sést munurinn ekki), hefur annars lítil áhrif á grunntókun. #B: Sama. Greinist sem óþekkt nafnorð. #C: Sama og #B - Var með mörgum punktum [SS, TS, TF] [65-84|92-120] + Var með mörgum punktum [SS, TS, TF] [65-84|89-115] #A: Skiptir rétt í setningar þó að sé aftast í setningu. Skiptir ekki upp þegar í miðri setningu. Heldur tókum saman, fyrir utan lokapunkt þegar aftast í setningu. #B: Skiptir að mestu rétt út frá há-/lágstaf. Ef sérnafn kemur á eftir, skiptir setningu. Ef næsta setning hefst á tölu, skiptir ekki upp. Ef öllum punktum er sleppt er þetta sagt óþekkt sérnafn og setningu er alltaf skipt þegar það finnst aftast í setningu. Annars er gert ráð fyrir að þetta sé óþekkt skammstöfun. Jafnvel er hætta á að þetta greinist sem lén (t.om)! TODO skoða hvað hægt að gera hér til að hjálpa málrýni. #C: Sama og #B - Skammstafanir ranglega með punktum; acronyms [SS, TS, TF] [84-88|121-125] + Skammstafanir ranglega með punktum; acronyms [SS, TS, TF] [84-88|115-120] #A: Heldur tókum saman. Skiptir rétt í setningar þó að sé aftast í setningu. Skiptir ekki setningu þegar tóki birtist í henni miðri. #B: Sama, byrjar nýja setningu á næsta orði ef það hefst á hástaf, skiptir ekki ef hefst á lágstaf eða tölu eða öðru. #C: Sama og #B - Skammstafanir með bandstriki (e-a) [TS, TF] [89|126] + Skammstafanir með bandstriki (e-a) [TS, TF] [89|121] #A: Heldur tóka saman. Hefur ekki áhrif á setningaskiptingu. #B: Sama #C: Sama -Mælieiningar\setn.staða\tölur+útskr.tölur [SS, TS, TF] [90-12004|127-15968] - Fyrir framan með bili [SS, TS, TF] [90-1769|127-2366] - Skammstafaðar mælieiningar án punkts [TS, TF] [90-329|127-446] +Mælieiningar\setn.staða\tölur+útskr.tölur [SS, TS, TF] [90-12004|122-15924] + Fyrir framan með bili [SS, TS, TF] [90-1769|122-2361] + Skammstafaðar mælieiningar án punkts [TS, TF] [90-329|122-441] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Sameinar gjaldmiðlatákn tölu á eftir, s.s. tekur bilið. #C: Sama og #B. - Skammstafaðar mælieiningar með punkti [SS, TS, TF] [330-570|447-766] + Skammstafaðar mælieiningar með punkti [SS, TS, TF] [330-570|442-762] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. #C: Sama og #B. - Skammstafaðar mælieiningar ranglega án punkts [TS, TF] [571-809|767-1086] + Skammstafaðar mælieiningar ranglega án punkts [TS, TF] [571-809|763-1081] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. #C: Sama og #B. - Gjaldmiðlaskammstafanir [SS, TS, TF] [810-1049|1087-1406] + Gjaldmiðlaskammstafanir [SS, TS, TF] [810-1049|1082-1401] #A: Heldur tölu og gjaldmiðli eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. #C: Sama og #B. - Gjaldmiðlaskammstafanir ranglega án punkts [TS, TF] [1050-1289|1407-1726] + Gjaldmiðlaskammstafanir ranglega án punkts [TS, TF] [1050-1289|1402-1721] #A: Heldur tölu og gjaldmiðli eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. #C: Sama og #B. - Gjaldmiðlaskammstafanir ranglega með punkti [SS, TS, TF] [1290-1529|1727-2046] + Gjaldmiðlaskammstafanir ranglega með punkti [SS, TS, TF] [1290-1529|1722-2041] #A: Heldur tölu og gjaldmiðli eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. #C: Sama og #B. - Gjaldmiðlatákn [TS, TF] [1530-1769|2047-2366] + Gjaldmiðlatákn [TS, TF] [1530-1769|2042-2361] #A: Heldur tölu og gjaldmiðli eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. #C: Sama og #B. - Fyrir framan án bils [SS, TS, TF] [1770-3289|2367-4446] - Skammstafaðar mælieiningar án punkts [TS, TF] [1770-2009|2367-2686] + Fyrir framan án bils [SS, TS, TF] [1770-3289|2362-4441] + Skammstafaðar mælieiningar án punkts [TS, TF] [1770-2009|2362-2681] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Rífur mælieiningu framan af, ef það er formerki á tölunni er það haft sér (kg + 54). #C: Sama og #B. - Skammstafaðar mælieiningar með punkti [SS, TS, TF] [2010-2249|2687-3006] + Skammstafaðar mælieiningar með punkti [SS, TS, TF] [2010-2249|2682-3001] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Rífur mælieiningu framan af, ef það er formerki á tölunni er það haft sér (klst. + 54). #C: Sama og #B. - Skammstafaðar mælieiningar ranglega án punkts [TS, TF] [2250-2489|3007-3326] + Skammstafaðar mælieiningar ranglega án punkts [TS, TF] [2250-2489|3002-3321] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. #C: Sama og #B. - Gjaldmiðlaskammstafanir [SS, TS, TF] [2490-2729|3327-3646] + Gjaldmiðlaskammstafanir [SS, TS, TF] [2490-2729|3322-3641] #A: Heldur tölu og gjaldmiðli eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Heldur mælieiningunni með tölunni, komið sértilvik fyrir það, nema þegar það er formerki framan á tölu. Þá er allt rifið í sundur (USD + 54) #C: Sama og #B. - Gjaldmiðlaskammstafanir ranglega án punkts [TS, TF] [2730-2809|3647-3806] + Gjaldmiðlaskammstafanir ranglega án punkts [TS, TF] [2730-2809|3642-3801] #A: Heldur tölu og gjaldmiðli eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Rífur gjaldmiðil framan af, ef það er formerki á tölunni er það haft sér (dkr + 54) #C: Sama og #B. - Gjaldmiðlaskammstafanir ranglega með punkti [SS, TS, TF] [2810-3049|3807-4126] + Gjaldmiðlaskammstafanir ranglega með punkti [SS, TS, TF] [2810-3049|3802-4121] #A: Heldur tölu og gjaldmiðli eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Rífur gjaldmiðil framan af, ef það er formerki á tölunni er það haft sér (USD. + 54) #C: Sama og #B. - Gjaldmiðlatákn [TS, TF] [3050-3289|4127-4446] + Gjaldmiðlatákn [TS, TF] [3050-3289|4122-4441] #A: Heldur tölu og gjaldmiðli eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Heldur gjaldmiðlinum með tölunni, komið sértilvik fyrir það, nema þegar það er formerki framan á tölu. Þá er allt rifið í sundur ($ + 54) #C: Sama og #B. - Fyrir aftan með bili [SS, TS, TF] [3290-8644|4447-11489] - Skammstafaðar mælieiningar án punkts [TS, TF] [3290-3568|4447-4818] + Fyrir aftan með bili [SS, TS, TF] [3290-8644|4442-11444] + Skammstafaðar mælieiningar án punkts [TS, TF] [3290-3568|4442-4813] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars sama og #A. #C: Sama og #B. - Skammstafaðar mælieiningar með punkti [SS, TS, TF] [3569-3940|4819-5190] + Skammstafaðar mælieiningar með punkti [SS, TS, TF] [3569-3940|4814-5172] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars sama og #A. #C: Sama og #B. - Skammstafaðar mælieiningar ranglega án punkts [TS, TF] [3941-4219|5191-5562] + Skammstafaðar mælieiningar ranglega án punkts [TS, TF] [3941-4219|5173-5531] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Skammstafaðar mælieiningar ranglega með punkti [SS, TS, TF] [4220-4498|5563-5960] + Skammstafaðar mælieiningar ranglega með punkti [SS, TS, TF] [4220-4498|5532-5929] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Nær ekki að þekkja ranga mælieiningu þegar útskrifuð tala er fyrir framan (tveir dl.), skiptir setningu þar. Annars eins og #A. #C: Sama og #B. - Útskrifaðar mælieiningar [TS, TF] [4499-4777|5961-6332] + Útskrifaðar mælieiningar [TS, TF] [4499-4777|5930-6301] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Mælieiningar með / [ TS, TF] [4778-5056|6333-6704] + Mælieiningar með / [ TS, TF] [4778-5056|6302-6660] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Þekkir ekki sameinaða mælieiningu þegar útskrifuð tala kemur á undan, hefur ekki áhrif á setningaskiptingu en skiptir tóka upp (km / klst.). Annars eins og #A. #C: Sama og #B. - Gjaldmiðlaskammstafanir [SS, TS, TF] [5057-5335|6705-7076] + Gjaldmiðlaskammstafanir [SS, TS, TF] [5057-5335|6661-7032] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Gjaldmiðlaskammstafanir ranglega án punkts [TS, TF] [5336-5614|7077-7448] + Gjaldmiðlaskammstafanir ranglega án punkts [TS, TF] [5336-5614|7033-7404] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Gjaldmiðlaskammstafanir ranglega með punkti [SS, TS, TF] [5615-5893|7449-7820] + Gjaldmiðlaskammstafanir ranglega með punkti [SS, TS, TF] [5615-5893|7405-7776] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. Nota bene, höndlar útskrifaðar tölur. #C: Sama og #B. - Útskrifaðir gjaldmiðlar [TS, TF] [5894-6172|7821-8192] + Útskrifaðir gjaldmiðlar [TS, TF] [5894-6172|7777-8148] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Gjaldmiðlatákn [TS, TF] [6173-6451|8193-8564] + Gjaldmiðlatákn [TS, TF] [6173-6451|8149-8520] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Prósentumerki [TS, TF] [6452-6730|8565-8936] + Prósentumerki [TS, TF] [6452-6730|8521-8892] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Útskrifaðar prósentur [TS, TF] [6731-7009|8937-9308] + Útskrifaðar prósentur [TS, TF] [6731-7009|8893-9264] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Prómill [TS, TF] [7010-7288|9309-9680] + Prómill [TS, TF] [7010-7288|9265-9636] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Útskrifuð prómill [TS, TF] [7289-7567|9681-10052] + Útskrifuð prómill [TS, TF] [7289-7567|9637-10008] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Tommumerki [TS, TF] [7568-7807|10053-10372] + Tommumerki [TS, TF] [7568-7807|10009-10328] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Heldur í sundur í tókaranum, nota bene breytir í lokandi gæsalappir og dregur að orði á seinni stigum, sem er líklega það skásta í stöðunni. Annars eins og #A. #C: Sama og #B. - ² og ³ [TS, TF] [7808-8086|10373-10744] + ² og ³ [TS, TF] [7808-8086|10329-10700] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Annars eins og #A. #C: Sama og #B. - Gráðumerki [TS, TF] [8087-8644|10745-11488] + Gráðumerki [TS, TF] [8087-8644|10701-11444] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Í lok setningar rífur gráðumerkið af C (nær samt að sameina tölu og ° C í einn tóka á seinni stigum). Ef bil er á eftir gráðumerki helst það í sundur, setningaskil eru sett inn á undan hástaf en ekki á undan lágstaf eða tölu. Nota bene þetta er allt sameinað rétt á seinni stigum. #C: Sama og #B. - Fyrir aftan án bils [SS, TS, TF] [8645-12004|11489-15968] - Skammstafaðar mælieiningar án punkts [TS, TF] [8645-8884|11489-11808] + Fyrir aftan án bils [SS, TS, TF] [8645-12004|11445-15924] + Skammstafaðar mælieiningar án punkts [TS, TF] [8645-8884|11445-11764] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur og bil er sett á undan mælieiningu. Þegar bil er á undan broti þekkist talan ekki sem heild og bil er sett á undan mælieiningu. #C: Sama og #B. - Skammstafaðar mælieiningar með punkti [SS, TS, TF] [8885-9124|11809-12128] + Skammstafaðar mælieiningar með punkti [SS, TS, TF] [8885-9124|11765-12084] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur og bil er sett á undan mælieiningu. Þegar bil er á undan broti þekkist talan ekki sem heild og bil er sett á undan mælieiningu. #C: Sama og #B. - Skammstafaðar mælieiningar ranglega án punkts [TS, TF] [9125-9364|12129-12448] + Skammstafaðar mælieiningar ranglega án punkts [TS, TF] [9125-9364|12085-12404] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur og bil er sett á undan mælieiningu. Þegar bil er á undan broti þekkist talan ekki sem heild og bil er sett á undan mælieiningu. #C: Sama og #B. - Skammstafaðar mælieiningar ranglega með punkti [SS, TS, TF] [9365-9604|12449-12768] + Skammstafaðar mælieiningar ranglega með punkti [SS, TS, TF] [9365-9604|12405-12724] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur og bil er sett á undan mælieiningu. Þegar bil er á undan broti þekkist talan ekki sem heild og bil er sett á undan mælieiningu. #C: Sama og #B. - Mælieiningar með / [TS, TF] [9605-9844|12769-13088] + Mælieiningar með / [TS, TF] [9605-9844|12725-13044] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Þegar bil er á undan broti þekkist talan ekki sem heild. Þegar talan þekkist, næst ekki að greina sameinuðu mælieininguna rétt (af því að klesst upp við tölu) og bara "km" er greint með tölu. Þegar talan þekkist ekki er tala og rest rifið í sundur og mælieiningu er haldið saman en frá tölu. #C: Sama og #B. - Gjaldmiðlaskammstafanir [SS, TS, TF] [9845-10084|13089-13408] + Gjaldmiðlaskammstafanir [SS, TS, TF] [9845-10084|13045-13364] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur. Þegar bil er á undan broti þekkist talan ekki sem heild. Setur alltaf bil á undan gjaldmiðli. #C: Sama og #B. - Gjaldmiðlaskammstafanir ranglega með punkti [SS, TS, TF] [10085-10324|13409-13728] + Gjaldmiðlaskammstafanir ranglega með punkti [SS, TS, TF] [10085-10324|13365-13684] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Setur alltaf bil á undan gjaldmiðli. #C: Sama og #B. - Gjaldmiðlatákn [TS, TF] [10325-10564|13729-14048] + Gjaldmiðlatákn [TS, TF] [10325-10564|13685-14004] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼,½ eða 1/3 fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur og bil er sett á undan mælieiningu. Þegar bil er á undan broti þekkist talan ekki sem heild og bil er sett á undan mælieiningu. #C: Sama og #B. - Prósentumerki [TS, TF] [10565-10804|14049-14368] + Prósentumerki [TS, TF] [10565-10804|14005-14324] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼,½ eða 1/3 fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur og bil er sett á undan mælieiningu. Þegar bil er á undan broti þekkist talan ekki sem heild og bil er sett á undan mælieiningu. #C: Sama og #B. - Prómill [TS, TF] [10805-11044|14369-14688] + Prómill [TS, TF] [10805-11044|14325-14644] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼,½ eða 1/3 fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur og bil er sett á undan mælieiningu. Þegar bil er á undan broti þekkist talan ekki sem heild og bil er sett á undan mælieiningu. #C: Sama og #B. - Tommumerki [TS, TF] [11045-11284|14689-15008] + Tommumerki [TS, TF] [11045-11284|14645-14964] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Setur alltaf bil á undan tommumerki. #C: Sama og #B. - ² og ³ [TS, TF] [11285-11524|15009-15328] + ² og ³ [TS, TF] [11285-11524|14965-15284] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼,½ eða 1/3 fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur og bil er sett á undan mælieiningu. Þegar bil er á undan broti þekkist talan ekki sem heild og bil er sett á undan mælieiningu. #C: Sama og #B. - Gráðumerki [TS, TF] [11525-12004|15329-15968] + Gráðumerki [TS, TF] [11525-12004|15285-15924] #A: Heldur tölu og mælieiningu eins og er í grunntókun en sameinar í einn tóka í djúptókun. #B: Þekkir ekki háar tölur með ¼,½ eða 1/3 fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Ekki heldur þegar "1/3" fyrir aftan. Skilur þá í sundur. Þegar bil er á undan broti þekkist talan ekki sem heild. Þegar tala þekkist ekki er sett bil á undan og eftir gráðumerki. Ef þetta gerist í lok setningar, s.s. að mælieiningin þekkist ekki, fer skiptingin eftir því hvort hástafur, lágstafur, tala eða annað kemur á eftir. Ath. á eftir "1/3" er "°C" haldið saman en rifið af tölunni. #C: Sama og #B. -Raðtölur [SS, TS, TF] [12005-12018|15969-15986] +Raðtölur [SS, TS, TF] [12005-12018|15925-15942] #A: Heldur rómverskum tölum saman. Veit hvenær á að skipta setningu fyrir aftan og hvenær ekki. Þekkir blandaðar tölur (4ra, 2svar). #B: Heldur rómverskum tölum saman. Byrjar nýja setningu ef það er hástafur fyrir aftan, ef lágstafur eða tala heldur setningin áfram. Greinir raðtölu aftast í setningu sem tölu. #C:Sama og #B. -Tölur\setn.staða\formerki\þúsundamerki\brot [SS, TS, TF] [12019-12378|15987-16466] +Tölur\setn.staða\formerki\þúsundamerki\brot [SS, TS, TF] [12019-12378|15943-16422] #A: Þekkir tölur á ólíku formi, sameinar í einn tóka í djúptókun en heldur textanum upprunalegum í grunntókun. #B: Þekkir ekki háar tölur með ¼½ fyrir aftan. Ekki heldur lágar þegar formerki (+-) fyrir framan. Skilur þá í sundur. Þekkir annars tölur með formerkjum, erlend þúsunda- og brotamerki o.fl. #C: Sama og #B. -Útskrifaðar tölur\setn.staða [TS, TF] [12379-12420|16467-16508] +Útskrifaðar tölur\setn.staða [TS, TF] [12379-12420|16423-16464] #A: Hefur ekki áhrif á setningaskiptingu. Heldur textanum réttum en sameinar í djúptókun. #B: Margorða útskrifaðar tölur eru réttar í grunntókun en ekki næst að sameina allt í djúptókun. #C: Sama og #B. -Aðrar tölur [SS, TS, TF] [12421-12429|16509-16516] +Aðrar tölur [SS, TS, TF] [12421-12429|16465-16472] #A: Öllum tölum haldið rétt saman. Hefur áhrif á tókaskiptingu, því almenn brot t.d. líta oft út eins og dagsetningar. #B: Þekkir ekki 9,- svo rífur greinarmerkin af og í sundur. Tekur almenn brot í sundur nema þegar eru eins og dagsetningar. #C: Sama og #B. -Greinarmerki [SS, TS, TF] [12430-12529|16517-16636] - Ólíkar samsetningar greinarmerkja [] [12430-12439|16517-16533] +Greinarmerki [SS, TS, TF] [12430-12529|16473-16590] + Ólíkar samsetningar greinarmerkja [] [12430-12439|16473-16487] #A: Greinarmerkjum er haldið saman. #B: Mörg greinarmerki í röð eru sameinuð, staðlaða gildið er gildi fyrsta. Bara gert þegar þau ljúka setningu saman; t.d. ?!? og margir punktar í röð. Skiptir setningu ranglega þegar !", eða ?", eða bara !" og ?" í lok beinnar ræðu. Nær því réttu ef bara ," í lok beinnar ræðu. #C: Sama og #B. - Þrípunktur og margir punktar [SS, TS, TF] [12440-12464|16534-16565] + Þrípunktur og margir punktar [SS, TS, TF] [12440-12464|16488-16519] #A: Mörgum punktum er haldið saman. Skipt er rétt í setningar í kringum þá. #B: Þekkir úrfellingarmerki og heldur setningu áfram ef við á. Ath. hefur úrfellingarmerkið í lok fyrri setningar ef á eftir kemur ný setning. Sameinar marga punkta, staðlaða gildið í djúptókuninni er þrípunktur. Byrjar nýja setningu á eftir ef á eftir kemur hástafur, heldur áfram í sömu setningu ef á eftir kemur lágstafur eða tala. Sameinar ekki marga punkta eða þrípunkt og svo spurningarmerki í einn tóka. Þekkir ekki úrfellingarmerki í lok orðs til að tákna styttingu. #C: Sama og #B. - Gæsalappir [TS, TF] [12465-12529|16566-16636] + Gæsalappir [TS, TF] [12465-12529|16520-16590] #A: Gæsalappir þekkjast rétt en þeim er ekki breytt sjálfkrafa. #B: Tekur gæsalappir frá orðum. Íslenskar, einfaldar gæsalappir leyfast ekki sem úrfellingarmerki á erlendum orðum en erlent úrfellingarmerki leyfist. Þekkir erlendar gæsalappir, heldur þeim eins og eru en í djúptókun fá þær staðlað gildi sem er samsvarandi íslenskar gæsalappir. Ef setning endar á beinni ræðu innan einfaldra gæsalappa og á eftir kemur ný setning er aftari gæsalöppunum haldið með síðustu setningunni. #C: Sama og #B. Erlendar 11279-11283 Úrfellingarkomma 11284-11284 Ólíkar samsetningar kringum orð 11285-11342 -Lagagreinar [TS, TF] [12530-12532|16637-16640] +Lagagreinar [TS, TF] [12530-12532|16591-16594] #A: Lagagreinar þekkjast, jafnvel er hægt að tengja þær við réttan lagatexta á vefnum. #B: Lagagreinar þekkjast ekki, þeim er skipt upp á skástriki (50 / 2000). #C: Sama og #B. -Símanúmer\setn.staða\skiptimerki [SS, TS, TF] [12533-12592|16641-16698] +Símanúmer\setn.staða\skiptimerki [SS, TS, TF] [12533-12592|16595-16652] #A: Leyfileg símanúmer þekkjast, þeim er ekki skipt upp. #B: Símanúmer sem hefjast á leyfilegum strengjum þekkjast, annað er kallað vörunúmer (SerialNumber). Skiptimerki er ekki staðlað í grunntókun. Íslenskur landskóði þekkist með 00 eða plúsmerki fyrir framan, það þarf að bæta við það safn. Skiptimerki þar getur verið bil eða bandstrik. Ef það er ekkert þekkist símanúmerið ekki, það telst tala og ef næsta setning hefst á tölu skiptist setning ekki þar. Það mætti bæta við stuðningi við 112, en líklega er það of margrætt. #C: Sama og #B. - Bandstrik á milli [] [12533-12550|16641-16658] - Enginn landskóði [12533-12538|16641-16646] - 00landskóði [12539-12544|16647-16652] - +landskóði [12544-12550|16653-16658] - Bil [] [12551-12568|16659-16676] - Enginn landskóði [12551-12556|16659-16664] - 00landskóði [12557-12562|16665-16670] - +landskóði [12563-12568|16671-16676] - Ekkert bil [] [12569-12586|16677-16698] - Enginn landskóði [12569-12574|16677-16682] - 00landskóði [12575-12580|16683-16687] - +landskóði [12581-12586|166|166867-16692] - Ógilt [] [12586-12592|16693-16698] -Kennitala [TS, TF] [12593-12604|16699-16714] + Bandstrik á milli [] [12533-12550|16595-16612] + Enginn landskóði [12533-12538|16595-16600] + 00landskóði [12539-12544|16601-16606] + +landskóði [12544-12550|16606-16612] + Bil [] [12551-12568|16613-16630] + Enginn landskóði [12551-12556|16613-16618] + 00landskóði [12557-12562|16619-16624] + +landskóði [12563-12568|16625-16630] + Ekkert bil [] [12569-12586|16631-16646] + Enginn landskóði [12569-12574|16631-16636] + 00landskóði [12575-12580|16637-16641] + +landskóði [12581-12586|16641-16646] + Ógilt [] [12586-12592|16646-16652] +Kennitala [TS, TF] [12593-12604|16653-16668] #A: Leyfilegar kennitölur þekkjast og þeim er haldið saman. #B: Kennitölur sem uppfylla skilyrði þekkjast, bæði manneskju og fyrirtækis. Aðrar eru teknar í sundur á bandstriki. #C: Sama og #B. Manneskju Fyrirtækis Ógild -Bandstrik [SS, TF] [12605-12617|16715-16727] +Bandstrik [SS, TF] [12605-12617|16669-16681] #A: Rétt er skipt í setningar í kringum ólík bandstrik. #B: Þeim er haldið í grunntókun eins og eru en eru stöðluð í djúptókun. Ekki næst að greina nýja setningu á eftir þeim þegar við á. #C: Sama og #B. -Samsett orð [TS, TF] [12618-12657|16728-16767] +Samsett orð [TS, TF] [12618-12657|16682-16721] #A: Samsetningum er haldið saman. #B: Samsetningum með bandstriki er haldið saman, nema þegar fyrri hlutinn er skammstöfun (Ph.D.-gráða verður Ph.D. - gráða). Bandstriki er haldið aftan á styttum fyrri hlutum. Þegar margir fyrri hlutar finnast og komma kemur á milli þeirra er henni haldið með fyrri hlutanum. Munurinn sést ekki í grunntókun en ekki tekst að sameina "þingkonur og -menn". Bandstrikinu er haldið aftan á styttum seinni hlutum. Skammstafanir eða samsetningar með skástriki þekkjast ekki og eru slitnar í sundur á skástriki. Samsetningar með "-/" þekkjast ekki, orðið er slitið í sundur á báðum greinarmerkjum. Munurinn sést ekki í grunntókun en ekki tekst að sameina samsetningar með margorða fyrri hluta í einn tóka. #C: Sama og #B. - Bandstrik eða skástrik [12618-12647|16728-16757] - Erlent sérnafn fremst [12618-12620|16728-16730] - Margorða (erlent) sérnafn fremst [12621|16731] - Sérnafn fremst [12622|16732] - Viðurnefni eða átt framan á sérnafni [12623-12630|16733-16740] - Skammstöfun fremst [12631-12633|16741-16743] - Einn fyrri hluti [12644-12635|16744-16745] - Tveir fyrri hlutar [12636-12637|16746-16747] - Þrír fyrri hlutar [12638-12639|16748-16749] - Fjórir fyrri hlutar [12640-12641|16750-16751] - Einn seinni hluti [12642-12643|16752-16753] - -/ samsetning [12644|16754] - / samsetning [12645-12647|16755-16757] - Ekkert bandstrik [12648-12657|16758-16767] - Erlent sérnafn fremst [12648-12650|16758-16760] - Margorða sérnafn fremst [12651-12652|16761-16762] - Sérnafn fremst [12653-12654|16763-16764] - Einn fyrri hluti [12655|16765] - Margir fyrri hlutar [12656-12657|16766-16767] -Nöfn [TS, TF] [12658-12664|16768-16774] + Bandstrik eða skástrik [12618-12647|16682-16711] + Erlent sérnafn fremst [12618-12620|16682-16684] + Margorða (erlent) sérnafn fremst [12621|16685] + Sérnafn fremst [12622|16686] + Viðurnefni eða átt framan á sérnafni [12623-12630|16687-16694] + Skammstöfun fremst [12631-12633|16695-16697] + Einn fyrri hluti [12634-12635|16698-16699] + Tveir fyrri hlutar [12636-12637|16700-16701] + Þrír fyrri hlutar [12638-12639|16702-16703] + Fjórir fyrri hlutar [12640-12641|16704-16705] + Einn seinni hluti [12642-12643|16706-16707] + -/ samsetning [12644|16708] + / samsetning [12645-12647|16709-16711] + Ekkert bandstrik [12648-12657|16712-16721] + Erlent sérnafn fremst [12648-12650|16712-16714] + Margorða sérnafn fremst [12651-12652|16715-16716] + Sérnafn fremst [12653-12654|16717-16718] + Einn fyrri hluti [12655|16719] + Margir fyrri hlutar [12656-12657|16720-16721] +Nöfn [TS, TF] [12658-12664|16722-16728] #A: Hefur ekki áhrif á setningaskiptingu eða tókaskiptingu í grunntókun. Nöfn eru sameinuð rétt í tóka í djúptókun. #B: Sama í grunntókun. Mætti þekkja fleiri mynstur í djúptókun, og koma í veg fyrir of mikla græðgi í sameiningu. #C: Sama og #B. -Tími [SS, TS, TF] [12665-12991|16775-17109] +Tími [SS, TS, TF] [12665-12991|16729-17057] #A: Allar tegundir tímaliða þekkjast og eru sameinaðar í einn tóka. #B: Margt mætti sameina betur í djúptókun. Það sem hefur áhrif á grunntókun er hér talið upp. MM:SS þekkist ekki og er slitið í sundur á tvípunkti. GMT+4 þekkist ekki og er slitið í sundur á plúsmerki. Sekúndubrot þekkjast en upplýsingar um þau eru ekki komin inn í tókagildið. D.MM, D.MM., D.M og D.M. þekkist ekki þar sem það er svo margrætt, seinna dæmið hefur áhrif á setningaskiptingu. D-MM, DD-MM, D-M og DD-M þekkist ekki þar sem það er of margrætt, er slitið í sundur á bandstriki. 'YY þekkist ekki, er slitið í sundur. MM-YY þekkist ekki því of margrætt, slitið í sundur á bandstriki. YYYY.M.DD þekkist ekki, setningu skipt á undan M.DD. YYYY/M/DD og YYYY-M-DD þekkist ekki, slitið í sundur á fyrra skástriki og báðum bandstrikum. YYYY-YYYY þekkist ekki, slitið í sundur á bandstriki. 'mars-apríl' þekkist sem samsetning, þarf sértilfelli til að greina rétt sem tímabil. 'nóv.-des.' er skipt upp á bandstriki. Erlendu skammstafanirnar BC, AD, AM, PM, am og pm eru slitnar aftan af. #C: Sama og #B. - Tímabil [12665-12677|16775-16787] - Tímasetning [12678-12802|16788-16912] - Dagsetning [12803-12964|167913-17082] - Annað [12965-12991|17083-17109] -Netföng [SS, TS, TF] [12992-12996|17110-17119] + Tímabil [12665-12677|16729-16741] + Tímasetning [12678-12802|16742-16866] + Dagsetning [12803-12964|16867-17030] + Annað [12965-12991|17031-17057] +Netföng [SS, TS, TF] [12992-12996|17058-17067] #A: Gild netföng greinast rétt með öllum leyfilegum táknum. #B: Greinast rétt, jafnvel í lok setningar. #C: Sama og #B. -Vefsíður [SS, TS, TF] [12997-13009|17120-17133] +Vefsíður [SS, TS, TF] [12997-13009|17068-17081] #A: Gildar vefsíður greinast rétt með öllum leyfilegum táknum. #B: Greinast rétt, eina sem veldur vandræðum er þegar spurningarmerki og samasemmerki koma fyrir. Þyrfti að bera kennsl á "www" og leyfa flest þar á eftir. #C: Sama og #B. -Efnasambönd [TS, TF] [13010-13019|17134-17143] +Efnasambönd [TS, TF] [13010-13019|17082-17091] #A: Ólíkar gerðir efnasambanda þekkjast. #B: Þekkjast. #C: Sama og #B. -Twitter-notendanöfn [TS, TF] [13020-13022|17144-17147] +Twitter-notendanöfn [TS, TF] [13020-13022|17092-17095] #A: Gild notendanöfn með öllum leyfilegum táknum greinast rétt. #B: Þekkjast. Það mætti prófa betur öll tákn sem mega koma fyrir. #C: Sama og #B. -Myllumerki [TS, TF] [13023-13024|17148-17151] +Myllumerki [TS, TF] [13023-13024|17096-17099] #A: Leyfileg myllumerki með öllum leyfilegum táknum þekkjast. Samsetningar með kassmerki fremst leyfast og er haldið saman. #B: Greinast. Ath. samsetningar með kassmerki fremst þekkjast ekki, eru slitnar í sundur á bandstriki; hægt að bera kennsl á síðar í greiningu. #C: Sama og #B. -Aðrir flóknir tókar [SS, TS, TF] [13025-13075|17152-17198] +Aðrir flóknir tókar [SS, TS, TF] [13025-13075|17100-17144] #A: Ólíkir tókar þekkjast. #B: Skák þekkist ekki, tölur eru slitnar aftan af. Stærðfræðidæmi eru slitin í sundur á flestum táknum nema skástrikum þegar þetta gæti verið dagsetning. Setningaskiptingin er líka röng á eftir tölu því næsta setning hefst á tölu eða öðru en hástaf, talan og punkturinn greinast því sem raðtala. Hnit eru slitin í sundur á kló og gráðumerki. Nótur með myllumerki t.d. þekkjast ekki. Möppuslóðir þekkjast ekki, er skipt upp á skástriki. Ýmis vörunúmer þekkjast ekki, almennt skipt upp á tölum og greinarmerkjum, hefur áhrif á setningaskiptingu. Pin-númer þekkjast ekki en hefur ekki áhrif á grunntókun. Sama gildir um CVC-númer. Kreditkortanúmer þekkjast ekki en hafa ekki áhrif á grunntókun. Flugnúmer þekkjast ekki. Flýtiskipanir þekkjast ekki, er skipt upp á plúsmerki. Þáttaraðastyttingar þekkjast ekki. Tákn eins og & eða * innan orða þekkjast ekki og skipta orðum. Tilvísanir innan sviga þekkjast ekki en hafa ekki áhrif á grunntókun. Tjákn þekkjast ekki og hafa áhrif á setningaskiptingu ef þau koma aftast í línu. HTML þekkist ekki. Önnur stafróf þekkjast ekki, stöfum er jafnvel skipt upp. Lausnarrunur þekkjast ekki, skipt er á skástriki og tölum. Hlutföll með tvípunkti þekkjast ekki, stjörnugjöf með skástriki eða stjörnum þekkjast ekki, skipt er á greinarmerkjum. #C: Sama og #B. - Skák [13025|17152-17153] - Stærðfræði [13026-13033|17154-17157] - Staðsetning [13034-13045|17158-17169] - Nótur [13046|17170] - Möppuslóð [13047|17171] - Vörunúmer [13048-13052|17172-17177] - Fjármálanúmer [13053-13056|17178-17181] - Flugnúmer [13057-13058|17182-17183] - Flýtiskipanir [13059|17184] - Þáttaraðir [13060|17185] - Önnur tákn innan orða [13061-13062|17186-18187] - Tilvísanir [13063-13064|17188-17190] - Tjákn [13065-13066|17191] - HTML [13067-13068|17191-17192] - Önnur stafróf [13069|17192] - Lausnarrunur [13070|17193] - Annað [13071-13075|17194-17198] + Skák [13025|17100-17101] + Stærðfræði [13026-13033|17102-17104] + Staðsetning [13034-13045|17105-17116] + Nótur [13046|17117] + Möppuslóð [13047|17118] + Vörunúmer [13048-13052|17119-17123] + Fjármálanúmer [13053-13056|17124-17127] + Flugnúmer [13057-13058|17128-17129] + Flýtiskipanir [13059|17130] + Þáttaraðir [13060|17131] + Önnur tákn innan orða [13061-13062|17132-17133] + Tilvísanir [13063-13064|17134-17136] + Tjákn [13065-13066|17137] + HTML [13067-13068|17137-17138] + Önnur stafróf [13069|17138] + Lausnarrunur [13070|17139] + Annað [13071-13075|17140-17144] =========================================== Setningastaða = framstaða|innstaða|bakstaða @@ -387,6 +387,10 @@ Setningastaða = framstaða|innstaða|bakstaða [X-X|Y-Y] X = Línutal í toktest_large.txt Y = Línutal í toktest_large_gold_acceptable.txt + Y var endurreiknað 2026-10-13 þegar toktest_large_gold_acceptable.txt var + endurgerð úr úttaki tokenize-skipunarinnar: Y nær yfir allar línur í + úttakinu sem innihalda texta úr línum X. Lýsingar #B og #C eru frá + 2019-2020 (útgáfa 2.0.0) og hafa ekki verið uppfærðar. Línutal í toktest_large_gold_perfect.txt er nánast það sama og í toktest_large_gold_acceptable.txt. #A: Hegðun tókara í fullkomnum heimi, skilgreind í toktest_large_gold_perfect.txt #B: Ásættanleg hegðun tilreiðara, skilgreind í toktest_large_gold_acceptable.txt diff --git a/test/test_large_gold.py b/test/test_large_gold.py new file mode 100644 index 0000000..0b0a80d --- /dev/null +++ b/test/test_large_gold.py @@ -0,0 +1,44 @@ +""" +Regression test for the large test set. +Copyright (C) 2026 Miðeind ehf. + +The shallow tokenization of test/toktest_large.txt by the tokenize command +must match test/toktest_large_gold_acceptable.txt exactly. When a change +in tokenization is intended, regenerate the gold file and review its diff: + + tokenize test/toktest_large.txt test/toktest_large_gold_acceptable.txt + +test/Overview.txt refers to line numbers in the gold file; see the note +at its end on how those line ranges were computed. +""" + +import difflib +from pathlib import Path +import sys +from unittest.mock import patch + +from pytest import CaptureFixture + +from tokenizer.main import main + +TEST_DIR = Path(__file__).parent +INPUT = TEST_DIR / "toktest_large.txt" +GOLD = TEST_DIR / "toktest_large_gold_acceptable.txt" + + +def test_large_gold(capsys: CaptureFixture[str]) -> None: + # Explicit "-" so that argparse resolves sys.stdout at call time, + # after capsys has replaced it + with patch.object(sys, "argv", ["tokenize", str(INPUT), "-"]): + main() + output = capsys.readouterr().out.splitlines() + gold = GOLD.read_text(encoding="utf-8").splitlines() + if output != gold: + diff = list( + difflib.unified_diff(gold, output, "gold", "output", n=1, lineterm="") + ) + changed = sum(1 for d in diff if d.startswith("-") and d != "--- gold") + raise AssertionError( + f"Output differs from {GOLD.name} on {changed} lines; first hunks:\n" + + "\n".join(diff[:40]) + ) diff --git a/test/toktest_large_gold_acceptable.txt b/test/toktest_large_gold_acceptable.txt index e1709ec..a4025b4 100644 --- a/test/toktest_large_gold_acceptable.txt +++ b/test/toktest_large_gold_acceptable.txt @@ -16,14 +16,14 @@ Ath. að taka öll útiföt með heim . Haraldur Beinteinsson próf. á átján ketti . Það gæti t.d. verið lögg. bókari . Áður fyrr kom fólk nk. sunnudag en ekki sl. viku . -Hún spurði hæstv. fmrh. hvort til stæði að breyta barnal . +Hún spurði hæstv. fmrh. hvort til stæði að breyta barnal. Sá þverneitaði . Hann var alg. alm. erl. fyrrn. núv. sk. sn. maður . Ég vil 5 stk. af smjöri . Hér er hr. Friðrik Maríusson að gera óskunda . -Hann vann hjá Mýrinni ehf . +Hann vann hjá Mýrinni ehf. Starfsmannaveltan þar var gífurlega há . -Áætluð koma er mánudaginn nk . +Áætluð koma er mánudaginn nk. Mundu að pakka vegabréfinu . T.a.m. fundust bækur í holunni . H.u.b. allir meðlimir samtakanna voru handteknir . @@ -33,15 +33,15 @@ Vatnið sauð þ.a. hann slökkti undir pottinum . Hún á t.d. a.m.k. 3 hesta . Ég las fréttina um IBM t.d. á Mbl . Eftir það var ekki aftur snúið . -Skoðum þetta t.a.m . +Skoðum þetta t.a.m. Þetta gæti farið illa . -Skoðum þetta o.s.frv . +Skoðum þetta o.s.frv. Þetta gæti farið illa . -Hún á sveppi , gúrkur o.s.frv . +Hún á sveppi , gúrkur o.s.frv. Friðrik Maríusson gerir oft óskunda . Þ. á m. safnaði hann skartgripum . Hann átti margar bækur , þ. á m. rauðar . -Á torgið safnaðist mikill fjöldi manns , nasistar þ. á m . +Á torgið safnaðist mikill fjöldi manns , nasistar þ. á m. Lögreglan reyndi að hafa hemil á mannfjöldanum . Rómv. gengu af göflunum eftir tapið í leiknum . Alþ. tekur sér frí . @@ -49,31 +49,28 @@ B.A. er nóg til að sækja um starfið . Óskað var eftir að Spánv. kláruðu umsóknina . Gaman er að því að Alþ. er grænt . Þú þarft B.A. til að sækja um starfið . -Óskað var eftir Pólv . +Óskað var eftir Pólv. Því var gengið frá málinu . -Gengið var að Alþ . +Gengið var að Alþ. Farið var frá hólnum . -Hér dugar að hafa B.A . -Best væri þó að hafa Ph.D . +Hér dugar að hafa B.A. +Best væri þó að hafa Ph.D. MS er góð . MS er góður . -Þar var á ferðinni þreyttur markaðsfr . -Þar var á ferðinni mögnuð markaðsfr . -Hann er einnig kallaður dr. A.P.J . -Maríusson . -Hér er dót í C . +Þar var á ferðinni þreyttur markaðsfr. +Þar var á ferðinni mögnuð markaðsfr. +Hann er einnig kallaður dr. A.P.J. Maríusson . +Hér er dót í C. American Continental búðinni . -C.S . -Lewis er vinur J.K . -Rowling . +C.S. Lewis er vinur J.K. Rowling . Hún var kölluð P.A. 900 milljarðar spöruðust við það . Hún var kölluð M.V.P. 900 vina sinna . Fyrirtækið heitir Industrial Holdings ltd . Það sér um tollamál . Farið var í klefa , kompur etc. til að finna gripinn . -Gengið var upp á Everest , Kilimanjaro etc . +Gengið var upp á Everest , Kilimanjaro etc. Þreytan var yfirþyrmandi . -Árið var 22 B.C . +Árið var 22 B.C. Ekkert gerðist þar til árið 2999 A.D. þegar allt gerðist . Ég fékk mér lögg . Gunna fékk sér hins vegar mikið . @@ -85,9 +82,9 @@ Danm grefur holur . Hann kemur nk sunnudag . Ég vil 5 stk af smjöri . Þetta kemur fram á bls fjörutíu . -Hún skrifar undir duln . +Hún skrifar undir duln. Þannig losnar hún við óða aðdáendur . -Hann var gerður að deildarstj . +Hann var gerður að deildarstj. Gallinn er að hann falsaði ferilskrána . Þetta er td röng skammstöfun . Pistillinn birtist eh . @@ -105,23 +102,21 @@ Skilafresturinn gildir to.m. febrúar . Skilafresturinn gildir t.om . febrúar . Skilafresturinn gildir t.o.m. febrúar . -Þetta eru 9 metrar amk . +Þetta eru 9 metrar amk. Bara að það væru 7 . Þetta eru 9 metrar a.mk . Bara að það væru 7 . -Þetta eru 9 metrar am.k . +Þetta eru 9 metrar am.k. Bara að það væru 7 . +Þetta eru 9 metrar a.m.k. Bara að það væru 7 . -Þetta eru 9 metrar a.m.k . -Bara að það væru 7 . -Þetta eru 8 metrar uþb . -100 hefðu verið betri . +Þetta eru 8 metrar uþb. 100 hefðu verið betri . Þetta eru 8 metrar u.þb. 100 hefðu verið betri . Þetta eru 8 metrar uþ.b. 100 hefðu verið betri . Þetta eru 8 metrar u.þ.b. 100 hefðu verið betri . N.A.S.A. er stofnun . Hér er minnst á B.B.C. til að skerpa á umræðunni . Gengið var að H.Í. í hádeginu . -Gengið var að H.Í . +Gengið var að H.Í. Þar hvíldist göngufólk . Hér eru e-r um e-ja frá e-m til e-rra . Kg 54 er há tala . @@ -5162,32 +5157,19 @@ Loks höfum við +23,985,554 ¼ klst . Eins gott að það gangi vel . Loks höfum við +23,985,554 1/3 klst . Eins gott að það gangi vel . -Loks höfum við tveir klst . -Eins gott að það gangi vel . -Loks höfum við þrjátíu klst . -Eins gott að það gangi vel . -Loks höfum við áttatíu og átta klst . -Eins gott að það gangi vel . -Loks höfum við hundrað og einn klst . -Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu klst . -Eins gott að það gangi vel . -Loks höfum við tólf hundruð milljónir klst . -Eins gott að það gangi vel . -Loks höfum við átján milljarðar klst . -Eins gott að það gangi vel . -Loks höfum við tveir ma. klst . -Eins gott að það gangi vel . -Loks höfum við þrjátíu þús. klst . -Eins gott að það gangi vel . -Loks höfum við áttatíu og átta mrð. klst . -Eins gott að það gangi vel . -Loks höfum við hundrað og einn mrð. klst . -Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu ma. klst . -Eins gott að það gangi vel . -Loks höfum við átta þúsund og ellefu þús. klst . -Eins gott að það gangi vel . +Loks höfum við tveir klst. Eins gott að það gangi vel . +Loks höfum við þrjátíu klst. Eins gott að það gangi vel . +Loks höfum við áttatíu og átta klst. Eins gott að það gangi vel . +Loks höfum við hundrað og einn klst. Eins gott að það gangi vel . +Loks höfum við tvö hundruð og fjörutíu klst. Eins gott að það gangi vel . +Loks höfum við tólf hundruð milljónir klst. Eins gott að það gangi vel . +Loks höfum við átján milljarðar klst. Eins gott að það gangi vel . +Loks höfum við tveir ma. klst. Eins gott að það gangi vel . +Loks höfum við þrjátíu þús. klst. Eins gott að það gangi vel . +Loks höfum við áttatíu og átta mrð. klst. Eins gott að það gangi vel . +Loks höfum við hundrað og einn mrð. klst. Eins gott að það gangi vel . +Loks höfum við tvö hundruð og fjörutíu ma. klst. Eins gott að það gangi vel . +Loks höfum við átta þúsund og ellefu þús. klst. Eins gott að það gangi vel . 54 klst er há tala . 54,664 klst er há tala . 54.664 klst er há tala . @@ -5534,32 +5516,19 @@ Loks höfum við +23,985,554 ¼ klst . Eins gott að það gangi vel . Loks höfum við +23,985,554 1/3 klst . Eins gott að það gangi vel . -Loks höfum við tveir klst . -Eins gott að það gangi vel . -Loks höfum við þrjátíu klst . -Eins gott að það gangi vel . -Loks höfum við áttatíu og átta klst . -Eins gott að það gangi vel . -Loks höfum við hundrað og einn klst . -Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu klst . -Eins gott að það gangi vel . -Loks höfum við tólf hundruð milljónir klst . -Eins gott að það gangi vel . -Loks höfum við átján milljarðar klst . -Eins gott að það gangi vel . -Loks höfum við tveir ma. klst . -Eins gott að það gangi vel . -Loks höfum við þrjátíu þús. klst . -Eins gott að það gangi vel . -Loks höfum við áttatíu og átta mrð. klst . -Eins gott að það gangi vel . -Loks höfum við hundrað og einn mrð. klst . -Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu ma. klst . -Eins gott að það gangi vel . -Loks höfum við átta þúsund og ellefu þús. klst . -Eins gott að það gangi vel . +Loks höfum við tveir klst. Eins gott að það gangi vel . +Loks höfum við þrjátíu klst. Eins gott að það gangi vel . +Loks höfum við áttatíu og átta klst. Eins gott að það gangi vel . +Loks höfum við hundrað og einn klst. Eins gott að það gangi vel . +Loks höfum við tvö hundruð og fjörutíu klst. Eins gott að það gangi vel . +Loks höfum við tólf hundruð milljónir klst. Eins gott að það gangi vel . +Loks höfum við átján milljarðar klst. Eins gott að það gangi vel . +Loks höfum við tveir ma. klst. Eins gott að það gangi vel . +Loks höfum við þrjátíu þús. klst. Eins gott að það gangi vel . +Loks höfum við áttatíu og átta mrð. klst. Eins gott að það gangi vel . +Loks höfum við hundrað og einn mrð. klst. Eins gott að það gangi vel . +Loks höfum við tvö hundruð og fjörutíu ma. klst. Eins gott að það gangi vel . +Loks höfum við átta þúsund og ellefu þús. klst. Eins gott að það gangi vel . 54 dl. er há tala . 54,664 dl. er há tala . 54.664 dl. er há tala . @@ -6676,32 +6645,19 @@ Loks höfum við +23,985,554 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við +23,985,554 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við tveir km / klst . -Eins gott að það gangi vel . -Loks höfum við þrjátíu km / klst . -Eins gott að það gangi vel . -Loks höfum við áttatíu og átta km / klst . -Eins gott að það gangi vel . -Loks höfum við hundrað og einn km / klst . -Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu km / klst . -Eins gott að það gangi vel . -Loks höfum við tólf hundruð milljónir km / klst . -Eins gott að það gangi vel . -Loks höfum við átján milljarðar km / klst . -Eins gott að það gangi vel . -Loks höfum við tveir ma. km / klst . -Eins gott að það gangi vel . -Loks höfum við þrjátíu þús. km / klst . -Eins gott að það gangi vel . -Loks höfum við áttatíu og átta mrð. km / klst . -Eins gott að það gangi vel . -Loks höfum við hundrað og einn mrð. km / klst . -Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu ma. km / klst . -Eins gott að það gangi vel . -Loks höfum við átta þúsund og ellefu þús. km / klst . -Eins gott að það gangi vel . +Loks höfum við tveir km / klst. Eins gott að það gangi vel . +Loks höfum við þrjátíu km / klst. Eins gott að það gangi vel . +Loks höfum við áttatíu og átta km / klst. Eins gott að það gangi vel . +Loks höfum við hundrað og einn km / klst. Eins gott að það gangi vel . +Loks höfum við tvö hundruð og fjörutíu km / klst. Eins gott að það gangi vel . +Loks höfum við tólf hundruð milljónir km / klst. Eins gott að það gangi vel . +Loks höfum við átján milljarðar km / klst. Eins gott að það gangi vel . +Loks höfum við tveir ma. km / klst. Eins gott að það gangi vel . +Loks höfum við þrjátíu þús. km / klst. Eins gott að það gangi vel . +Loks höfum við áttatíu og átta mrð. km / klst. Eins gott að það gangi vel . +Loks höfum við hundrað og einn mrð. km / klst. Eins gott að það gangi vel . +Loks höfum við tvö hundruð og fjörutíu ma. km / klst. Eins gott að það gangi vel . +Loks höfum við átta þúsund og ellefu þús. km / klst. Eins gott að það gangi vel . 54 USD er há tala . 54,664 USD er há tala . 54.664 USD er há tala . @@ -8748,165 +8704,165 @@ Hér eru áttatíu og átta mrð. % á ferðinni . Hér eru hundrað og einn mrð. % á ferðinni . Hér eru tvö hundruð og fjörutíu ma. % á ferðinni . Hér eru átta þúsund og ellefu þús. % á ferðinni . -Loks höfum við 54 % . +Loks höfum við 54% . Eins gott að það gangi vel . -Loks höfum við 54,664 % . +Loks höfum við 54,664% . Eins gott að það gangi vel . -Loks höfum við 54.664 % . +Loks höfum við 54.664% . Eins gott að það gangi vel . -Loks höfum við 54½ % . +Loks höfum við 54½% . Eins gott að það gangi vel . -Loks höfum við 54¼ % . +Loks höfum við 54¼% . Eins gott að það gangi vel . -Loks höfum við 54 ½ % . +Loks höfum við 54 ½% . Eins gott að það gangi vel . -Loks höfum við 54 ¼ % . +Loks höfum við 54 ¼% . Eins gott að það gangi vel . -Loks höfum við 54 1/3 % . +Loks höfum við 54 1/3% . Eins gott að það gangi vel . -Loks höfum við 5.554 % . +Loks höfum við 5.554% . Eins gott að það gangi vel . -Loks höfum við 5.554,664 % . +Loks höfum við 5.554,664% . Eins gott að það gangi vel . -Loks höfum við 5.554.664 % . +Loks höfum við 5.554.664% . Eins gott að það gangi vel . -Loks höfum við 5.554 ½ % . +Loks höfum við 5.554 ½% . Eins gott að það gangi vel . -Loks höfum við 5.554 ¼ % . +Loks höfum við 5.554 ¼% . Eins gott að það gangi vel . -Loks höfum við 5.554 ½ % . +Loks höfum við 5.554 ½% . Eins gott að það gangi vel . -Loks höfum við 5.554 ¼ % . +Loks höfum við 5.554 ¼% . Eins gott að það gangi vel . -Loks höfum við 5.554 1/3 % . +Loks höfum við 5.554 1/3% . Eins gott að það gangi vel . -Loks höfum við 5,554 % . +Loks höfum við 5,554% . Eins gott að það gangi vel . -Loks höfum við 5,554,664 % . +Loks höfum við 5,554,664% . Eins gott að það gangi vel . -Loks höfum við 5,554.664 % . +Loks höfum við 5,554.664% . Eins gott að það gangi vel . -Loks höfum við 5,554 ½ % . +Loks höfum við 5,554 ½% . Eins gott að það gangi vel . -Loks höfum við 5,554 ¼ % . +Loks höfum við 5,554 ¼% . Eins gott að það gangi vel . -Loks höfum við 5,554 ½ % . +Loks höfum við 5,554 ½% . Eins gott að það gangi vel . -Loks höfum við 5,554 ¼ % . +Loks höfum við 5,554 ¼% . Eins gott að það gangi vel . -Loks höfum við 5,554 1/3 % . +Loks höfum við 5,554 1/3% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 % . +Loks höfum við 23.985.554% . Eins gott að það gangi vel . -Loks höfum við 23.985.554,664 % . +Loks höfum við 23.985.554,664% . Eins gott að það gangi vel . -Loks höfum við 23.985.554.664 % . +Loks höfum við 23.985.554.664% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ½ % . +Loks höfum við 23.985.554 ½% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ¼ % . +Loks höfum við 23.985.554 ¼% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ½ % . +Loks höfum við 23.985.554 ½% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ¼ % . +Loks höfum við 23.985.554 ¼% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 1/3 % . +Loks höfum við 23.985.554 1/3% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 % . +Loks höfum við 23,985,554% . Eins gott að það gangi vel . -Loks höfum við 23,985,554,664 % . +Loks höfum við 23,985,554,664% . Eins gott að það gangi vel . -Loks höfum við 23,985,554.664 % . +Loks höfum við 23,985,554.664% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ½ % . +Loks höfum við 23,985,554 ½% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ¼ % . +Loks höfum við 23,985,554 ¼% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ½ % . +Loks höfum við 23,985,554 ½% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ¼ % . +Loks höfum við 23,985,554 ¼% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 1/3 % . +Loks höfum við 23,985,554 1/3% . Eins gott að það gangi vel . -Loks höfum við +54 % . +Loks höfum við +54% . Eins gott að það gangi vel . -Loks höfum við +54,664 % . +Loks höfum við +54,664% . Eins gott að það gangi vel . -Loks höfum við +54.664 % . +Loks höfum við +54.664% . Eins gott að það gangi vel . -Loks höfum við +54 ½ % . +Loks höfum við +54 ½% . Eins gott að það gangi vel . -Loks höfum við +54 ¼ % . +Loks höfum við +54 ¼% . Eins gott að það gangi vel . -Loks höfum við +54 ½ % . +Loks höfum við +54 ½% . Eins gott að það gangi vel . -Loks höfum við +54 ¼ % . +Loks höfum við +54 ¼% . Eins gott að það gangi vel . -Loks höfum við +54 1/3 % . +Loks höfum við +54 1/3% . Eins gott að það gangi vel . -Loks höfum við +5.554 % . +Loks höfum við +5.554% . Eins gott að það gangi vel . -Loks höfum við +5.554,664 % . +Loks höfum við +5.554,664% . Eins gott að það gangi vel . -Loks höfum við +5.554.664 % . +Loks höfum við +5.554.664% . Eins gott að það gangi vel . -Loks höfum við +5.554 ½ % . +Loks höfum við +5.554 ½% . Eins gott að það gangi vel . -Loks höfum við +5.554 ¼ % . +Loks höfum við +5.554 ¼% . Eins gott að það gangi vel . -Loks höfum við +5.554 ½ % . +Loks höfum við +5.554 ½% . Eins gott að það gangi vel . -Loks höfum við +5.554 ¼ % . +Loks höfum við +5.554 ¼% . Eins gott að það gangi vel . -Loks höfum við +5.554 1/3 % . +Loks höfum við +5.554 1/3% . Eins gott að það gangi vel . -Loks höfum við +5,554 % . +Loks höfum við +5,554% . Eins gott að það gangi vel . -Loks höfum við +5,554,664 % . +Loks höfum við +5,554,664% . Eins gott að það gangi vel . -Loks höfum við +5,554.664 % . +Loks höfum við +5,554.664% . Eins gott að það gangi vel . -Loks höfum við +5,554 ½ % . +Loks höfum við +5,554 ½% . Eins gott að það gangi vel . -Loks höfum við +5,554 ¼ % . +Loks höfum við +5,554 ¼% . Eins gott að það gangi vel . -Loks höfum við +5,554 ½ % . +Loks höfum við +5,554 ½% . Eins gott að það gangi vel . -Loks höfum við +5,554 ¼ % . +Loks höfum við +5,554 ¼% . Eins gott að það gangi vel . -Loks höfum við +5,554 1/3 % . +Loks höfum við +5,554 1/3% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 % . +Loks höfum við +23.985.554% . Eins gott að það gangi vel . -Loks höfum við +23.985.554,664 % . +Loks höfum við +23.985.554,664% . Eins gott að það gangi vel . -Loks höfum við +23.985.554.664 % . +Loks höfum við +23.985.554.664% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ½ % . +Loks höfum við +23.985.554 ½% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ¼ % . +Loks höfum við +23.985.554 ¼% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ½ % . +Loks höfum við +23.985.554 ½% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ¼ % . +Loks höfum við +23.985.554 ¼% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 1/3 % . +Loks höfum við +23.985.554 1/3% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 % . +Loks höfum við +23,985,554% . Eins gott að það gangi vel . -Loks höfum við +23,985,554,664 % . +Loks höfum við +23,985,554,664% . Eins gott að það gangi vel . -Loks höfum við +23,985,554.664 % . +Loks höfum við +23,985,554.664% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ½ % . +Loks höfum við +23,985,554 ½% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ¼ % . +Loks höfum við +23,985,554 ¼% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ½ % . +Loks höfum við +23,985,554 ½% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ¼ % . +Loks höfum við +23,985,554 ¼% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 1/3 % . +Loks höfum við +23,985,554 1/3% . Eins gott að það gangi vel . Loks höfum við tvö % . Eins gott að það gangi vel . @@ -9492,165 +9448,165 @@ Hér eru áttatíu og átta mrð. ‰ á ferðinni . Hér eru hundrað og einn mrð. ‰ á ferðinni . Hér eru tvö hundruð og fjörutíu ma. ‰ á ferðinni . Hér eru átta þúsund og ellefu þús. ‰ á ferðinni . -Loks höfum við 54 ‰ . +Loks höfum við 54‰ . Eins gott að það gangi vel . -Loks höfum við 54,664 ‰ . +Loks höfum við 54,664‰ . Eins gott að það gangi vel . -Loks höfum við 54.664 ‰ . +Loks höfum við 54.664‰ . Eins gott að það gangi vel . -Loks höfum við 54½ ‰ . +Loks höfum við 54½‰ . Eins gott að það gangi vel . -Loks höfum við 54¼ ‰ . +Loks höfum við 54¼‰ . Eins gott að það gangi vel . -Loks höfum við 54 ½ ‰ . +Loks höfum við 54 ½‰ . Eins gott að það gangi vel . -Loks höfum við 54 ¼ ‰ . +Loks höfum við 54 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 54 1/3 ‰ . +Loks höfum við 54 1/3‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ‰ . +Loks höfum við 5.554‰ . Eins gott að það gangi vel . -Loks höfum við 5.554,664 ‰ . +Loks höfum við 5.554,664‰ . Eins gott að það gangi vel . -Loks höfum við 5.554.664 ‰ . +Loks höfum við 5.554.664‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ½ ‰ . +Loks höfum við 5.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ¼ ‰ . +Loks höfum við 5.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ½ ‰ . +Loks höfum við 5.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ¼ ‰ . +Loks höfum við 5.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 1/3 ‰ . +Loks höfum við 5.554 1/3‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ‰ . +Loks höfum við 5,554‰ . Eins gott að það gangi vel . -Loks höfum við 5,554,664 ‰ . +Loks höfum við 5,554,664‰ . Eins gott að það gangi vel . -Loks höfum við 5,554.664 ‰ . +Loks höfum við 5,554.664‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ½ ‰ . +Loks höfum við 5,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ¼ ‰ . +Loks höfum við 5,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ½ ‰ . +Loks höfum við 5,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ¼ ‰ . +Loks höfum við 5,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 1/3 ‰ . +Loks höfum við 5,554 1/3‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ‰ . +Loks höfum við 23.985.554‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554,664 ‰ . +Loks höfum við 23.985.554,664‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554.664 ‰ . +Loks höfum við 23.985.554.664‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ½ ‰ . +Loks höfum við 23.985.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ¼ ‰ . +Loks höfum við 23.985.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ½ ‰ . +Loks höfum við 23.985.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ¼ ‰ . +Loks höfum við 23.985.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 1/3 ‰ . +Loks höfum við 23.985.554 1/3‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ‰ . +Loks höfum við 23,985,554‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554,664 ‰ . +Loks höfum við 23,985,554,664‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554.664 ‰ . +Loks höfum við 23,985,554.664‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ½ ‰ . +Loks höfum við 23,985,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ¼ ‰ . +Loks höfum við 23,985,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ½ ‰ . +Loks höfum við 23,985,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ¼ ‰ . +Loks höfum við 23,985,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 1/3 ‰ . +Loks höfum við 23,985,554 1/3‰ . Eins gott að það gangi vel . -Loks höfum við +54 ‰ . +Loks höfum við +54‰ . Eins gott að það gangi vel . -Loks höfum við +54,664 ‰ . +Loks höfum við +54,664‰ . Eins gott að það gangi vel . -Loks höfum við +54.664 ‰ . +Loks höfum við +54.664‰ . Eins gott að það gangi vel . -Loks höfum við +54 ½ ‰ . +Loks höfum við +54 ½‰ . Eins gott að það gangi vel . -Loks höfum við +54 ¼ ‰ . +Loks höfum við +54 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +54 ½ ‰ . +Loks höfum við +54 ½‰ . Eins gott að það gangi vel . -Loks höfum við +54 ¼ ‰ . +Loks höfum við +54 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +54 1/3 ‰ . +Loks höfum við +54 1/3‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ‰ . +Loks höfum við +5.554‰ . Eins gott að það gangi vel . -Loks höfum við +5.554,664 ‰ . +Loks höfum við +5.554,664‰ . Eins gott að það gangi vel . -Loks höfum við +5.554.664 ‰ . +Loks höfum við +5.554.664‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ½ ‰ . +Loks höfum við +5.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ¼ ‰ . +Loks höfum við +5.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ½ ‰ . +Loks höfum við +5.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ¼ ‰ . +Loks höfum við +5.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 1/3 ‰ . +Loks höfum við +5.554 1/3‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ‰ . +Loks höfum við +5,554‰ . Eins gott að það gangi vel . -Loks höfum við +5,554,664 ‰ . +Loks höfum við +5,554,664‰ . Eins gott að það gangi vel . -Loks höfum við +5,554.664 ‰ . +Loks höfum við +5,554.664‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ½ ‰ . +Loks höfum við +5,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ¼ ‰ . +Loks höfum við +5,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ½ ‰ . +Loks höfum við +5,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ¼ ‰ . +Loks höfum við +5,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 1/3 ‰ . +Loks höfum við +5,554 1/3‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ‰ . +Loks höfum við +23.985.554‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554,664 ‰ . +Loks höfum við +23.985.554,664‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554.664 ‰ . +Loks höfum við +23.985.554.664‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ½ ‰ . +Loks höfum við +23.985.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ¼ ‰ . +Loks höfum við +23.985.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ½ ‰ . +Loks höfum við +23.985.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ¼ ‰ . +Loks höfum við +23.985.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 1/3 ‰ . +Loks höfum við +23.985.554 1/3‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ‰ . +Loks höfum við +23,985,554‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554,664 ‰ . +Loks höfum við +23,985,554,664‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554.664 ‰ . +Loks höfum við +23,985,554.664‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ½ ‰ . +Loks höfum við +23,985,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ¼ ‰ . +Loks höfum við +23,985,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ½ ‰ . +Loks höfum við +23,985,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ¼ ‰ . +Loks höfum við +23,985,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 1/3 ‰ . +Loks höfum við +23,985,554 1/3‰ . Eins gott að það gangi vel . Loks höfum við tvö ‰ . Eins gott að það gangi vel . @@ -11088,31 +11044,31 @@ Loks höfum við +23,985,554 ¼ ° C . Eins gott að það gangi vel . Loks höfum við +23,985,554 1/3 ° C . Eins gott að það gangi vel . -Loks höfum við tveir ° C . +Loks höfum við tveir ° C. Eins gott að það gangi vel . -Loks höfum við þrjátíu ° C . +Loks höfum við þrjátíu ° C. Eins gott að það gangi vel . -Loks höfum við áttatíu og átta ° C . +Loks höfum við áttatíu og átta ° C. Eins gott að það gangi vel . -Loks höfum við hundrað og einn ° C . +Loks höfum við hundrað og einn ° C. Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu ° C . +Loks höfum við tvö hundruð og fjörutíu ° C. Eins gott að það gangi vel . -Loks höfum við tólf hundruð milljónir ° C . +Loks höfum við tólf hundruð milljónir ° C. Eins gott að það gangi vel . -Loks höfum við átján milljarðar ° C . +Loks höfum við átján milljarðar ° C. Eins gott að það gangi vel . -Loks höfum við tveir ma. ° C . +Loks höfum við tveir ma. ° C. Eins gott að það gangi vel . -Loks höfum við þrjátíu þús. ° C . +Loks höfum við þrjátíu þús. ° C. Eins gott að það gangi vel . -Loks höfum við áttatíu og átta mrð. ° C . +Loks höfum við áttatíu og átta mrð. ° C. Eins gott að það gangi vel . -Loks höfum við hundrað og einn mrð. ° C . +Loks höfum við hundrað og einn mrð. ° C. Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu ma. ° C . +Loks höfum við tvö hundruð og fjörutíu ma. ° C. Eins gott að það gangi vel . -Loks höfum við átta þúsund og ellefu þús. ° C . +Loks höfum við átta þúsund og ellefu þús. ° C. Eins gott að það gangi vel . 54 ° C er há tala . 54,664 ° C er há tala . @@ -11460,31 +11416,31 @@ Loks höfum við +23,985,554 ¼ ° C . Eins gott að það gangi vel . Loks höfum við +23,985,554 1/3 ° C . Eins gott að það gangi vel . -Loks höfum við tveir ° C . +Loks höfum við tveir ° C. Eins gott að það gangi vel . -Loks höfum við þrjátíu ° C . +Loks höfum við þrjátíu ° C. Eins gott að það gangi vel . -Loks höfum við áttatíu og átta ° C . +Loks höfum við áttatíu og átta ° C. Eins gott að það gangi vel . -Loks höfum við hundrað og einn ° C . +Loks höfum við hundrað og einn ° C. Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu ° C . +Loks höfum við tvö hundruð og fjörutíu ° C. Eins gott að það gangi vel . -Loks höfum við tólf hundruð milljónir ° C . +Loks höfum við tólf hundruð milljónir ° C. Eins gott að það gangi vel . -Loks höfum við átján milljarðar ° C . +Loks höfum við átján milljarðar ° C. Eins gott að það gangi vel . -Loks höfum við tveir ma. ° C . +Loks höfum við tveir ma. ° C. Eins gott að það gangi vel . -Loks höfum við þrjátíu þús. ° C . +Loks höfum við þrjátíu þús. ° C. Eins gott að það gangi vel . -Loks höfum við áttatíu og átta mrð. ° C . +Loks höfum við áttatíu og átta mrð. ° C. Eins gott að það gangi vel . -Loks höfum við hundrað og einn mrð. ° C . +Loks höfum við hundrað og einn mrð. ° C. Eins gott að það gangi vel . -Loks höfum við tvö hundruð og fjörutíu ma. ° C . +Loks höfum við tvö hundruð og fjörutíu ma. ° C. Eins gott að það gangi vel . -Loks höfum við átta þúsund og ellefu þús. ° C . +Loks höfum við átta þúsund og ellefu þús. ° C. Eins gott að það gangi vel . 54ml er há tala . 54,664ml er há tala . @@ -12766,175 +12722,175 @@ Loks höfum við +23,985,554 ¼ dl . Eins gott að það gangi vel . Loks höfum við +23,985,554 1/3 dl . Eins gott að það gangi vel . -54km / klst. er há tala . -54,664km / klst. er há tala . -54.664km / klst. er há tala . -54½km / klst. er há tala . -54¼km / klst. er há tala . +54km/klst. er há tala . +54,664km/klst. er há tala . +54.664km/klst. er há tala . +54½km/klst. er há tala . +54¼km/klst. er há tala . 54 ½ km/klst. er há tala . 54 ¼ km/klst. er há tala . 54 1/3 km/klst. er há tala . -5.554km / klst. er há tala . -5.554,664km / klst. er há tala . -5.554.664km / klst. er há tala . +5.554km/klst. er há tala . +5.554,664km/klst. er há tala . +5.554.664km/klst. er há tala . 5.554 ½ km/klst. er há tala . 5.554 ¼ km/klst. er há tala . 5.554 ½ km/klst. er há tala . 5.554 ¼ km/klst. er há tala . 5.554 1/3 km/klst. er há tala . -5,554km / klst. er há tala . -5,554,664km / klst. er há tala . -5,554.664km / klst. er há tala . +5,554km/klst. er há tala . +5,554,664km/klst. er há tala . +5,554.664km/klst. er há tala . 5,554 ½ km/klst. er há tala . 5,554 ¼ km/klst. er há tala . 5,554 ½ km/klst. er há tala . 5,554 ¼ km/klst. er há tala . 5,554 1/3 km/klst. er há tala . -23.985.554km / klst. er há tala . -23.985.554,664km / klst. er há tala . -23.985.554.664km / klst. er há tala . +23.985.554km/klst. er há tala . +23.985.554,664km/klst. er há tala . +23.985.554.664km/klst. er há tala . 23.985.554 ½ km/klst. er há tala . 23.985.554 ¼ km/klst. er há tala . 23.985.554 ½ km/klst. er há tala . 23.985.554 ¼ km/klst. er há tala . 23.985.554 1/3 km/klst. er há tala . -23,985,554km / klst. er há tala . -23,985,554,664km / klst. er há tala . -23,985,554.664km / klst. er há tala . +23,985,554km/klst. er há tala . +23,985,554,664km/klst. er há tala . +23,985,554.664km/klst. er há tala . 23,985,554 ½ km/klst. er há tala . 23,985,554 ¼ km/klst. er há tala . 23,985,554 ½ km/klst. er há tala . 23,985,554 ¼ km/klst. er há tala . 23,985,554 1/3 km/klst. er há tala . -+54km / klst. er há tala . -+54,664km / klst. er há tala . -+54.664km / klst. er há tala . ++54km/klst. er há tala . ++54,664km/klst. er há tala . ++54.664km/klst. er há tala . +54 ½ km/klst. er há tala . +54 ¼ km/klst. er há tala . +54 ½ km/klst. er há tala . +54 ¼ km/klst. er há tala . +54 1/3 km/klst. er há tala . -+5.554km / klst. er há tala . -+5.554,664km / klst. er há tala . -+5.554.664km / klst. er há tala . ++5.554km/klst. er há tala . ++5.554,664km/klst. er há tala . ++5.554.664km/klst. er há tala . +5.554 ½ km/klst. er há tala . +5.554 ¼ km/klst. er há tala . +5.554 ½ km/klst. er há tala . +5.554 ¼ km/klst. er há tala . +5.554 1/3 km/klst. er há tala . -+5,554km / klst. er há tala . -+5,554,664km / klst. er há tala . -+5,554.664km / klst. er há tala . ++5,554km/klst. er há tala . ++5,554,664km/klst. er há tala . ++5,554.664km/klst. er há tala . +5,554 ½ km/klst. er há tala . +5,554 ¼ km/klst. er há tala . +5,554 ½ km/klst. er há tala . +5,554 ¼ km/klst. er há tala . +5,554 1/3 km/klst. er há tala . -+23.985.554km / klst. er há tala . -+23.985.554,664km / klst. er há tala . -+23.985.554.664km / klst. er há tala . ++23.985.554km/klst. er há tala . ++23.985.554,664km/klst. er há tala . ++23.985.554.664km/klst. er há tala . +23.985.554 ½ km/klst. er há tala . +23.985.554 ¼ km/klst. er há tala . +23.985.554 ½ km/klst. er há tala . +23.985.554 ¼ km/klst. er há tala . +23.985.554 1/3 km/klst. er há tala . -+23,985,554km / klst. er há tala . -+23,985,554,664km / klst. er há tala . -+23,985,554.664km / klst. er há tala . ++23,985,554km/klst. er há tala . ++23,985,554,664km/klst. er há tala . ++23,985,554.664km/klst. er há tala . +23,985,554 ½ km/klst. er há tala . +23,985,554 ¼ km/klst. er há tala . +23,985,554 ½ km/klst. er há tala . +23,985,554 ¼ km/klst. er há tala . +23,985,554 1/3 km/klst. er há tala . -Hér eru 54km / klst. á ferðinni . -Hér eru 54,664km / klst. á ferðinni . -Hér eru 54.664km / klst. á ferðinni . -Hér eru 54½km / klst. á ferðinni . -Hér eru 54¼km / klst. á ferðinni . +Hér eru 54km/klst. á ferðinni . +Hér eru 54,664km/klst. á ferðinni . +Hér eru 54.664km/klst. á ferðinni . +Hér eru 54½km/klst. á ferðinni . +Hér eru 54¼km/klst. á ferðinni . Hér eru 54 ½ km/klst. á ferðinni . Hér eru 54 ¼ km/klst. á ferðinni . Hér eru 54 1/3 km/klst. á ferðinni . -Hér eru 5.554km / klst. á ferðinni . -Hér eru 5.554,664km / klst. á ferðinni . -Hér eru 5.554.664km / klst. á ferðinni . +Hér eru 5.554km/klst. á ferðinni . +Hér eru 5.554,664km/klst. á ferðinni . +Hér eru 5.554.664km/klst. á ferðinni . Hér eru 5.554 ½ km/klst. á ferðinni . Hér eru 5.554 ¼ km/klst. á ferðinni . Hér eru 5.554 ½ km/klst. á ferðinni . Hér eru 5.554 ¼ km/klst. á ferðinni . Hér eru 5.554 1/3 km/klst. á ferðinni . -Hér eru 5,554km / klst. á ferðinni . -Hér eru 5,554,664km / klst. á ferðinni . -Hér eru 5,554.664km / klst. á ferðinni . +Hér eru 5,554km/klst. á ferðinni . +Hér eru 5,554,664km/klst. á ferðinni . +Hér eru 5,554.664km/klst. á ferðinni . Hér eru 5,554 ½ km/klst. á ferðinni . Hér eru 5,554 ¼ km/klst. á ferðinni . Hér eru 5,554 ½ km/klst. á ferðinni . Hér eru 5,554 ¼ km/klst. á ferðinni . Hér eru 5,554 1/3 km/klst. á ferðinni . -Hér eru 23.985.554km / klst. á ferðinni . -Hér eru 23.985.554,664km / klst. á ferðinni . -Hér eru 23.985.554.664km / klst. á ferðinni . +Hér eru 23.985.554km/klst. á ferðinni . +Hér eru 23.985.554,664km/klst. á ferðinni . +Hér eru 23.985.554.664km/klst. á ferðinni . Hér eru 23.985.554 ½ km/klst. á ferðinni . Hér eru 23.985.554 ¼ km/klst. á ferðinni . Hér eru 23.985.554 ½ km/klst. á ferðinni . Hér eru 23.985.554 ¼ km/klst. á ferðinni . Hér eru 23.985.554 1/3 km/klst. á ferðinni . -Hér eru 23,985,554km / klst. á ferðinni . -Hér eru 23,985,554,664km / klst. á ferðinni . -Hér eru 23,985,554.664km / klst. á ferðinni . +Hér eru 23,985,554km/klst. á ferðinni . +Hér eru 23,985,554,664km/klst. á ferðinni . +Hér eru 23,985,554.664km/klst. á ferðinni . Hér eru 23,985,554 ½ km/klst. á ferðinni . Hér eru 23,985,554 ¼ km/klst. á ferðinni . Hér eru 23,985,554 ½ km/klst. á ferðinni . Hér eru 23,985,554 ¼ km/klst. á ferðinni . Hér eru 23,985,554 1/3 km/klst. á ferðinni . -Hér eru +54km / klst. á ferðinni . -Hér eru +54,664km / klst. á ferðinni . -Hér eru +54.664km / klst. á ferðinni . +Hér eru +54km/klst. á ferðinni . +Hér eru +54,664km/klst. á ferðinni . +Hér eru +54.664km/klst. á ferðinni . Hér eru +54 ½ km/klst. á ferðinni . Hér eru +54 ¼ km/klst. á ferðinni . Hér eru +54 ½ km/klst. á ferðinni . Hér eru +54 ¼ km/klst. á ferðinni . Hér eru +54 1/3 km/klst. á ferðinni . -Hér eru +5.554km / klst. á ferðinni . -Hér eru +5.554,664km / klst. á ferðinni . -Hér eru +5.554.664km / klst. á ferðinni . +Hér eru +5.554km/klst. á ferðinni . +Hér eru +5.554,664km/klst. á ferðinni . +Hér eru +5.554.664km/klst. á ferðinni . Hér eru +5.554 ½ km/klst. á ferðinni . Hér eru +5.554 ¼ km/klst. á ferðinni . Hér eru +5.554 ½ km/klst. á ferðinni . Hér eru +5.554 ¼ km/klst. á ferðinni . Hér eru +5.554 1/3 km/klst. á ferðinni . -Hér eru +5,554km / klst. á ferðinni . -Hér eru +5,554,664km / klst. á ferðinni . -Hér eru +5,554.664km / klst. á ferðinni . +Hér eru +5,554km/klst. á ferðinni . +Hér eru +5,554,664km/klst. á ferðinni . +Hér eru +5,554.664km/klst. á ferðinni . Hér eru +5,554 ½ km/klst. á ferðinni . Hér eru +5,554 ¼ km/klst. á ferðinni . Hér eru +5,554 ½ km/klst. á ferðinni . Hér eru +5,554 ¼ km/klst. á ferðinni . Hér eru +5,554 1/3 km/klst. á ferðinni . -Hér eru +23.985.554km / klst. á ferðinni . -Hér eru +23.985.554,664km / klst. á ferðinni . -Hér eru +23.985.554.664km / klst. á ferðinni . +Hér eru +23.985.554km/klst. á ferðinni . +Hér eru +23.985.554,664km/klst. á ferðinni . +Hér eru +23.985.554.664km/klst. á ferðinni . Hér eru +23.985.554 ½ km/klst. á ferðinni . Hér eru +23.985.554 ¼ km/klst. á ferðinni . Hér eru +23.985.554 ½ km/klst. á ferðinni . Hér eru +23.985.554 ¼ km/klst. á ferðinni . Hér eru +23.985.554 1/3 km/klst. á ferðinni . -Hér eru +23,985,554km / klst. á ferðinni . -Hér eru +23,985,554,664km / klst. á ferðinni . -Hér eru +23,985,554.664km / klst. á ferðinni . +Hér eru +23,985,554km/klst. á ferðinni . +Hér eru +23,985,554,664km/klst. á ferðinni . +Hér eru +23,985,554.664km/klst. á ferðinni . Hér eru +23,985,554 ½ km/klst. á ferðinni . Hér eru +23,985,554 ¼ km/klst. á ferðinni . Hér eru +23,985,554 ½ km/klst. á ferðinni . Hér eru +23,985,554 ¼ km/klst. á ferðinni . Hér eru +23,985,554 1/3 km/klst. á ferðinni . -Loks höfum við 54km / klst . +Loks höfum við 54km/klst . Eins gott að það gangi vel . -Loks höfum við 54,664km / klst . +Loks höfum við 54,664km/klst . Eins gott að það gangi vel . -Loks höfum við 54.664km / klst . +Loks höfum við 54.664km/klst . Eins gott að það gangi vel . -Loks höfum við 54½km / klst . +Loks höfum við 54½km/klst . Eins gott að það gangi vel . -Loks höfum við 54¼km / klst . +Loks höfum við 54¼km/klst . Eins gott að það gangi vel . Loks höfum við 54 ½ km/klst . Eins gott að það gangi vel . @@ -12942,11 +12898,11 @@ Loks höfum við 54 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við 54 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við 5.554km / klst . +Loks höfum við 5.554km/klst . Eins gott að það gangi vel . -Loks höfum við 5.554,664km / klst . +Loks höfum við 5.554,664km/klst . Eins gott að það gangi vel . -Loks höfum við 5.554.664km / klst . +Loks höfum við 5.554.664km/klst . Eins gott að það gangi vel . Loks höfum við 5.554 ½ km/klst . Eins gott að það gangi vel . @@ -12958,11 +12914,11 @@ Loks höfum við 5.554 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við 5.554 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við 5,554km / klst . +Loks höfum við 5,554km/klst . Eins gott að það gangi vel . -Loks höfum við 5,554,664km / klst . +Loks höfum við 5,554,664km/klst . Eins gott að það gangi vel . -Loks höfum við 5,554.664km / klst . +Loks höfum við 5,554.664km/klst . Eins gott að það gangi vel . Loks höfum við 5,554 ½ km/klst . Eins gott að það gangi vel . @@ -12974,11 +12930,11 @@ Loks höfum við 5,554 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við 5,554 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við 23.985.554km / klst . +Loks höfum við 23.985.554km/klst . Eins gott að það gangi vel . -Loks höfum við 23.985.554,664km / klst . +Loks höfum við 23.985.554,664km/klst . Eins gott að það gangi vel . -Loks höfum við 23.985.554.664km / klst . +Loks höfum við 23.985.554.664km/klst . Eins gott að það gangi vel . Loks höfum við 23.985.554 ½ km/klst . Eins gott að það gangi vel . @@ -12990,11 +12946,11 @@ Loks höfum við 23.985.554 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við 23.985.554 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við 23,985,554km / klst . +Loks höfum við 23,985,554km/klst . Eins gott að það gangi vel . -Loks höfum við 23,985,554,664km / klst . +Loks höfum við 23,985,554,664km/klst . Eins gott að það gangi vel . -Loks höfum við 23,985,554.664km / klst . +Loks höfum við 23,985,554.664km/klst . Eins gott að það gangi vel . Loks höfum við 23,985,554 ½ km/klst . Eins gott að það gangi vel . @@ -13006,11 +12962,11 @@ Loks höfum við 23,985,554 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við 23,985,554 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við +54km / klst . +Loks höfum við +54km/klst . Eins gott að það gangi vel . -Loks höfum við +54,664km / klst . +Loks höfum við +54,664km/klst . Eins gott að það gangi vel . -Loks höfum við +54.664km / klst . +Loks höfum við +54.664km/klst . Eins gott að það gangi vel . Loks höfum við +54 ½ km/klst . Eins gott að það gangi vel . @@ -13022,11 +12978,11 @@ Loks höfum við +54 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við +54 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við +5.554km / klst . +Loks höfum við +5.554km/klst . Eins gott að það gangi vel . -Loks höfum við +5.554,664km / klst . +Loks höfum við +5.554,664km/klst . Eins gott að það gangi vel . -Loks höfum við +5.554.664km / klst . +Loks höfum við +5.554.664km/klst . Eins gott að það gangi vel . Loks höfum við +5.554 ½ km/klst . Eins gott að það gangi vel . @@ -13038,11 +12994,11 @@ Loks höfum við +5.554 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við +5.554 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við +5,554km / klst . +Loks höfum við +5,554km/klst . Eins gott að það gangi vel . -Loks höfum við +5,554,664km / klst . +Loks höfum við +5,554,664km/klst . Eins gott að það gangi vel . -Loks höfum við +5,554.664km / klst . +Loks höfum við +5,554.664km/klst . Eins gott að það gangi vel . Loks höfum við +5,554 ½ km/klst . Eins gott að það gangi vel . @@ -13054,11 +13010,11 @@ Loks höfum við +5,554 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við +5,554 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við +23.985.554km / klst . +Loks höfum við +23.985.554km/klst . Eins gott að það gangi vel . -Loks höfum við +23.985.554,664km / klst . +Loks höfum við +23.985.554,664km/klst . Eins gott að það gangi vel . -Loks höfum við +23.985.554.664km / klst . +Loks höfum við +23.985.554.664km/klst . Eins gott að það gangi vel . Loks höfum við +23.985.554 ½ km/klst . Eins gott að það gangi vel . @@ -13070,11 +13026,11 @@ Loks höfum við +23.985.554 ¼ km/klst . Eins gott að það gangi vel . Loks höfum við +23.985.554 1/3 km/klst . Eins gott að það gangi vel . -Loks höfum við +23,985,554km / klst . +Loks höfum við +23,985,554km/klst . Eins gott að það gangi vel . -Loks höfum við +23,985,554,664km / klst . +Loks höfum við +23,985,554,664km/klst . Eins gott að það gangi vel . -Loks höfum við +23,985,554.664km / klst . +Loks höfum við +23,985,554.664km/klst . Eins gott að það gangi vel . Loks höfum við +23,985,554 ½ km/klst . Eins gott að það gangi vel . @@ -14051,160 +14007,160 @@ Eins gott að það gangi vel . 54.664% er há tala . 54½% er há tala . 54¼% er há tala . -54 ½ % er há tala . -54 ¼ % er há tala . +54 ½% er há tala . +54 ¼% er há tala . 54 1/3 % er há tala . 5.554% er há tala . 5.554,664% er há tala . 5.554.664% er há tala . -5.554 ½ % er há tala . -5.554 ¼ % er há tala . -5.554 ½ % er há tala . -5.554 ¼ % er há tala . +5.554 ½% er há tala . +5.554 ¼% er há tala . +5.554 ½% er há tala . +5.554 ¼% er há tala . 5.554 1/3 % er há tala . 5,554% er há tala . 5,554,664% er há tala . 5,554.664% er há tala . -5,554 ½ % er há tala . -5,554 ¼ % er há tala . -5,554 ½ % er há tala . -5,554 ¼ % er há tala . +5,554 ½% er há tala . +5,554 ¼% er há tala . +5,554 ½% er há tala . +5,554 ¼% er há tala . 5,554 1/3 % er há tala . 23.985.554% er há tala . 23.985.554,664% er há tala . 23.985.554.664% er há tala . -23.985.554 ½ % er há tala . -23.985.554 ¼ % er há tala . -23.985.554 ½ % er há tala . -23.985.554 ¼ % er há tala . +23.985.554 ½% er há tala . +23.985.554 ¼% er há tala . +23.985.554 ½% er há tala . +23.985.554 ¼% er há tala . 23.985.554 1/3 % er há tala . 23,985,554% er há tala . 23,985,554,664% er há tala . 23,985,554.664% er há tala . -23,985,554 ½ % er há tala . -23,985,554 ¼ % er há tala . -23,985,554 ½ % er há tala . -23,985,554 ¼ % er há tala . +23,985,554 ½% er há tala . +23,985,554 ¼% er há tala . +23,985,554 ½% er há tala . +23,985,554 ¼% er há tala . 23,985,554 1/3 % er há tala . +54% er há tala . +54,664% er há tala . +54.664% er há tala . -+54 ½ % er há tala . -+54 ¼ % er há tala . -+54 ½ % er há tala . -+54 ¼ % er há tala . ++54 ½% er há tala . ++54 ¼% er há tala . ++54 ½% er há tala . ++54 ¼% er há tala . +54 1/3 % er há tala . +5.554% er há tala . +5.554,664% er há tala . +5.554.664% er há tala . -+5.554 ½ % er há tala . -+5.554 ¼ % er há tala . -+5.554 ½ % er há tala . -+5.554 ¼ % er há tala . ++5.554 ½% er há tala . ++5.554 ¼% er há tala . ++5.554 ½% er há tala . ++5.554 ¼% er há tala . +5.554 1/3 % er há tala . +5,554% er há tala . +5,554,664% er há tala . +5,554.664% er há tala . -+5,554 ½ % er há tala . -+5,554 ¼ % er há tala . -+5,554 ½ % er há tala . -+5,554 ¼ % er há tala . ++5,554 ½% er há tala . ++5,554 ¼% er há tala . ++5,554 ½% er há tala . ++5,554 ¼% er há tala . +5,554 1/3 % er há tala . +23.985.554% er há tala . +23.985.554,664% er há tala . +23.985.554.664% er há tala . -+23.985.554 ½ % er há tala . -+23.985.554 ¼ % er há tala . -+23.985.554 ½ % er há tala . -+23.985.554 ¼ % er há tala . ++23.985.554 ½% er há tala . ++23.985.554 ¼% er há tala . ++23.985.554 ½% er há tala . ++23.985.554 ¼% er há tala . +23.985.554 1/3 % er há tala . +23,985,554% er há tala . +23,985,554,664% er há tala . +23,985,554.664% er há tala . -+23,985,554 ½ % er há tala . -+23,985,554 ¼ % er há tala . -+23,985,554 ½ % er há tala . -+23,985,554 ¼ % er há tala . ++23,985,554 ½% er há tala . ++23,985,554 ¼% er há tala . ++23,985,554 ½% er há tala . ++23,985,554 ¼% er há tala . +23,985,554 1/3 % er há tala . Hér eru 54% á ferðinni . Hér eru 54,664% á ferðinni . Hér eru 54.664% á ferðinni . Hér eru 54½% á ferðinni . Hér eru 54¼% á ferðinni . -Hér eru 54 ½ % á ferðinni . -Hér eru 54 ¼ % á ferðinni . +Hér eru 54 ½% á ferðinni . +Hér eru 54 ¼% á ferðinni . Hér eru 54 1/3 % á ferðinni . Hér eru 5.554% á ferðinni . Hér eru 5.554,664% á ferðinni . Hér eru 5.554.664% á ferðinni . -Hér eru 5.554 ½ % á ferðinni . -Hér eru 5.554 ¼ % á ferðinni . -Hér eru 5.554 ½ % á ferðinni . -Hér eru 5.554 ¼ % á ferðinni . +Hér eru 5.554 ½% á ferðinni . +Hér eru 5.554 ¼% á ferðinni . +Hér eru 5.554 ½% á ferðinni . +Hér eru 5.554 ¼% á ferðinni . Hér eru 5.554 1/3 % á ferðinni . Hér eru 5,554% á ferðinni . Hér eru 5,554,664% á ferðinni . Hér eru 5,554.664% á ferðinni . -Hér eru 5,554 ½ % á ferðinni . -Hér eru 5,554 ¼ % á ferðinni . -Hér eru 5,554 ½ % á ferðinni . -Hér eru 5,554 ¼ % á ferðinni . +Hér eru 5,554 ½% á ferðinni . +Hér eru 5,554 ¼% á ferðinni . +Hér eru 5,554 ½% á ferðinni . +Hér eru 5,554 ¼% á ferðinni . Hér eru 5,554 1/3 % á ferðinni . Hér eru 23.985.554% á ferðinni . Hér eru 23.985.554,664% á ferðinni . Hér eru 23.985.554.664% á ferðinni . -Hér eru 23.985.554 ½ % á ferðinni . -Hér eru 23.985.554 ¼ % á ferðinni . -Hér eru 23.985.554 ½ % á ferðinni . -Hér eru 23.985.554 ¼ % á ferðinni . +Hér eru 23.985.554 ½% á ferðinni . +Hér eru 23.985.554 ¼% á ferðinni . +Hér eru 23.985.554 ½% á ferðinni . +Hér eru 23.985.554 ¼% á ferðinni . Hér eru 23.985.554 1/3 % á ferðinni . Hér eru 23,985,554% á ferðinni . Hér eru 23,985,554,664% á ferðinni . Hér eru 23,985,554.664% á ferðinni . -Hér eru 23,985,554 ½ % á ferðinni . -Hér eru 23,985,554 ¼ % á ferðinni . -Hér eru 23,985,554 ½ % á ferðinni . -Hér eru 23,985,554 ¼ % á ferðinni . +Hér eru 23,985,554 ½% á ferðinni . +Hér eru 23,985,554 ¼% á ferðinni . +Hér eru 23,985,554 ½% á ferðinni . +Hér eru 23,985,554 ¼% á ferðinni . Hér eru 23,985,554 1/3 % á ferðinni . Hér eru +54% á ferðinni . Hér eru +54,664% á ferðinni . Hér eru +54.664% á ferðinni . -Hér eru +54 ½ % á ferðinni . -Hér eru +54 ¼ % á ferðinni . -Hér eru +54 ½ % á ferðinni . -Hér eru +54 ¼ % á ferðinni . +Hér eru +54 ½% á ferðinni . +Hér eru +54 ¼% á ferðinni . +Hér eru +54 ½% á ferðinni . +Hér eru +54 ¼% á ferðinni . Hér eru +54 1/3 % á ferðinni . Hér eru +5.554% á ferðinni . Hér eru +5.554,664% á ferðinni . Hér eru +5.554.664% á ferðinni . -Hér eru +5.554 ½ % á ferðinni . -Hér eru +5.554 ¼ % á ferðinni . -Hér eru +5.554 ½ % á ferðinni . -Hér eru +5.554 ¼ % á ferðinni . +Hér eru +5.554 ½% á ferðinni . +Hér eru +5.554 ¼% á ferðinni . +Hér eru +5.554 ½% á ferðinni . +Hér eru +5.554 ¼% á ferðinni . Hér eru +5.554 1/3 % á ferðinni . Hér eru +5,554% á ferðinni . Hér eru +5,554,664% á ferðinni . Hér eru +5,554.664% á ferðinni . -Hér eru +5,554 ½ % á ferðinni . -Hér eru +5,554 ¼ % á ferðinni . -Hér eru +5,554 ½ % á ferðinni . -Hér eru +5,554 ¼ % á ferðinni . +Hér eru +5,554 ½% á ferðinni . +Hér eru +5,554 ¼% á ferðinni . +Hér eru +5,554 ½% á ferðinni . +Hér eru +5,554 ¼% á ferðinni . Hér eru +5,554 1/3 % á ferðinni . Hér eru +23.985.554% á ferðinni . Hér eru +23.985.554,664% á ferðinni . Hér eru +23.985.554.664% á ferðinni . -Hér eru +23.985.554 ½ % á ferðinni . -Hér eru +23.985.554 ¼ % á ferðinni . -Hér eru +23.985.554 ½ % á ferðinni . -Hér eru +23.985.554 ¼ % á ferðinni . +Hér eru +23.985.554 ½% á ferðinni . +Hér eru +23.985.554 ¼% á ferðinni . +Hér eru +23.985.554 ½% á ferðinni . +Hér eru +23.985.554 ¼% á ferðinni . Hér eru +23.985.554 1/3 % á ferðinni . Hér eru +23,985,554% á ferðinni . Hér eru +23,985,554,664% á ferðinni . Hér eru +23,985,554.664% á ferðinni . -Hér eru +23,985,554 ½ % á ferðinni . -Hér eru +23,985,554 ¼ % á ferðinni . -Hér eru +23,985,554 ½ % á ferðinni . -Hér eru +23,985,554 ¼ % á ferðinni . +Hér eru +23,985,554 ½% á ferðinni . +Hér eru +23,985,554 ¼% á ferðinni . +Hér eru +23,985,554 ½% á ferðinni . +Hér eru +23,985,554 ¼% á ferðinni . Hér eru +23,985,554 1/3 % á ferðinni . Loks höfum við 54% . Eins gott að það gangi vel . @@ -14216,9 +14172,9 @@ Loks höfum við 54½% . Eins gott að það gangi vel . Loks höfum við 54¼% . Eins gott að það gangi vel . -Loks höfum við 54 ½ % . +Loks höfum við 54 ½% . Eins gott að það gangi vel . -Loks höfum við 54 ¼ % . +Loks höfum við 54 ¼% . Eins gott að það gangi vel . Loks höfum við 54 1/3 % . Eins gott að það gangi vel . @@ -14228,13 +14184,13 @@ Loks höfum við 5.554,664% . Eins gott að það gangi vel . Loks höfum við 5.554.664% . Eins gott að það gangi vel . -Loks höfum við 5.554 ½ % . +Loks höfum við 5.554 ½% . Eins gott að það gangi vel . -Loks höfum við 5.554 ¼ % . +Loks höfum við 5.554 ¼% . Eins gott að það gangi vel . -Loks höfum við 5.554 ½ % . +Loks höfum við 5.554 ½% . Eins gott að það gangi vel . -Loks höfum við 5.554 ¼ % . +Loks höfum við 5.554 ¼% . Eins gott að það gangi vel . Loks höfum við 5.554 1/3 % . Eins gott að það gangi vel . @@ -14244,13 +14200,13 @@ Loks höfum við 5,554,664% . Eins gott að það gangi vel . Loks höfum við 5,554.664% . Eins gott að það gangi vel . -Loks höfum við 5,554 ½ % . +Loks höfum við 5,554 ½% . Eins gott að það gangi vel . -Loks höfum við 5,554 ¼ % . +Loks höfum við 5,554 ¼% . Eins gott að það gangi vel . -Loks höfum við 5,554 ½ % . +Loks höfum við 5,554 ½% . Eins gott að það gangi vel . -Loks höfum við 5,554 ¼ % . +Loks höfum við 5,554 ¼% . Eins gott að það gangi vel . Loks höfum við 5,554 1/3 % . Eins gott að það gangi vel . @@ -14260,13 +14216,13 @@ Loks höfum við 23.985.554,664% . Eins gott að það gangi vel . Loks höfum við 23.985.554.664% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ½ % . +Loks höfum við 23.985.554 ½% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ¼ % . +Loks höfum við 23.985.554 ¼% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ½ % . +Loks höfum við 23.985.554 ½% . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ¼ % . +Loks höfum við 23.985.554 ¼% . Eins gott að það gangi vel . Loks höfum við 23.985.554 1/3 % . Eins gott að það gangi vel . @@ -14276,13 +14232,13 @@ Loks höfum við 23,985,554,664% . Eins gott að það gangi vel . Loks höfum við 23,985,554.664% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ½ % . +Loks höfum við 23,985,554 ½% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ¼ % . +Loks höfum við 23,985,554 ¼% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ½ % . +Loks höfum við 23,985,554 ½% . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ¼ % . +Loks höfum við 23,985,554 ¼% . Eins gott að það gangi vel . Loks höfum við 23,985,554 1/3 % . Eins gott að það gangi vel . @@ -14292,13 +14248,13 @@ Loks höfum við +54,664% . Eins gott að það gangi vel . Loks höfum við +54.664% . Eins gott að það gangi vel . -Loks höfum við +54 ½ % . +Loks höfum við +54 ½% . Eins gott að það gangi vel . -Loks höfum við +54 ¼ % . +Loks höfum við +54 ¼% . Eins gott að það gangi vel . -Loks höfum við +54 ½ % . +Loks höfum við +54 ½% . Eins gott að það gangi vel . -Loks höfum við +54 ¼ % . +Loks höfum við +54 ¼% . Eins gott að það gangi vel . Loks höfum við +54 1/3 % . Eins gott að það gangi vel . @@ -14308,13 +14264,13 @@ Loks höfum við +5.554,664% . Eins gott að það gangi vel . Loks höfum við +5.554.664% . Eins gott að það gangi vel . -Loks höfum við +5.554 ½ % . +Loks höfum við +5.554 ½% . Eins gott að það gangi vel . -Loks höfum við +5.554 ¼ % . +Loks höfum við +5.554 ¼% . Eins gott að það gangi vel . -Loks höfum við +5.554 ½ % . +Loks höfum við +5.554 ½% . Eins gott að það gangi vel . -Loks höfum við +5.554 ¼ % . +Loks höfum við +5.554 ¼% . Eins gott að það gangi vel . Loks höfum við +5.554 1/3 % . Eins gott að það gangi vel . @@ -14324,13 +14280,13 @@ Loks höfum við +5,554,664% . Eins gott að það gangi vel . Loks höfum við +5,554.664% . Eins gott að það gangi vel . -Loks höfum við +5,554 ½ % . +Loks höfum við +5,554 ½% . Eins gott að það gangi vel . -Loks höfum við +5,554 ¼ % . +Loks höfum við +5,554 ¼% . Eins gott að það gangi vel . -Loks höfum við +5,554 ½ % . +Loks höfum við +5,554 ½% . Eins gott að það gangi vel . -Loks höfum við +5,554 ¼ % . +Loks höfum við +5,554 ¼% . Eins gott að það gangi vel . Loks höfum við +5,554 1/3 % . Eins gott að það gangi vel . @@ -14340,13 +14296,13 @@ Loks höfum við +23.985.554,664% . Eins gott að það gangi vel . Loks höfum við +23.985.554.664% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ½ % . +Loks höfum við +23.985.554 ½% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ¼ % . +Loks höfum við +23.985.554 ¼% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ½ % . +Loks höfum við +23.985.554 ½% . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ¼ % . +Loks höfum við +23.985.554 ¼% . Eins gott að það gangi vel . Loks höfum við +23.985.554 1/3 % . Eins gott að það gangi vel . @@ -14356,13 +14312,13 @@ Loks höfum við +23,985,554,664% . Eins gott að það gangi vel . Loks höfum við +23,985,554.664% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ½ % . +Loks höfum við +23,985,554 ½% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ¼ % . +Loks höfum við +23,985,554 ¼% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ½ % . +Loks höfum við +23,985,554 ½% . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ¼ % . +Loks höfum við +23,985,554 ¼% . Eins gott að það gangi vel . Loks höfum við +23,985,554 1/3 % . Eins gott að það gangi vel . @@ -14371,160 +14327,160 @@ Eins gott að það gangi vel . 54.664‰ er há tala . 54½‰ er há tala . 54¼‰ er há tala . -54 ½ ‰ er há tala . -54 ¼ ‰ er há tala . +54 ½‰ er há tala . +54 ¼‰ er há tala . 54 1/3 ‰ er há tala . 5.554‰ er há tala . 5.554,664‰ er há tala . 5.554.664‰ er há tala . -5.554 ½ ‰ er há tala . -5.554 ¼ ‰ er há tala . -5.554 ½ ‰ er há tala . -5.554 ¼ ‰ er há tala . +5.554 ½‰ er há tala . +5.554 ¼‰ er há tala . +5.554 ½‰ er há tala . +5.554 ¼‰ er há tala . 5.554 1/3 ‰ er há tala . 5,554‰ er há tala . 5,554,664‰ er há tala . 5,554.664‰ er há tala . -5,554 ½ ‰ er há tala . -5,554 ¼ ‰ er há tala . -5,554 ½ ‰ er há tala . -5,554 ¼ ‰ er há tala . +5,554 ½‰ er há tala . +5,554 ¼‰ er há tala . +5,554 ½‰ er há tala . +5,554 ¼‰ er há tala . 5,554 1/3 ‰ er há tala . 23.985.554‰ er há tala . 23.985.554,664‰ er há tala . 23.985.554.664‰ er há tala . -23.985.554 ½ ‰ er há tala . -23.985.554 ¼ ‰ er há tala . -23.985.554 ½ ‰ er há tala . -23.985.554 ¼ ‰ er há tala . +23.985.554 ½‰ er há tala . +23.985.554 ¼‰ er há tala . +23.985.554 ½‰ er há tala . +23.985.554 ¼‰ er há tala . 23.985.554 1/3 ‰ er há tala . 23,985,554‰ er há tala . 23,985,554,664‰ er há tala . 23,985,554.664‰ er há tala . -23,985,554 ½ ‰ er há tala . -23,985,554 ¼ ‰ er há tala . -23,985,554 ½ ‰ er há tala . -23,985,554 ¼ ‰ er há tala . +23,985,554 ½‰ er há tala . +23,985,554 ¼‰ er há tala . +23,985,554 ½‰ er há tala . +23,985,554 ¼‰ er há tala . 23,985,554 1/3 ‰ er há tala . +54‰ er há tala . +54,664‰ er há tala . +54.664‰ er há tala . -+54 ½ ‰ er há tala . -+54 ¼ ‰ er há tala . -+54 ½ ‰ er há tala . -+54 ¼ ‰ er há tala . ++54 ½‰ er há tala . ++54 ¼‰ er há tala . ++54 ½‰ er há tala . ++54 ¼‰ er há tala . +54 1/3 ‰ er há tala . +5.554‰ er há tala . +5.554,664‰ er há tala . +5.554.664‰ er há tala . -+5.554 ½ ‰ er há tala . -+5.554 ¼ ‰ er há tala . -+5.554 ½ ‰ er há tala . -+5.554 ¼ ‰ er há tala . ++5.554 ½‰ er há tala . ++5.554 ¼‰ er há tala . ++5.554 ½‰ er há tala . ++5.554 ¼‰ er há tala . +5.554 1/3 ‰ er há tala . +5,554‰ er há tala . +5,554,664‰ er há tala . +5,554.664‰ er há tala . -+5,554 ½ ‰ er há tala . -+5,554 ¼ ‰ er há tala . -+5,554 ½ ‰ er há tala . -+5,554 ¼ ‰ er há tala . ++5,554 ½‰ er há tala . ++5,554 ¼‰ er há tala . ++5,554 ½‰ er há tala . ++5,554 ¼‰ er há tala . +5,554 1/3 ‰ er há tala . +23.985.554‰ er há tala . +23.985.554,664‰ er há tala . +23.985.554.664‰ er há tala . -+23.985.554 ½ ‰ er há tala . -+23.985.554 ¼ ‰ er há tala . -+23.985.554 ½ ‰ er há tala . -+23.985.554 ¼ ‰ er há tala . ++23.985.554 ½‰ er há tala . ++23.985.554 ¼‰ er há tala . ++23.985.554 ½‰ er há tala . ++23.985.554 ¼‰ er há tala . +23.985.554 1/3 ‰ er há tala . +23,985,554‰ er há tala . +23,985,554,664‰ er há tala . +23,985,554.664‰ er há tala . -+23,985,554 ½ ‰ er há tala . -+23,985,554 ¼ ‰ er há tala . -+23,985,554 ½ ‰ er há tala . -+23,985,554 ¼ ‰ er há tala . ++23,985,554 ½‰ er há tala . ++23,985,554 ¼‰ er há tala . ++23,985,554 ½‰ er há tala . ++23,985,554 ¼‰ er há tala . +23,985,554 1/3 ‰ er há tala . Hér eru 54‰ á ferðinni . Hér eru 54,664‰ á ferðinni . Hér eru 54.664‰ á ferðinni . Hér eru 54½‰ á ferðinni . Hér eru 54¼‰ á ferðinni . -Hér eru 54 ½ ‰ á ferðinni . -Hér eru 54 ¼ ‰ á ferðinni . +Hér eru 54 ½‰ á ferðinni . +Hér eru 54 ¼‰ á ferðinni . Hér eru 54 1/3 ‰ á ferðinni . Hér eru 5.554‰ á ferðinni . Hér eru 5.554,664‰ á ferðinni . Hér eru 5.554.664‰ á ferðinni . -Hér eru 5.554 ½ ‰ á ferðinni . -Hér eru 5.554 ¼ ‰ á ferðinni . -Hér eru 5.554 ½ ‰ á ferðinni . -Hér eru 5.554 ¼ ‰ á ferðinni . +Hér eru 5.554 ½‰ á ferðinni . +Hér eru 5.554 ¼‰ á ferðinni . +Hér eru 5.554 ½‰ á ferðinni . +Hér eru 5.554 ¼‰ á ferðinni . Hér eru 5.554 1/3 ‰ á ferðinni . Hér eru 5,554‰ á ferðinni . Hér eru 5,554,664‰ á ferðinni . Hér eru 5,554.664‰ á ferðinni . -Hér eru 5,554 ½ ‰ á ferðinni . -Hér eru 5,554 ¼ ‰ á ferðinni . -Hér eru 5,554 ½ ‰ á ferðinni . -Hér eru 5,554 ¼ ‰ á ferðinni . +Hér eru 5,554 ½‰ á ferðinni . +Hér eru 5,554 ¼‰ á ferðinni . +Hér eru 5,554 ½‰ á ferðinni . +Hér eru 5,554 ¼‰ á ferðinni . Hér eru 5,554 1/3 ‰ á ferðinni . Hér eru 23.985.554‰ á ferðinni . Hér eru 23.985.554,664‰ á ferðinni . Hér eru 23.985.554.664‰ á ferðinni . -Hér eru 23.985.554 ½ ‰ á ferðinni . -Hér eru 23.985.554 ¼ ‰ á ferðinni . -Hér eru 23.985.554 ½ ‰ á ferðinni . -Hér eru 23.985.554 ¼ ‰ á ferðinni . +Hér eru 23.985.554 ½‰ á ferðinni . +Hér eru 23.985.554 ¼‰ á ferðinni . +Hér eru 23.985.554 ½‰ á ferðinni . +Hér eru 23.985.554 ¼‰ á ferðinni . Hér eru 23.985.554 1/3 ‰ á ferðinni . Hér eru 23,985,554‰ á ferðinni . Hér eru 23,985,554,664‰ á ferðinni . Hér eru 23,985,554.664‰ á ferðinni . -Hér eru 23,985,554 ½ ‰ á ferðinni . -Hér eru 23,985,554 ¼ ‰ á ferðinni . -Hér eru 23,985,554 ½ ‰ á ferðinni . -Hér eru 23,985,554 ¼ ‰ á ferðinni . +Hér eru 23,985,554 ½‰ á ferðinni . +Hér eru 23,985,554 ¼‰ á ferðinni . +Hér eru 23,985,554 ½‰ á ferðinni . +Hér eru 23,985,554 ¼‰ á ferðinni . Hér eru 23,985,554 1/3 ‰ á ferðinni . Hér eru +54‰ á ferðinni . Hér eru +54,664‰ á ferðinni . Hér eru +54.664‰ á ferðinni . -Hér eru +54 ½ ‰ á ferðinni . -Hér eru +54 ¼ ‰ á ferðinni . -Hér eru +54 ½ ‰ á ferðinni . -Hér eru +54 ¼ ‰ á ferðinni . +Hér eru +54 ½‰ á ferðinni . +Hér eru +54 ¼‰ á ferðinni . +Hér eru +54 ½‰ á ferðinni . +Hér eru +54 ¼‰ á ferðinni . Hér eru +54 1/3 ‰ á ferðinni . Hér eru +5.554‰ á ferðinni . Hér eru +5.554,664‰ á ferðinni . Hér eru +5.554.664‰ á ferðinni . -Hér eru +5.554 ½ ‰ á ferðinni . -Hér eru +5.554 ¼ ‰ á ferðinni . -Hér eru +5.554 ½ ‰ á ferðinni . -Hér eru +5.554 ¼ ‰ á ferðinni . +Hér eru +5.554 ½‰ á ferðinni . +Hér eru +5.554 ¼‰ á ferðinni . +Hér eru +5.554 ½‰ á ferðinni . +Hér eru +5.554 ¼‰ á ferðinni . Hér eru +5.554 1/3 ‰ á ferðinni . Hér eru +5,554‰ á ferðinni . Hér eru +5,554,664‰ á ferðinni . Hér eru +5,554.664‰ á ferðinni . -Hér eru +5,554 ½ ‰ á ferðinni . -Hér eru +5,554 ¼ ‰ á ferðinni . -Hér eru +5,554 ½ ‰ á ferðinni . -Hér eru +5,554 ¼ ‰ á ferðinni . +Hér eru +5,554 ½‰ á ferðinni . +Hér eru +5,554 ¼‰ á ferðinni . +Hér eru +5,554 ½‰ á ferðinni . +Hér eru +5,554 ¼‰ á ferðinni . Hér eru +5,554 1/3 ‰ á ferðinni . Hér eru +23.985.554‰ á ferðinni . Hér eru +23.985.554,664‰ á ferðinni . Hér eru +23.985.554.664‰ á ferðinni . -Hér eru +23.985.554 ½ ‰ á ferðinni . -Hér eru +23.985.554 ¼ ‰ á ferðinni . -Hér eru +23.985.554 ½ ‰ á ferðinni . -Hér eru +23.985.554 ¼ ‰ á ferðinni . +Hér eru +23.985.554 ½‰ á ferðinni . +Hér eru +23.985.554 ¼‰ á ferðinni . +Hér eru +23.985.554 ½‰ á ferðinni . +Hér eru +23.985.554 ¼‰ á ferðinni . Hér eru +23.985.554 1/3 ‰ á ferðinni . Hér eru +23,985,554‰ á ferðinni . Hér eru +23,985,554,664‰ á ferðinni . Hér eru +23,985,554.664‰ á ferðinni . -Hér eru +23,985,554 ½ ‰ á ferðinni . -Hér eru +23,985,554 ¼ ‰ á ferðinni . -Hér eru +23,985,554 ½ ‰ á ferðinni . -Hér eru +23,985,554 ¼ ‰ á ferðinni . +Hér eru +23,985,554 ½‰ á ferðinni . +Hér eru +23,985,554 ¼‰ á ferðinni . +Hér eru +23,985,554 ½‰ á ferðinni . +Hér eru +23,985,554 ¼‰ á ferðinni . Hér eru +23,985,554 1/3 ‰ á ferðinni . Loks höfum við 54‰ . Eins gott að það gangi vel . @@ -14536,9 +14492,9 @@ Loks höfum við 54½‰ . Eins gott að það gangi vel . Loks höfum við 54¼‰ . Eins gott að það gangi vel . -Loks höfum við 54 ½ ‰ . +Loks höfum við 54 ½‰ . Eins gott að það gangi vel . -Loks höfum við 54 ¼ ‰ . +Loks höfum við 54 ¼‰ . Eins gott að það gangi vel . Loks höfum við 54 1/3 ‰ . Eins gott að það gangi vel . @@ -14548,13 +14504,13 @@ Loks höfum við 5.554,664‰ . Eins gott að það gangi vel . Loks höfum við 5.554.664‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ½ ‰ . +Loks höfum við 5.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ¼ ‰ . +Loks höfum við 5.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ½ ‰ . +Loks höfum við 5.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 5.554 ¼ ‰ . +Loks höfum við 5.554 ¼‰ . Eins gott að það gangi vel . Loks höfum við 5.554 1/3 ‰ . Eins gott að það gangi vel . @@ -14564,13 +14520,13 @@ Loks höfum við 5,554,664‰ . Eins gott að það gangi vel . Loks höfum við 5,554.664‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ½ ‰ . +Loks höfum við 5,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ¼ ‰ . +Loks höfum við 5,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ½ ‰ . +Loks höfum við 5,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 5,554 ¼ ‰ . +Loks höfum við 5,554 ¼‰ . Eins gott að það gangi vel . Loks höfum við 5,554 1/3 ‰ . Eins gott að það gangi vel . @@ -14580,13 +14536,13 @@ Loks höfum við 23.985.554,664‰ . Eins gott að það gangi vel . Loks höfum við 23.985.554.664‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ½ ‰ . +Loks höfum við 23.985.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ¼ ‰ . +Loks höfum við 23.985.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ½ ‰ . +Loks höfum við 23.985.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 23.985.554 ¼ ‰ . +Loks höfum við 23.985.554 ¼‰ . Eins gott að það gangi vel . Loks höfum við 23.985.554 1/3 ‰ . Eins gott að það gangi vel . @@ -14596,13 +14552,13 @@ Loks höfum við 23,985,554,664‰ . Eins gott að það gangi vel . Loks höfum við 23,985,554.664‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ½ ‰ . +Loks höfum við 23,985,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ¼ ‰ . +Loks höfum við 23,985,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ½ ‰ . +Loks höfum við 23,985,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við 23,985,554 ¼ ‰ . +Loks höfum við 23,985,554 ¼‰ . Eins gott að það gangi vel . Loks höfum við 23,985,554 1/3 ‰ . Eins gott að það gangi vel . @@ -14612,13 +14568,13 @@ Loks höfum við +54,664‰ . Eins gott að það gangi vel . Loks höfum við +54.664‰ . Eins gott að það gangi vel . -Loks höfum við +54 ½ ‰ . +Loks höfum við +54 ½‰ . Eins gott að það gangi vel . -Loks höfum við +54 ¼ ‰ . +Loks höfum við +54 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +54 ½ ‰ . +Loks höfum við +54 ½‰ . Eins gott að það gangi vel . -Loks höfum við +54 ¼ ‰ . +Loks höfum við +54 ¼‰ . Eins gott að það gangi vel . Loks höfum við +54 1/3 ‰ . Eins gott að það gangi vel . @@ -14628,13 +14584,13 @@ Loks höfum við +5.554,664‰ . Eins gott að það gangi vel . Loks höfum við +5.554.664‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ½ ‰ . +Loks höfum við +5.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ¼ ‰ . +Loks höfum við +5.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ½ ‰ . +Loks höfum við +5.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +5.554 ¼ ‰ . +Loks höfum við +5.554 ¼‰ . Eins gott að það gangi vel . Loks höfum við +5.554 1/3 ‰ . Eins gott að það gangi vel . @@ -14644,13 +14600,13 @@ Loks höfum við +5,554,664‰ . Eins gott að það gangi vel . Loks höfum við +5,554.664‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ½ ‰ . +Loks höfum við +5,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ¼ ‰ . +Loks höfum við +5,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ½ ‰ . +Loks höfum við +5,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +5,554 ¼ ‰ . +Loks höfum við +5,554 ¼‰ . Eins gott að það gangi vel . Loks höfum við +5,554 1/3 ‰ . Eins gott að það gangi vel . @@ -14660,13 +14616,13 @@ Loks höfum við +23.985.554,664‰ . Eins gott að það gangi vel . Loks höfum við +23.985.554.664‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ½ ‰ . +Loks höfum við +23.985.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ¼ ‰ . +Loks höfum við +23.985.554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ½ ‰ . +Loks höfum við +23.985.554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +23.985.554 ¼ ‰ . +Loks höfum við +23.985.554 ¼‰ . Eins gott að það gangi vel . Loks höfum við +23.985.554 1/3 ‰ . Eins gott að það gangi vel . @@ -14676,13 +14632,13 @@ Loks höfum við +23,985,554,664‰ . Eins gott að það gangi vel . Loks höfum við +23,985,554.664‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ½ ‰ . +Loks höfum við +23,985,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ¼ ‰ . +Loks höfum við +23,985,554 ¼‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ½ ‰ . +Loks höfum við +23,985,554 ½‰ . Eins gott að það gangi vel . -Loks höfum við +23,985,554 ¼ ‰ . +Loks höfum við +23,985,554 ¼‰ . Eins gott að það gangi vel . Loks höfum við +23,985,554 1/3 ‰ . Eins gott að það gangi vel . @@ -16500,12 +16456,12 @@ Tvö hundruð og fjörutíu ma. var náð í gær . Þau náðu átta þúsund og ellefu . Þau náðu tólf hundruð milljónum . Þau náðu átján milljörðum . -Þau náðu tveimur ma . -Þau náðu þrjátíu þús . -Þau náðu áttatíu og átta mrð . -Þau náðu hundrað og einum mrð . -Þau náðu tvö hundruð og fjörutíu ma . -Þau náðu átta þúsund og ellefu þús . +Þau náðu tveimur ma. +Þau náðu þrjátíu þús. +Þau náðu áttatíu og átta mrð. +Þau náðu hundrað og einum mrð. +Þau náðu tvö hundruð og fjörutíu ma. +Þau náðu átta þúsund og ellefu þús. Almennt verð er krónur 9.900 , - en kr. 8.000 , - fyrir félagsmenn . Almennt verð er krónur 9.900 , - . 9.900 , - fyrir félagsmenn . @@ -16514,17 +16470,15 @@ Hún borðaði 4/7 kökunnar en vildi svo 16 / 339 af kaffi . Loks gafst hann upp á pylsuátinu eftir 4959 / 39. 45 3/7 kökunnar féllu í hans hlut . Hún borðaði 45 4/7 kökunnar en vildi svo 45 16 / 339 af kaffi . Loks gafst hann upp á pylsuátinu eftir 45 9 / 39 . -Hvað segirðu ,, skemmtirðu þér vel ???! -" Komið með strákana eins og skot ! " +Hvað segirðu ,, skemmtirðu þér vel ???! " +Komið með strákana eins og skot ! " , sagði hann og hló . -" Komið með strákana eins og skot ! " -sagði hann og hló . +" Komið með strákana eins og skot ! " sagði hann og hló . " Komið með strákana eins og skot ! " " Skal gert , kafteinn ! " " Hvernig fórstu að því ? " , spurði barnið stóreygt . -" Hvernig fórstu að því ? " -spurði barnið stóreygt . +" Hvernig fórstu að því ? " spurði barnið stóreygt . " Hvernig fórstu að því ? " " Ég hoppaði bara . " " Hér er gott að vera , " sagði rúmenski rithöfundurinn . @@ -16919,18 +16873,15 @@ Nú saknar Helgi Björns . Það var þriðji 2. þegar við lentum . Það var 3. desember þegar við lentum . Það var 3. des. þegar við lentum . -Það var 3.12 . -þegar við lentum . +Það var 3.12. þegar við lentum . Það var 3.12 þegar við lentum . -Það var 3.2 . -þegar við lentum . +Það var 3.2. þegar við lentum . Það var 3.2 þegar við lentum . Það var 23. desember þegar við lentum . Það var 23. des. þegar við lentum . Það var 23.12. þegar við lentum . Það var 23.12 þegar við lentum . -Það var 23.2 . -þegar við lentum . +Það var 23.2. þegar við lentum . Það var 23.2 þegar við lentum . Það var 3/12 þegar við lentum . Það var 23/12 þegar við lentum . @@ -16946,18 +16897,15 @@ Nú saknar Helgi Björns . Það var þriðjudagurinn þriðji 2. þegar við lentum . Það var þriðjudagurinn 3. desember þegar við lentum . Það var þriðjudagurinn 3. des. þegar við lentum . -Það var þriðjudagurinn 3.12 . -þegar við lentum . +Það var þriðjudagurinn 3.12. þegar við lentum . Það var þriðjudagurinn 3.12 þegar við lentum . -Það var þriðjudagurinn 3.2 . -þegar við lentum . +Það var þriðjudagurinn 3.2. þegar við lentum . Það var þriðjudagurinn 3.2 þegar við lentum . Það var þriðjudagurinn 23. desember þegar við lentum . Það var þriðjudagurinn 23. des. þegar við lentum . Það var þriðjudagurinn 23.12. þegar við lentum . Það var þriðjudagurinn 23.12 þegar við lentum . -Það var þriðjudagurinn 23.2 . -þegar við lentum . +Það var þriðjudagurinn 23.2. þegar við lentum . Það var þriðjudagurinn 23.2 þegar við lentum . Það var þriðjudagurinn 3/12 þegar við lentum . Það var þriðjudagurinn 23/12 þegar við lentum . @@ -17091,7 +17039,7 @@ Hér komum við 20 f.Kr. til að breyta heiminum . Hér komum við 20 e.Kr. til að breyta heiminum . Hér komum við áramótin 2014 - 2015 til að breyta heiminum . Hér komum við áramótin 2014 - 15 til að breyta heiminum . -Hér komum við mánaðamótin mars-apríl til að breyta heiminum . +Hér komum við mánaðamótin mars - apríl til að breyta heiminum . Hér komum við mánaðamótin nóv. - des. til að breyta heiminum . Hér komum við milli klukkan 13:00 og 15:00 alla virka daga til að breyta heiminum . Bréfið var dagsett 19/5 til að allt gengi upp . @@ -17152,8 +17100,7 @@ Hér er #lifidergott og #mnmlsm - hreyfingin og #égermeðíslenskastafi . Hann lék Nc 6 en þá lék mótherjinn Rxc 6 . Skák og mát . 5/6 ^ 4. √ 4. 12 ³ . -5/6 ˆ 3. √ 3. 100,8 / 2 = 50.4 . -100,8 / 2 = 50.4 . +5/6 ˆ 3. √ 3. 100,8 / 2 = 50.4. 100,8 / 2 = 50.4 . Það á að geyma mjólkina við 20 ± 3 ° C . Atburðurinn verður í stofu 101 . Atburðurinn verður í herbergi 293 . @@ -17169,8 +17116,7 @@ Hús 33B er til vinstri . Hús 1129c er til vinstri . Lagið er í C # . Slóðin er / usr / local . -Ég keypti Android 43.1 , 5.3 . -alpha . +Ég keypti Android 43.1 , 5.3. alpha . Ég keypti Intel Xeon E 5 - 2609 2,4GHz 32 nm 15 MB . Ég keypti Boeing 747 . Ég keypti Pentium i 5 .