"""Writes a frequency rank onto every bank word. Without this the bank is handed out in alphabetical order, so the first two weeks are nothing but words starting with `a`. Rank 0 is the most common word. A multi-word entry (`bus stop`, `air conditioning`) is not in a word frequency list at all, so it takes the rank of its rarest part: a phrase is no easier than the hardest word in it. """ import json import os import re import sys ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) BANK = os.path.join(ROOT, 'assets/words/wordbank.json') # Words the list does not have at all go last, but stay in their level. UNRANKED = 99999 def load_ranks(path): ranks = {} with open(path) as handle: for position, line in enumerate(handle): parts = line.split() if len(parts) == 2: ranks.setdefault(parts[0], position) return ranks def rank_of(word, ranks): direct = ranks.get(word.lower()) if direct is not None: return direct parts = [re.sub(r"[^a-z']", '', part) for part in word.lower().split()] parts = [part for part in parts if part] found = [ranks[part] for part in parts if part in ranks] if len(found) == len(parts) and found: return max(found) return UNRANKED def main(): frequency = sys.argv[1] ranks = load_ranks(frequency) with open(BANK) as handle: bank = json.load(handle) unranked = 0 for word in bank['words']: rank = rank_of(word['en'], ranks) word['rank'] = rank if rank == UNRANKED: unranked += 1 with open(BANK, 'w') as handle: json.dump(bank, handle, ensure_ascii=False, separators=(',', ':')) handle.write('\n') print('ranked %d, unranked %d' % (len(bank['words']) - unranked, unranked)) for level in ('A1', 'A2', 'B1'): words = sorted( (w for w in bank['words'] if w['level'] == level), key=lambda w: w['rank'], ) print('%s first 12: %s' % (level, ' '.join(w['en'] for w in words[:12]))) if __name__ == '__main__': main()