sumolib.fpdiff

  1# -*- coding: utf-8 -*-
  2# Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
  3# Copyright (C) 2011-2026 German Aerospace Center (DLR) and others.
  4# This program and the accompanying materials are made available under the
  5# terms of the Eclipse Public License 2.0 which is available at
  6# https://www.eclipse.org/legal/epl-2.0/
  7# This Source Code may also be made available under the following Secondary
  8# Licenses when the conditions for such availability set forth in the Eclipse
  9# Public License 2.0 are satisfied: GNU General Public License, version 2
 10# or later which is available at
 11# https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
 12# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
 13
 14# @file    fpdiff.py
 15# @author  Michael Behrisch
 16# @date    2014-08-26
 17
 18
 19def _getNumberAt(line, pos):
 20    start = pos
 21    eSeen = False
 22    dotSeen = False
 23    while start > 0 and line[start-1] in "1234567890.eE-+":
 24        if line[start-1] in "eE":
 25            if eSeen:
 26                break
 27            eSeen = True
 28        if line[start-1] == ".":
 29            if dotSeen:
 30                break
 31            dotSeen = True
 32        start -= 1
 33    end = pos
 34    while end < len(line) and line[end] in "1234567890.eE-+":
 35        if line[end] in "eE":
 36            if eSeen:
 37                break
 38            eSeen = True
 39        if line[end] == ".":
 40            if dotSeen:
 41                break
 42            dotSeen = True
 43        end += 1
 44    return line[start:end], line[end:]
 45
 46
 47def _fpequalAtPos(l1, l2, tolerance, relTolerance, pos):
 48    number1, l1 = _getNumberAt(l1, pos)
 49    number2, l2 = _getNumberAt(l2, pos)
 50    try:
 51        equal = False
 52        deviation = abs(float(number1) - float(number2))
 53        if tolerance is not None and deviation <= tolerance:
 54            equal = True
 55        elif relTolerance is not None:
 56            referenceValue = abs(float(number1))
 57            if referenceValue == 0:
 58                equal = (deviation == 0)
 59            elif deviation / referenceValue <= relTolerance:
 60                equal = True
 61    except ValueError:
 62        pass
 63    return equal, l1, l2
 64
 65
 66def _fpequal(l1, l2, tolerance, relTolerance):
 67    pos = 0
 68    while pos < min(len(l1), len(l2)):
 69        if l1[pos] != l2[pos]:
 70            equal, l1, l2 = _fpequalAtPos(l1, l2, tolerance, relTolerance, pos)
 71            if not equal:
 72                return False
 73            pos = 0
 74        else:
 75            pos += 1
 76    if len(l1) == len(l2):
 77        return True
 78    else:
 79        return _fpequalAtPos(l1, l2, tolerance, relTolerance, pos)[0]
 80
 81
 82def fpfilter(fromlines, tolines, tolerance, relTolerance=None):
 83    out = []
 84    for fromline, toline in zip(fromlines, tolines):
 85        if fromline == toline or _fpequal(fromline, toline, tolerance, relTolerance):
 86            out.append(fromline)
 87        else:
 88            out.append(toline)
 89    return out + tolines[len(fromlines):]
 90
 91
 92def diff(fromlines, tolines, tolerance, relTolerance=None):
 93    out = []
 94    for fromline, toline in zip(fromlines, tolines):
 95        if fromline != toline and not _fpequal(fromline, toline, tolerance, relTolerance):
 96            out.append("< " + fromline)
 97            out.append("> " + toline)
 98    for line in tolines[len(fromlines):]:
 99        out.append("> " + line)
100    for line in fromlines[len(tolines):]:
101        out.append("< " + line)
102    return out
def fpfilter(fromlines, tolines, tolerance, relTolerance=None):
83def fpfilter(fromlines, tolines, tolerance, relTolerance=None):
84    out = []
85    for fromline, toline in zip(fromlines, tolines):
86        if fromline == toline or _fpequal(fromline, toline, tolerance, relTolerance):
87            out.append(fromline)
88        else:
89            out.append(toline)
90    return out + tolines[len(fromlines):]
def diff(fromlines, tolines, tolerance, relTolerance=None):
 93def diff(fromlines, tolines, tolerance, relTolerance=None):
 94    out = []
 95    for fromline, toline in zip(fromlines, tolines):
 96        if fromline != toline and not _fpequal(fromline, toline, tolerance, relTolerance):
 97            out.append("< " + fromline)
 98            out.append("> " + toline)
 99    for line in tolines[len(fromlines):]:
100        out.append("> " + line)
101    for line in fromlines[len(tolines):]:
102        out.append("< " + line)
103    return out