;idddlmZddlmZddlmZddlmZmZm Z m Z ddl m Z ddl mZmZmZdZdeiZd Zd Zd Zd d d dZdZd d d dZd d d dZd d d dZd d d dZd d d dZd d d dZ d d d dZ!d d d dZ"d d d dZ#d d d dZ$eeeeeeeeeeeeeeeee eee!eee"eee#eee$ed S)) annotations)ceil)conv_sequences) ScorerFlagadd_scorer_attrsis_none setupPandas)ScoreAlignment)_block_normalized_similaritydistancenormalized_similarityc <ddtjtjzdS)Ndr) optimal_score worst_scoreflags)r RESULT_F64 SYMMETRIC)_kwargss EC:\PYTHON\MyICR_Workspace\venv\Lib\site-packages\rapidfuzz/fuzz_py.pyget_scorer_flags_fuzzrs%&)==  get_scorer_flagsc4|r dd|z|z z nd}||kr|ndS)Nrr)distlensum score_cutoffscores r_norm_distancer s3+1 :S3:& & &sE\))55q0rc`t|ttfr|Sgg}|D]m}t|tr|nt |}|r|gR|d|nd|DS)Nc0g|]}|t|Sr)tuple).0xs r z#_split_sequence..-s# 0 0 0a 0E!HH 0 0 0r) isinstancestrbytessplitchrisspaceappend)seq splitted_seqr&chs r_split_sequencer2!s#U|$$yy{{4L ''Q$$ 0QQ#a&& ::<< '    # # # #   # #A & & & & 0 0l 0 0 00rcl|sdSttt|trd|Sttt|t rd|Sg}|D]}||z }|t dgz }|ddS)N  r")r(nextiterr)joinr*ord)seq_listjoinedr/s r_join_splitted_sequencer=0s r$tH~~&&,,"xx!!!$tH~~&&..#yy""" F# 3s88* #2#;rN processorrctt|st|rdS||dz}t||||}|dzS)a Calculates the normalized Indel similarity. Parameters ---------- s1 : Sequence[Hashable] First string to compare. s2 : Sequence[Hashable] Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 See Also -------- rapidfuzz.distance.Indel.normalized_similarity : Normalized Indel similarity Notes ----- .. image:: img/ratio.svg Examples -------- >>> fuzz.ratio("this is a test", "this is a test!") 96.55171966552734 rNrr>)r rindel_normalized_similarity)s1s2r?rrs rratiorD?s_TMMMr{{gbkkq 'B)R^ _ _ _E 3;rc t|}t|}t|}tdd|d|}i}|j}d} |D]} || d| z|| <| dz} t d|D]e} || dz } | |vrt |||d| |} | |jkr-| x|_}d|_| |_|jdkr d|_|cSft ||z D]n} || |zdz } | |vrt |||| | |z|} | |jkr0| x|_}| |_| |z|_|jdkr d|_|cSot ||z |D]b} || }||vrt |||| d|} | |jkr-| x|_}| |_||_|jdkr d|_|cSc|xjdzc_|S)zK implementation of partial_ratio. This assumes len(s1) <= len(s2). rNrr) setlenr getrange!indel_block_normalized_similarityr dest_startdest_end)rBrCr s1_char_setlen1len2resblock block_getr&ch1i substr_lastls_ratio substr_firsts r_partial_ratio_implrZtsjb''K r77D r77D AtQ - -C E I AYsA&&*c  a 1d^^  Qi k ) ) 5UB2A2Uabbb ci  '/ /CI CNCLyA~~  4$;    TA& k ) ) 5UB1q4x<@P_klll ci  '/ /CI CNt8CLyA~~  4$; % %  !u { * * 5UB122Uabbb ci  '/ /CI CNCLyA~~  IIII Jrc>t||||}|dS|jS)u Searches for the optimal alignment of the shorter string in the longer string and returns the fuzz.ratio for this alignment. Parameters ---------- s1 : Sequence[Hashable] First string to compare. s2 : Sequence[Hashable] Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Notes ----- Depending on the length of the needle (shorter string) different implementations are used to improve the performance. short needle (length ≤ 64): When using a short needle length the fuzz.ratio is calculated for all alignments that could result in an optimal alignment. It is guaranteed to find the optimal alignment. For short needles this is very fast, since for them fuzz.ratio runs in ``O(N)`` time. This results in a worst case performance of ``O(NM)``. .. image:: img/partial_ratio_short_needle.svg long needle (length > 64): For long needles a similar implementation to FuzzyWuzzy is used. This implementation only considers alignments which start at one of the longest common substrings. This results in a worst case performance of ``O(N[N/64]M)``. However usually most of the alignments can be skipped. The following Python code shows the concept: .. code-block:: python blocks = SequenceMatcher(None, needle, longer, False).get_matching_blocks() score = 0 for block in blocks: long_start = block[1] - block[0] if (block[1] - block[0]) > 0 else 0 long_end = long_start + len(shorter) long_substr = longer[long_start:long_end] score = max(score, fuzz.ratio(needle, long_substr)) This is a lot faster than checking all possible alignments. However it only finds one of the best alignments and not necessarily the optimal one. .. image:: img/partial_ratio_long_needle.svg Examples -------- >>> fuzz.partial_ratio("this is a test", "this is a test!") 100.0 r>Nr)partial_ratio_alignmentr)rBrCr?r alignments r partial_ratior^s/N(B)R^___Iq ?rctt|st|rdS|||}||}|d}|s|stdddddSt||\}}t |}t |}||kr|}|}n|}|}t |||dz }|jdkrk||kret||j}t |||dz } | j|jkr,t| j| j| j | j | j }|j|krdS||kr|St|j|j|j |j |j S)a Searches for the optimal alignment of the shorter string in the longer string and returns the fuzz.ratio and the corresponding alignment. Parameters ---------- s1 : str | bytes First string to compare. s2 : str | bytes Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff None is returned instead. Default is 0, which deactivates this behaviour. Returns ------- alignment : ScoreAlignment, optional alignment between s1 and s2 with the score as a float between 0 and 100 Examples -------- >>> s1 = "a certain string" >>> s2 = "cetain" >>> res = fuzz.partial_ratio_alignment(s1, s2) >>> res ScoreAlignment(score=83.33333333333334, src_start=2, src_end=8, dest_start=0, dest_end=6) Using the alignment information it is possible to calculate the same fuzz.ratio >>> fuzz.ratio(s1[res.src_start:res.src_end], s2[res.dest_start:res.dest_end]) 83.33333333333334 NrgY@r) r rr rrIrZrmaxrMrN src_startsrc_end) rBrCr?rrPrQshorterlongerrRres2s rr\r\sXMMMr{{gbkkt Yr]] Yr]] 1b1eQ1a000 B # #FB r77D r77D t|| gv|c/A B BC yCDDLL<33 "67L34FGG : ! ! T_dmT^]a]ijjC y<t t|| #)S^S\3=RUR] ^ ^^rc|tt|st|rdS|||}||}t||\}}tt t |}tt t |}t |||S)a Sorts the words in the strings and calculates the fuzz.ratio between them Parameters ---------- s1 : str First string to compare. s2 : str Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Notes ----- .. image:: img/token_sort_ratio.svg Examples -------- >>> fuzz.token_sort_ratio("fuzzy wuzzy was a bear", "wuzzy fuzzy was a bear") 100.0 rNrG)r rrr=sortedr2rDrBrCr?r sorted_s1 sorted_s2s rtoken_sort_ratiorkWsLMMMr{{gbkkq Yr]] Yr]] B # #FB'r/B/B(C(CDDI'r/B/B(C(CDDI IL A A AArc tt|st|rdS|||}||}|d}t||\}}tt |}tt |}|r|sdS||}||}||}|r|r|sdStt|} tt|} t| } t| } tt|} | | dkz| z}| | dkz| z}d}t||zd|dz z z}t| | |}||krt|||z|}| s|S| dk| z}t|| |z|}| dk| z}t|| |z|}t|||S)a Compares the words in the strings based on unique and common words between them using fuzz.ratio Parameters ---------- s1 : str First string to compare. s2 : str Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Notes ----- .. image:: img/token_set_ratio.svg Examples -------- >>> fuzz.token_sort_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear") 83.8709716796875 >>> fuzz.token_set_ratio("fuzzy was a bear", "fuzzy fuzzy was a bear") 100.0 # Returns 100.0 if one string is a subset of the other, regardless of extra content in the longer string >>> fuzz.token_set_ratio("fuzzy was a bear but not a dog", "fuzzy was a bear") 100.0 # Score is reduced only when there is explicit disagreement in the two strings >>> fuzz.token_set_ratio("fuzzy was a bear but not a dog", "fuzzy was a bear but not a cat") 92.3076923076923 rNrgrFrG)r rrrHr2 intersection differencer=rgrIrindel_distancer r`)rBrCr?rtokens_atokens_b intersectdiff_abdiff_badiff_ab_joineddiff_ba_joinedab_lenba_lensect_len sect_ab_len sect_ba_lenresultcutoff_distancer sect_ab_dist sect_ab_ratio sect_ba_dist sect_ba_ratios rtoken_set_ratiorsF^MMMr{{gbkkq Yr]] Yr]] B # #FB?2&&''H?2&&''H 8q%%h//I!!(++G!!(++G's,VG__==N,VG__==N  F  F*95566Hh!m,v5Kh!m,v5K FK+5!lS>P:PQRRO .. W W WD kK&?NN  MV+L"<K1GVVMMV+L"<K1GVVM v}m 4 44rc tt|st|rdS|||}||}tt||d|t ||d|S)aU Helper method that returns the maximum of fuzz.token_set_ratio and fuzz.token_sort_ratio (faster than manually executing the two functions) Parameters ---------- s1 : str First string to compare. s2 : str Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Notes ----- .. image:: img/token_ratio.svg rNr>)r rr`rrkrBrCr?rs r token_ratiorsDMMMr{{gbkkq Yr]] Yr]] B$\JJJR4lKKK  rc|tt|st|rdS|||}||}t||\}}tt t |}tt t |}t |||S)a$ sorts the words in the strings and calculates the fuzz.partial_ratio between them Parameters ---------- s1 : str First string to compare. s2 : str Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Notes ----- .. image:: img/partial_token_sort_ratio.svg rNrG)r rrr=rgr2r^rhs rpartial_token_sort_ratior+sBMMMr{{gbkkq Yr]] Yr]] B # #FB'r/B/B(C(CDDI'r/B/B(C(CDDI IL I I IIrc>tt|st|rdS|||}||}t||\}}tt |}tt |}|r|sdS||rdSt t||}t t||}t|||S)a> Compares the words in the strings based on unique and common words between them using fuzz.partial_ratio Parameters ---------- s1 : str First string to compare. s2 : str Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Notes ----- .. image:: img/partial_token_set_ratio.svg rNrrG) r rrrHr2rmr=rgrnr^)rBrCr?rrprqrsrts rpartial_token_set_ratiorZsDMMMr{{gbkkq Yr]] Yr]] B # #FB?2&&''H?2&&''H 8qX&&s%fX-@-@-J-J&K&KLLG%fX-@-@-J-J&K&KLLG ' E E EErc tt|st|rdS|||}||}|d}t||\}}t|}t|}t |}t |}||rdS||}||} ttt|tt||} t|t|kr"t|t| kr| St|| }t| ttt|tt| |S)am Helper method that returns the maximum of fuzz.partial_token_set_ratio and fuzz.partial_token_sort_ratio (faster than manually executing the two functions) Parameters ---------- s1 : str First string to compare. s2 : str Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Notes ----- .. image:: img/partial_token_ratio.svg rNrrG) r rrr2rHrmrnr^r=rgrIr`) rBrCr?rtokens_split_atokens_split_brprqrsrtr|s rpartial_token_ratiorsDMMMr{{gbkkq Yr]] Yr]] B # #FB$R((N$R((N>""H>""HX&&s!!(++G!!(++G ~ 6 677~ 6 677!F >c'll**s>/B/Bc'll/R/R |V,,L  #F7OO 4 4 #F7OO 4 4%     rc tt|st|rdSd}|||}||}|r|sdS|d}t|}t|}||kr||z n||z }t|||}|dkr7t |||z }t |t |||d|zS|dkrdnd } t ||| z }t |t |||| z}t |||z }t |t|||d|z| zS) a Calculates a weighted ratio based on the other ratio algorithms Parameters ---------- s1 : str First string to compare. s2 : str Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Notes ----- .. image:: img/WRatio.svg rgffffff?NrGg?)rr?g @g?g333333?)r rrIrDr`rr^r) rBrCr?r UNBASE_SCALErPrQ len_ratio end_ratio PARTIAL_SCALEs rWRatiorsBMMMr{{gbkkqL Yr]] Yr]] Rq r77D r77D#d{{t t Ib"<888I3<33lB   B\T J J J\ Y   %++CCM|Y//-?LI}R,OOOR__``I|Y//,>L BNNNQ]]`mm  rctt|st|rdS|||}||}|r|sdSt|||S)a Calculates a quick ratio between two strings using fuzz.ratio. Since v3.0 this behaves similar to fuzz.ratio with the exception that this returns 0 when comparing two empty strings Parameters ---------- s1 : Sequence[Hashable] First string to compare. s2 : Sequence[Hashable] Second string to compare. processor: callable, optional Optional callable that is used to preprocess the strings before comparing them. Default is None, which deactivates this behaviour. score_cutoff : float, optional Optional argument for a score threshold as a float between 0 and 100. For ratio < score_cutoff 0 is returned instead. Default is 0, which deactivates this behaviour. Returns ------- similarity : float similarity between s1 and s2 as a float between 0 and 100 Examples -------- >>> fuzz.QRatio("this is a test", "this is a test!") 96.55171966552734 rNrG)r rrDrs rQRatior0syJMMMr{{gbkkq Yr]] Yr]] Rq Rl 3 3 33r)% __future__rmathrrapidfuzz._common_pyrrapidfuzz._utilsrrrr rapidfuzz.distancer rapidfuzz.distance.Indel_pyr rLr ror rArfuzz_attributer r2r=rDrZr^r\rkrrrrrrrrrrrsk#"""""//////OOOOOOOOOOOO------%&;<111 1 1 1   & 22222j???L KKKKKd P_P_P_P_P_n 1B1B1B1B1Bp l5l5l5l5l5f .....j ,J,J,J,J,Jf 9F9F9F9F9F@ MMMMMh GGGGG\ 1414141414h'''///!>222.111n---)>:::(.999$n555((((((((r