<s> import sys <EOL> import os <EOL> import re <EOL> from collections import OrderedDict <EOL> libdir = os . path . join ( os . path . dirname ( os . path . realpath ( __file__ ) ) , '<STR_LIT>' ) <EOL> sys . path . append ( libdir ) <EOL> import utils <EOL> import jdecode <EOL> datadir = os . path . realpath ( os . path . join ( libdir , '<STR_LIT>' ) ) <EOL> gramdir = os . path . join ( datadir , '<STR_LIT>' ) <EOL> compute_ngrams = False <EOL> gramdicts = { } <EOL> if os . path . isdir ( gramdir ) : <EOL> import keydiff <EOL> compute_ngrams = True <EOL> for fname in os . listdir ( gramdir ) : <EOL> suffixes = re . findall ( r'<STR_LIT>' , fname ) <EOL> if suffixes : <EOL> grams = int ( suffixes [ <NUM_LIT:0> ] [ <NUM_LIT:1> : - <NUM_LIT:1> ] ) <EOL> d = { } <EOL> with open ( os . path . join ( gramdir , fname ) , '<STR_LIT>' ) as f : <EOL> keydiff . parse_keyfile ( f , d , int ) <EOL> gramdicts [ grams ] = d <EOL> def rare_grams ( card , thresh = <NUM_LIT:2> , grams = <NUM_LIT:2> ) : <EOL> if not grams in gramdicts : <EOL> return None <EOL> rares = <NUM_LIT:0> <EOL> gramdict = gramdicts [ grams ] <EOL> for line in card . text_lines_words : <EOL> for i in range ( <NUM_LIT:0> , len ( line ) - ( grams - <NUM_LIT:1> ) ) : <EOL> ngram = '<STR_LIT:U+0020>' . join ( [ line [ i + j ] for j in range ( <NUM_LIT:0> , grams ) ] ) <EOL> if ngram in gramdict : <EOL> if gramdict [ ngram ] < thresh : <EOL> rares += <NUM_LIT:1> <EOL> else : <EOL> rares += <NUM_LIT:1> <EOL> return rares <EOL> def list_only ( l , items ) : <EOL> for e in l : <EOL> if not e in items : <EOL> return False <EOL> return True <EOL> def pct ( x , total ) : <EOL> pctstr = <NUM_LIT> * float ( x ) / float ( total ) <EOL> return '<STR_LIT:(>' + str ( pctstr ) [ : <NUM_LIT:5> ] + '<STR_LIT>' <EOL> def check_types ( card ) : <EOL> if '<STR_LIT>' in card . types : <EOL> return list_only ( card . types , [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> if '<STR_LIT>' in card . types : <EOL> return list_only ( card . types , [ '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> if '<STR_LIT>' in card . types : <EOL> return list_only ( card . types , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> if '<STR_LIT>' in card . types : <EOL> return list_only ( card . types , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> else : <EOL> return list_only ( card . types , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> def check_pt ( card ) : <EOL> if '<STR_LIT>' in card . types or card . pt : <EOL> return ( ( '<STR_LIT>' in card . types and len ( re . findall ( re . escape ( '<STR_LIT:/>' ) , card . pt ) ) == <NUM_LIT:1> ) <EOL> and not card . loyalty ) <EOL> if '<STR_LIT>' in card . types or card . loyalty : <EOL> return ( ( '<STR_LIT>' in card . types and card . loyalty ) <EOL> and not card . pt ) <EOL> return None <EOL> def check_lands ( card ) : <EOL> if '<STR_LIT>' in card . types : <EOL> return card . cost . format ( ) == '<STR_LIT>' <EOL> else : <EOL> return None <EOL> def check_X ( card ) : <EOL> correct = None <EOL> incost = '<STR_LIT:X>' in card . cost . encode ( ) <EOL> extra_cost_lines = <NUM_LIT:0> <EOL> cost_lines = <NUM_LIT:0> <EOL> use_lines = <NUM_LIT:0> <EOL> for mt in card . text_lines : <EOL> sides = mt . text . split ( '<STR_LIT::>' ) <EOL> if len ( sides ) == <NUM_LIT:2> : <EOL> actcosts = len ( re . findall ( re . escape ( utils . reserved_mana_marker ) , sides [ <NUM_LIT:0> ] ) ) <EOL> lcosts = mt . costs [ : actcosts ] <EOL> rcosts = mt . costs [ actcosts : ] <EOL> if '<STR_LIT:X>' in sides [ <NUM_LIT:0> ] or ( utils . reserved_mana_marker in sides [ <NUM_LIT:0> ] and <EOL> '<STR_LIT:X>' in '<STR_LIT>' . join ( map ( lambda c : c . encode ( ) , lcosts ) ) ) : <EOL> if incost : <EOL> return False <EOL> if '<STR_LIT:X>' in sides [ <NUM_LIT:1> ] or ( utils . reserved_mana_marker in sides [ <NUM_LIT:1> ] and <EOL> '<STR_LIT:X>' in '<STR_LIT>' . join ( map ( lambda c : c . encode ( ) , rcosts ) ) ) : <EOL> correct = True <EOL> if '<STR_LIT>' in sides [ <NUM_LIT:1> ] : <EOL> extra_cost_lines += <NUM_LIT:1> <EOL> continue <EOL> elif '<STR_LIT>' in sides [ <NUM_LIT:0> ] and '<STR_LIT>' in sides [ <NUM_LIT:1> ] : <EOL> correct = True <EOL> continue <EOL> elif '<STR_LIT>' in sides [ <NUM_LIT:1> ] : <EOL> correct = True <EOL> continue <EOL> else : <EOL> return False <EOL> linetext = mt . encode ( ) <EOL> intext = len ( re . findall ( r'<STR_LIT:X>' , linetext ) ) <EOL> defs = ( len ( re . findall ( r'<STR_LIT>' , linetext ) ) <EOL> + len ( re . findall ( re . escape ( '<STR_LIT>' ) , linetext ) ) <EOL> + len ( re . findall ( re . escape ( '<STR_LIT>' ) , linetext ) ) <EOL> + len ( re . findall ( re . escape ( '<STR_LIT>' ) , linetext ) ) <EOL> + len ( re . findall ( re . escape ( '<STR_LIT>' ) , linetext ) ) ) <EOL> if incost : <EOL> if intext : <EOL> correct = True <EOL> elif intext > <NUM_LIT:0> : <EOL> if intext > <NUM_LIT:1> and defs > <NUM_LIT:0> : <EOL> correct = True <EOL> elif '<STR_LIT>' in linetext or '<STR_LIT>' in linetext : <EOL> correct = True <EOL> elif '<STR_LIT>' in linetext and intext > <NUM_LIT:2> : <EOL> correct = True <EOL> elif '<STR_LIT>' in linetext or '<STR_LIT>' in linetext : <EOL> correct = True <EOL> elif ( '<STR_LIT>' in linetext <EOL> or '<STR_LIT>' in linetext <EOL> or '<STR_LIT>' in linetext ) : <EOL> cost_lines += <NUM_LIT:1> <EOL> else : <EOL> use_lines += <NUM_LIT:1> <EOL> if incost and not correct : <EOL> if '<STR_LIT>' in card . text . text or '<STR_LIT>' in card . text . text : <EOL> return True <EOL> return False <EOL> elif cost_lines > <NUM_LIT:0> or use_lines > <NUM_LIT:0> : <EOL> if ( cost_lines + extra_cost_lines ) == <NUM_LIT:1> and use_lines > <NUM_LIT:0> : <EOL> return True <EOL> else : <EOL> return False <EOL> return correct <EOL> def check_kicker ( card ) : <EOL> if '<STR_LIT>' in card . text . text or '<STR_LIT>' in card . text . text : <EOL> newtext = card . text . text . replace ( utils . reserved_mana_marker + '<STR_LIT>' , '<STR_LIT>' ) <EOL> return '<STR_LIT>' in newtext and '<STR_LIT>' in newtext <EOL> else : <EOL> return None <EOL> def check_counters ( card ) : <EOL> uses = len ( re . findall ( re . escape ( utils . counter_marker ) , card . text . text ) ) <EOL> if uses > <NUM_LIT:0> : <EOL> return uses > <NUM_LIT:1> and '<STR_LIT>' + utils . counter_marker in card . text . text <EOL> else : <EOL> return None <EOL> def check_choices ( card ) : <EOL> bullets = len ( re . findall ( re . escape ( utils . bullet_marker ) , card . text . text ) ) <EOL> obracks = len ( re . findall ( re . escape ( utils . choice_open_delimiter ) , card . text . text ) ) <EOL> cbracks = len ( re . findall ( re . escape ( utils . choice_close_delimiter ) , card . text . text ) ) <EOL> if bullets + obracks + cbracks > <NUM_LIT:0> : <EOL> if not ( obracks == cbracks and bullets > <NUM_LIT:0> ) : <EOL> return False <EOL> choice_regex = ( re . escape ( utils . choice_open_delimiter ) + re . escape ( utils . unary_marker ) <EOL> + r'<STR_LIT>' + re . escape ( utils . bullet_marker ) + r'<STR_LIT>' <EOL> + re . escape ( utils . choice_close_delimiter ) ) <EOL> nochoices = re . sub ( choice_regex , '<STR_LIT>' , card . text . text ) <EOL> nobullets = len ( re . findall ( re . escape ( utils . bullet_marker ) , nochoices ) ) <EOL> noobracks = len ( re . findall ( re . escape ( utils . choice_open_delimiter ) , nochoices ) ) <EOL> nocbracks = len ( re . findall ( re . escape ( utils . choice_close_delimiter ) , nochoices ) ) <EOL> return nobullets + noobracks + nocbracks == <NUM_LIT:0> <EOL> else : <EOL> return None <EOL> def check_auras ( card ) : <EOL> if '<STR_LIT>' in card . types or '<STR_LIT>' in card . subtypes or '<STR_LIT>' in card . text . text : <EOL> return '<STR_LIT>' in card . types or '<STR_LIT>' in card . subtypes or '<STR_LIT>' in card . text . text <EOL> else : <EOL> return None <EOL> def check_equipment ( card ) : <EOL> if '<STR_LIT>' in card . subtypes : <EOL> return '<STR_LIT>' in card . text . text <EOL> else : <EOL> return None <EOL> def check_planeswalkers ( card ) : <EOL> if '<STR_LIT>' in card . types : <EOL> good_lines = <NUM_LIT:0> <EOL> bad_lines = <NUM_LIT:0> <EOL> initial_re = r'<STR_LIT>' + re . escape ( utils . unary_marker ) + re . escape ( utils . unary_counter ) + '<STR_LIT>' <EOL> initial_re_X = r'<STR_LIT>' + re . escape ( utils . x_marker ) + '<STR_LIT>' <EOL> for line in card . text_lines : <EOL> if len ( re . findall ( initial_re , line . text ) ) == <NUM_LIT:1> : <EOL> good_lines += <NUM_LIT:1> <EOL> elif len ( re . findall ( initial_re_X , line . text ) ) == <NUM_LIT:1> : <EOL> good_lines += <NUM_LIT:1> <EOL> elif '<STR_LIT>' in line . text : <EOL> pass <EOL> elif '<STR_LIT>' in line . text or '<STR_LIT>' in line . text : <EOL> pass <EOL> else : <EOL> bad_lines += <NUM_LIT:1> <EOL> return good_lines > <NUM_LIT:1> and bad_lines == <NUM_LIT:0> <EOL> else : <EOL> return None <EOL> def check_levelup ( card ) : <EOL> if '<STR_LIT>' in card . text . text : <EOL> uplines = <NUM_LIT:0> <EOL> llines = <NUM_LIT:0> <EOL> for line in card . text_lines : <EOL> if '<STR_LIT>' + utils . counter_marker + '<STR_LIT>' in line . text : <EOL> uplines += <NUM_LIT:1> <EOL> llines += <NUM_LIT:1> <EOL> elif '<STR_LIT>' in line . text : <EOL> llines += <NUM_LIT:1> <EOL> elif '<STR_LIT>' in line . text : <EOL> uplines += <NUM_LIT:1> <EOL> elif '<STR_LIT>' in line . text : <EOL> llines += <NUM_LIT:1> <EOL> return uplines == <NUM_LIT:1> and llines > <NUM_LIT:0> <EOL> else : <EOL> return None <EOL> def check_activated ( card ) : <EOL> activated = <NUM_LIT:0> <EOL> for line in card . text_lines : <EOL> if '<STR_LIT:.>' in line . text : <EOL> subtext = re . sub ( r'<STR_LIT>' , '<STR_LIT>' , line . text ) <EOL> if '<STR_LIT>' in subtext : <EOL> pass <EOL> elif '<STR_LIT>' + utils . this_marker + '<STR_LIT>' in subtext : <EOL> pass <EOL> elif '<STR_LIT>' in subtext : <EOL> pass <EOL> elif '<STR_LIT::>' in subtext : <EOL> activated += <NUM_LIT:1> <EOL> if activated > <NUM_LIT:0> : <EOL> return list_only ( card . types , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> else : <EOL> return None <EOL> def check_triggered ( card ) : <EOL> triggered = <NUM_LIT:0> <EOL> triggered_2 = <NUM_LIT:0> <EOL> for line in card . text_lines : <EOL> if '<STR_LIT>' + utils . this_marker + '<STR_LIT>' in line . text : <EOL> triggered += <NUM_LIT:1> <EOL> if '<STR_LIT>' + utils . this_marker + '<STR_LIT>' in line . text : <EOL> triggered += <NUM_LIT:1> <EOL> if '<STR_LIT>' + utils . this_marker + '<STR_LIT>' in line . text : <EOL> triggered += <NUM_LIT:1> <EOL> elif '<STR_LIT>' == line . text [ : <NUM_LIT:16> ] or '<STR_LIT>' == line . text [ : <NUM_LIT:4> ] : <EOL> if '<STR_LIT>' in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> elif '<STR_LIT>' in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> elif '<STR_LIT>' + utils . this_marker + '<STR_LIT>' in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> elif '<STR_LIT>' in line . text or '<STR_LIT>' + utils . this_marker + '<STR_LIT>' in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> elif '<STR_LIT>' + utils . this_marker + '<STR_LIT>' in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> elif '<STR_LIT>' + utils . this_marker in line . text or '<STR_LIT>' + utils . this_marker in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> elif '<STR_LIT>' in line . text or '<STR_LIT>' in line . text or '<STR_LIT>' in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> elif '<STR_LIT>' in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> elif '<STR_LIT>' + utils . this_marker in line . text or '<STR_LIT>' + utils . this_marker in line . text : <EOL> triggered_2 += <NUM_LIT:1> <EOL> else : <EOL> triggered += <NUM_LIT:1> <EOL> if triggered > <NUM_LIT:0> : <EOL> return list_only ( card . types , [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] ) <EOL> elif triggered_2 : <EOL> return True <EOL> else : <EOL> return None <EOL> def check_chosen ( card ) : <EOL> if '<STR_LIT>' in card . text . text : <EOL> return ( '<STR_LIT>' in card . text . text <EOL> or '<STR_LIT>' in card . text . text <EOL> or '<STR_LIT:name>' in card . text . text <EOL> or '<STR_LIT>' in card . text . text <EOL> or '<STR_LIT>' in card . text . text ) <EOL> else : <EOL> return None <EOL> def check_shuffle ( card ) : <EOL> retval = None <EOL> for line in card . text_lines : <EOL> if '<STR_LIT>' in line . text and '<STR_LIT>' in line . text : <EOL> thisval = ( '<STR_LIT>' in line . text <EOL> or '<STR_LIT>' in line . text <EOL> or '<STR_LIT>' in line . text <EOL> or '<STR_LIT>' in line . text <EOL> or '<STR_LIT>' in line . text <EOL> or '<STR_LIT>' in line . text ) <EOL> if retval is None : <EOL> retval = thisval <EOL> else : <EOL> retval = retval and thisval <EOL> return retval <EOL> def check_quotes ( card ) : <EOL> retval = None <EOL> for line in card . text_lines : <EOL> quotes = len ( re . findall ( re . escape ( '<STR_LIT:">' ) , line . text ) ) <EOL> quotes += len ( re . findall ( re . escape ( '<STR_LIT>' ) , line . text ) ) <EOL> if quotes > <NUM_LIT:0> : <EOL> thisval = quotes % <NUM_LIT:2> == <NUM_LIT:0> <EOL> if retval is None : <EOL> retval = thisval <EOL> else : <EOL> retval = retval and thisval <EOL> return retval <EOL> props = OrderedDict ( [ <EOL> ( '<STR_LIT>' , check_types ) , <EOL> ( '<STR_LIT>' , check_pt ) , <EOL> ( '<STR_LIT>' , check_lands ) , <EOL> ( '<STR_LIT:X>' , check_X ) , <EOL> ( '<STR_LIT>' , check_kicker ) , <EOL> ( '<STR_LIT>' , check_counters ) , <EOL> ( '<STR_LIT>' , check_choices ) , <EOL> ( '<STR_LIT>' , check_quotes ) , <EOL> ( '<STR_LIT>' , check_auras ) , <EOL> ( '<STR_LIT>' , check_equipment ) , <EOL> ( '<STR_LIT>' , check_planeswalkers ) , <EOL> ( '<STR_LIT>' , check_levelup ) , <EOL> ( '<STR_LIT>' , check_chosen ) , <EOL> ( '<STR_LIT>' , check_shuffle ) , <EOL> ( '<STR_LIT>' , check_activated ) , <EOL> ( '<STR_LIT>' , check_triggered ) , <EOL> ] ) <EOL> def process_props ( cards , dump = False , uncovered = False ) : <EOL> total_all = <NUM_LIT:0> <EOL> total_good = <NUM_LIT:0> <EOL> total_bad = <NUM_LIT:0> <EOL> total_uncovered = <NUM_LIT:0> <EOL> values = OrderedDict ( [ ( k , ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) ) for k in props ] ) <EOL> for card in cards : <EOL> total_all += <NUM_LIT:1> <EOL> overall = True <EOL> any_prop = False <EOL> for prop in props : <EOL> ( total , good , bad ) = values [ prop ] <EOL> this_prop = props [ prop ] ( card ) <EOL> if not this_prop is None : <EOL> total += <NUM_LIT:1> <EOL> if not prop == '<STR_LIT>' : <EOL> any_prop = True <EOL> if this_prop : <EOL> good += <NUM_LIT:1> <EOL> else : <EOL> bad += <NUM_LIT:1> <EOL> overall = False <EOL> if card . name not in [ '<STR_LIT>' , '<STR_LIT>' , <EOL> "<STR_LIT>" , '<STR_LIT>' , <EOL> ] and dump : <EOL> print ( '<STR_LIT>' + prop + '<STR_LIT>' ) <EOL> print ( card . encode ( ) ) <EOL> print ( card . format ( ) ) <EOL> values [ prop ] = ( total , good , bad ) <EOL> if overall : <EOL> total_good += <NUM_LIT:1> <EOL> else : <EOL> total_bad += <NUM_LIT:1> <EOL> if not any_prop : <EOL> total_uncovered += <NUM_LIT:1> <EOL> if uncovered : <EOL> print ( '<STR_LIT>' ) <EOL> print ( card . encode ( ) ) <EOL> print ( card . format ( ) ) <EOL> return ( ( total_all , total_good , total_bad , total_uncovered ) , <EOL> values ) <EOL> def main ( fname , oname = None , verbose = False , dump = False ) : <EOL> cards = jdecode . mtg_open_file ( fname , verbose = verbose ) <EOL> do_grams = False <EOL> if do_grams : <EOL> rg = { } <EOL> for card in cards : <EOL> g = rare_grams ( card , thresh = <NUM_LIT:2> , grams = <NUM_LIT:2> ) <EOL> if len ( card . text_words ) > <NUM_LIT:0> : <EOL> g = int ( <NUM_LIT:1.0> + ( float ( g ) * <NUM_LIT> / float ( len ( card . text_words ) ) ) ) <EOL> if g in rg : <EOL> rg [ g ] += <NUM_LIT:1> <EOL> else : <EOL> rg [ g ] = <NUM_LIT:1> <EOL> if g >= <NUM_LIT> : <EOL> print g <EOL> print card . format ( ) <EOL> tot = <NUM_LIT:0> <EOL> vmax = sum ( rg . values ( ) ) <EOL> pct90 = None <EOL> pct95 = None <EOL> pct99 = None <EOL> for i in sorted ( rg ) : <EOL> print str ( i ) + '<STR_LIT>' + str ( rg [ i ] ) <EOL> tot += rg [ i ] <EOL> if pct90 is None and tot >= vmax * <NUM_LIT> : <EOL> pct90 = i <EOL> if pct95 is None and tot >= vmax * <NUM_LIT> : <EOL> pct95 = i <EOL> if pct99 is None and tot >= vmax * <NUM_LIT> : <EOL> pct99 = i <EOL> print '<STR_LIT>' + str ( pct90 ) <EOL> print '<STR_LIT>' + str ( pct95 ) <EOL> print '<STR_LIT>' + str ( pct99 ) <EOL> else : <EOL> ( ( total_all , total_good , total_bad , total_uncovered ) , <EOL> values ) = process_props ( cards , dump = dump ) <EOL> print ( '<STR_LIT>' ) <EOL> print ( '<STR_LIT>' + str ( total_all ) ) <EOL> print ( '<STR_LIT>' + str ( total_good ) + '<STR_LIT:U+0020>' + pct ( total_good , total_all ) ) <EOL> print ( '<STR_LIT>' + str ( total_bad ) + '<STR_LIT:U+0020>' + pct ( total_bad , total_all ) ) <EOL> print ( '<STR_LIT>' + str ( total_uncovered ) + '<STR_LIT:U+0020>' + pct ( total_uncovered , total_all ) ) <EOL> print ( '<STR_LIT>' ) <EOL> for prop in props : <EOL> ( total , good , bad ) = values [ prop ] <EOL> print ( prop + '<STR_LIT::>' ) <EOL> print ( '<STR_LIT>' + str ( total ) + '<STR_LIT:U+0020>' + pct ( total , total_all ) ) <EOL> print ( '<STR_LIT>' + str ( good ) + '<STR_LIT:U+0020>' + pct ( good , total_all ) ) <EOL> print ( '<STR_LIT>' + str ( bad ) + '<STR_LIT:U+0020>' + pct ( bad , total_all ) ) <EOL> if __name__ == '<STR_LIT:__main__>' : <EOL> import argparse <EOL> parser = argparse . ArgumentParser ( ) <EOL> parser . add_argument ( '<STR_LIT>' , <EOL> help = '<STR_LIT>' ) <EOL> parser . add_argument ( '<STR_LIT>' , nargs = '<STR_LIT:?>' , default = None , <EOL> help = '<STR_LIT>' ) <EOL> parser . add_argument ( '<STR_LIT>' , '<STR_LIT>' , action = '<STR_LIT:store_true>' , <EOL> help = '<STR_LIT>' ) <EOL> parser . add_argument ( '<STR_LIT>' , '<STR_LIT>' , action = '<STR_LIT:store_true>' , <EOL> help = '<STR_LIT>' ) <EOL> args = parser . parse_args ( ) <EOL> main ( args . infile , args . outfile , verbose = args . verbose , dump = args . dump ) <EOL> exit ( <NUM_LIT:0> ) </s>
