Package: python-ottype
Python-OTTypeA python library for Operational Transformation (OT). Basic idea follows the spec athttps://github.com/ottypes/docs.Supported Python versions : CPython 3.8 - 3.11Installationpipinstallpython-ottypeBasic usage:importottypeassertottype.apply('asdf',[3,'123',{'d':'f'}])=='asd123'OT OperationsSkipObject type :intSkipncharacters from the current position is represented asnassertapply('asdf',[3])=='asdf'InsertObject type :strInsert a stringsat the current position is represented assassertapply('asdf',['qwer'])=='qwerasdf'assertapply('asdf',[2,'qwer'])=='asqwerdf'DeleteObject type :dictDelete a stringsat the current position is represented as{'d': s}assertapply('asdf',[{'d':'as'}])=='df'assertapply('asdf',[1,{'d':'sd'}])=='af'Supported FunctionsOT=int|str|dict[str,str]check(ots: list[OT], *, check_unoptimized: bool = True) -> boolCheck a list whether it only contains valid OTs. Ifcheck_unoptimizedisTrue, only normalized list of OTs is accepted.assertcheck(['a',4,'b'])assertnotcheck(['a','b'])# is not normalizedassertnotcheck([3])# is not normalizedapply(doc: str, ots: list[OT], *, check_unoptimized: bool = True) -> strApply a list of OTs to a string.assertapply('abcde',[2,'qq',{'d':'c'},1,'w'])=='abqqdwe'inverse_apply(doc: str, ots: list[OT], *, check_unoptimized: bool = True) -> strInversely apply a list of OTs to a string.assertinverse_apply(apply(doc,ots),ots)==docnormalize(ots: list[OT]) -> list[OT]Normalize a list of OTs : merge consecutive OTs and trim the last skip operation.assertnormalize([1,2,'as','df',{'d':'qw'},{'d':'er'},3])\==[3,'asdf',{'d':'qwer'}]transform(ots1: list[OT], ots2: list[OT]) -> list[OT]Transform a list of OTs with the property:assertapply(apply(doc,ots1),transform(ots2,ots1,'left'))\==apply(apply(doc,ots2),transform(ots1,ots2,'right'))compose(ots1: list[OT], ots2: list[OT]) -> list[OT]Compose two list of OTs with the property:assertapply(apply(doc,ots1),ots2)==apply(doc,compose(ots1,ots2))Benchmark (at Python 3.11)Bechnmark :applyoperationlen(doc)len(ots)baseline (op/s)python (op/s)cython (op/s)1005310.38 ( 1.00x)415.91 ( 1.34x)590.83 ( 1.90x)10010213.27 ( 1.00x)204.82 ( 0.96x)469.43 ( 2.20x)1002094.72 ( 1.00x)112.82 ( 1.19x)457.64 ( 4.83x)1005052.70 ( 1.00x)49.87 ( 0.95x)126.20 ( 2.39x)10010021.74 ( 1.00x)29.78 ( 1.37x)78.39 ( 3.61x)10005493.57 ( 1.00x)322.84 ( 0.65x)638.34 ( 1.29x)100010181.16 ( 1.00x)171.70 ( 0.95x)438.26 ( 2.42x)10002092.83 ( 1.00x)121.60 ( 1.31x)331.89 ( 3.58x)10005043.47 ( 1.00x)60.56 ( 1.39x)121.90 ( 2.80x)100010020.67 ( 1.00x)22.46 ( 1.09x)77.43 ( 3.75x)100005355.19 ( 1.00x)511.89 ( 1.44x)360.03 ( 1.01x)1000010125.78 ( 1.00x)174.76 ( 1.39x)313.41 ( 2.49x)100002077.23 ( 1.00x)98.21 ( 1.27x)246.25 ( 3.19x)100005032.63 ( 1.00x)42.51 ( 1.30x)114.60 ( 3.51x)1000010018.12 ( 1.00x)23.37 ( 1.29x)64.85 ( 3.58x)Bechnmark :inverse_applyoperationlen(doc)len(ots)baseline (op/s)python (op/s)cython (op/s)1005222.70 ( 1.00x)217.16 ( 0.98x)600.39 ( 2.70x)1001098.34 ( 1.00x)154.64 ( 1.57x)391.55 ( 3.98x)1002082.22 ( 1.00x)76.66 ( 0.93x)174.17 ( 2.12x)1005035.24 ( 1.00x)35.82 ( 1.02x)92.70 ( 2.63x)10010017.57 ( 1.00x)19.50 ( 1.11x)48.85 ( 2.78x)10005282.72 ( 1.00x)270.60 ( 0.96x)443.24 ( 1.57x)100010168.26 ( 1.00x)119.19 ( 0.71x)357.90 ( 2.13x)10002060.79 ( 1.00x)64.79 ( 1.07x)293.46 ( 4.83x)10005026.98 ( 1.00x)29.60 ( 1.10x)93.06 ( 3.45x)100010014.38 ( 1.00x)18.09 ( 1.26x)53.81 ( 3.74x)100005172.21 ( 1.00x)178.69 ( 1.04x)318.69 ( 1.85x)1000010143.82 ( 1.00x)120.42 ( 0.84x)257.91 ( 1.79x)100002055.85 ( 1.00x)99.49 ( 1.78x)181.88 ( 3.26x)100005033.09 ( 1.00x)31.53 ( 0.95x)76.12 ( 2.30x)1000010016.76 ( 1.00x)17.02 ( 1.02x)43.02 ( 2.57x)