Guest User

Untitled

a guest
Apr 16th, 2018
178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.94 KB | None | 0 0
  1. ## words/word.py
  2. import scriptutil as SU
  3. import re
  4.  
  5. import psycopg2
  6. from psycopg2.extras import DictCursor
  7. from psycopg2.extensions import adapt
  8.  
  9. try:
  10. db = psycopg2.connect(database="scrabble", user="python", password="python")
  11. cur = db.cursor(cursor_factory=psycopg2.extras.DictCursor)
  12. # cur.execute ("CREATE TABLE words (name varchar, probability int, frequency int, catches varchar, hangs varchar);")
  13. except:
  14. print "I am unable to connect to the database"
  15. sys.ext()
  16.  
  17. try:
  18. "trying to find a wordlist reference file"
  19. except:
  20. "failing to find a wordlist reference file. You're on your own, you database-dependent chump!"
  21.  
  22.  
  23. class Word:
  24. """legal scrabble words
  25.  
  26. 1) in official lists, and
  27. 2) have point/frequency attributes that are derived --- not from it's own letters ---
  28. but rather from the point/prob sums of all the possible _derivative_ scrabble-legal words
  29.  
  30. # raw data from official scrabble lists. Can be downloaded from hasbro
  31. """
  32.  
  33. letters = "_ a b c d e f g h i j k l m n o p q r s t u v w x y z".split()
  34. frequencies = (2, 9, 2, 2, 4, 12, 2, 3, 2, 9, 1, 1, 4, 2, 6, 8, 2, 1, 6, 4, 6, 4, 2, 2, 1, 2, 1)
  35. points = (0, 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10)
  36.  
  37.  
  38. letter_frequencies = dict(zip(letters,frequencies))
  39. letter_points = dict(zip(letters,frequencies))
  40.  
  41. def calculate_probability(self):
  42. return sum(map(lambda letter: letter_points[letter], self.catches))
  43. def calculate_frequencies(self):
  44. return sum(map(lambda letter: letter_frequencies[letter], self.catches))
  45.  
  46. def __init__(self,name,points=None,frequency=None,catches=None,hangs=None):
  47. self.name = name
  48.  
  49. if catches is None: self.catches = catches
  50. if frequency is None: self.frequency = frequency
  51. if points is None: self.points = points
  52. if hangs is None: self.hangs = hangs
  53.  
  54. @staticmethod
  55. def count(finder_sql = ""):
  56. """rails-style finder
  57. """
  58. cur.execute("select * from words {0}".format(finder_sql))
  59. return cur.rowcount
  60.  
  61.  
  62. def hangs(self):
  63. """ one-lettter shorter
  64. """
  65. return self.name[0:-1]
  66.  
  67. # def catches(self):
  68. ## var = re.compile(self.name())
  69. # print self.name
  70. # return var.split()
  71.  
  72. @staticmethod
  73. def find_or_create_all_by_name(names):
  74. """
  75. merge
  76. VS
  77. cur.copy_in( ... scratch ... )
  78. insert into words select * from (select distinct * from scratch) uniq where not exists (select 1 from words where words.name = uniq.name);
  79. """
  80.  
  81. # MYTODO escape names ... learning exercise.
  82. matches = Word.find_all("""where words.name in {0}""".format(tuple(names)))
  83. unmatched = set(names) - set(map(lambda w: w.name, matches))
  84. pdb.set_trace()
  85.  
  86. #MYTODO: transactions?
  87. invalid_words = []
  88. created_words = []
  89. for n in unmatched:
  90. w = Word(n)
  91. try:
  92. w.new()
  93. created_words.append(w)
  94. except NameError:
  95. invalid_words.append(n)
  96. # MYTODO: hose invalid words over to the output somehow ... through a logger, if nothing else
  97.  
  98. if not len(created_words) == 0: db.commit()
  99. return created_words.extend(matches) or []
  100.  
  101.  
  102. def new(self):
  103. """ vaguely rails-AR-like new()
  104.  
  105. validates, find-greps for catches, and pre-commits instance to the db
  106.  
  107. #MYTODO: profiling. Is it worth it to split up the two grep searches? (above)
  108. """
  109. self.validate_against_local_lists()
  110. grepd_catches = self.fgrep_catches_in_directories(("./words",))
  111.  
  112. flat_catches = []
  113. for c in grepd_catches: flat_catches.extend(c) #split()
  114. self.catches = "".join(map(lambda catch: catch+" ", set(flat_catches))).strip()
  115.  
  116. cur.execute("""INSERT INTO words VALUES {0}""".format(
  117. (
  118. self.name,
  119. self.calculate_probability(),
  120. self.calculate_frequencies(),
  121. self.catches,
  122. # hangs
  123. self.name[1:] + " " + self.name[:-1],
  124. )
  125. ))
  126.  
  127.  
  128. def validate_against_local_lists(self, lists=(".",)):
  129. """if not found in any text file => not a legal word!
  130.  
  131. this will also catch all the weird things people might throw. Like numbers.
  132. """
  133. if [self.name] not in self.fgrep_in_directories(lists):
  134. raise NameError, "not in ./words/*.txt. Look again, shall we?"
  135. pass
  136.  
  137. def fgrep_in_directories(self, directories=(".",),search_string=None):
  138. """ grep in dir ("." by default)
  139.  
  140. find a word in local .txt files
  141. """
  142. if search_string is None:
  143. search_tuple = (("^{0}$".format(self.name), re.I),)
  144. else:
  145. search_tuple = ((search_string, re.M),)
  146.  
  147. result = map(lambda directory:
  148. SU.ffindgrep(directory, namefs=(lambda s: s.endswith('.txt'),),
  149. regexl=search_tuple
  150. ).values(),
  151. directories)
  152.  
  153. return [catch[0] for catch in result if len(catch) is not 0]
  154.  
  155. def fgrep_catches_in_directories(self, directories=(".",)):
  156. """find all _catches_
  157.  
  158. find a word in local .txt files
  159. """
  160. temp = []
  161. temp.extend(self.fgrep_in_directories(("./words",), "^{0}.$".format(self.name)))
  162. temp.extend(self.fgrep_in_directories(("./words",), "^.{0}$".format(self.name)))
  163. return temp
  164.  
  165. # raise ArgumentError
  166. @staticmethod
  167. def find_all(finder_sql = ""):
  168. """rails-style finder
  169. """
  170. cur.execute("select * from words {0}".format(finder_sql))
  171. return map(lambda properties: Word(*properties), cur.fetchall())
  172.  
  173.  
  174. def flatten(l):
  175. if l is []:
  176. pass
  177. elif isinstance(l,list):
  178. return sum(map(flatten,l))
  179. else:
  180. return l
Add Comment
Please, Sign In to add comment