diff --git a/.gitignore b/.gitignore index 6af70f0..83e7205 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ __pycache__/ *$py.class *.lock - +.vscode/ # C extensions *.so diff --git a/data/data_tests.ipynb b/data/data_tests.ipynb index 9fbb84d..80cb9ed 100644 --- a/data/data_tests.ipynb +++ b/data/data_tests.ipynb @@ -31,7 +31,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ @@ -48,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -67,7 +67,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -81,7 +81,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -95,7 +95,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -116,14 +116,14 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1023195/1023195 [00:00<00:00, 1386092.63it/s]\n" + "100%|██████████| 1023195/1023195 [00:00<00:00, 1368488.50it/s]\n" ] } ], @@ -142,7 +142,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ @@ -221,14 +221,14 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "100%|██████████| 1023195/1023195 [00:06<00:00, 159434.15it/s]\n" + "100%|██████████| 1023195/1023195 [00:08<00:00, 125917.77it/s]\n" ] } ], @@ -239,8 +239,16 @@ " item = dictionary_database[word]\n", " try:\n", " senses = get_senses(word)\n", - " if len(senses) > 1:\n", + " if len(senses) > 4:\n", " list_words.append(word)\n", + " continue\n", + " try:\n", + " if len(get_antonyms(word)) >= 1:\n", + " list_words.append(word)\n", + " continue\n", + " except NoDataException:\n", + " if len(get_synonyms(word)) >= 1:\n", + " list_words.append(word)\n", " \n", " except NoDataException:\n", " pass\n", @@ -249,7 +257,7 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -296,7 +304,134 @@ }, { "cell_type": "code", - "execution_count": 358, + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 68842/68842 [00:01<00:00, 50914.78it/s]\n" + ] + } + ], + "source": [ + "## store an optimized library version for production\n", + "optimized_lib = {}\n", + "for word in tqdm.tqdm(list_words):\n", + " item = {}\n", + " senses = None\n", + " antonyms = None\n", + " synonyms = None\n", + " try:\n", + " senses = get_senses(word)\n", + " except:\n", + " pass\n", + " try:\n", + " synonyms = get_synonyms(word)\n", + " except:\n", + " pass\n", + " try:\n", + " antonyms = get_antonyms(word)\n", + " except:\n", + " pass\n", + " \n", + " item['senses'] = senses\n", + " item['antonyms'] = antonyms\n", + " item['synonyms'] = synonyms\n", + " item['word'] = dictionary_database[word]['word']\n", + " optimized_lib[word] = item" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "with open(\"en.json\",'w') as f:\n", + " json.dump(optimized_lib, f, indent = 4)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[0;31mSignature:\u001b[0m\n", + "\u001b[0mjson\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdump\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mobj\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mfp\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mskipkeys\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mensure_ascii\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mcheck_circular\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mallow_nan\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mcls\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mindent\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mseparators\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0mdefault\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0msort_keys\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mFalse\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkw\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\n", + "\u001b[0;34m\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mDocstring:\u001b[0m\n", + "Serialize ``obj`` as a JSON formatted stream to ``fp`` (a\n", + "``.write()``-supporting file-like object).\n", + "\n", + "If ``skipkeys`` is true then ``dict`` keys that are not basic types\n", + "(``str``, ``int``, ``float``, ``bool``, ``None``) will be skipped\n", + "instead of raising a ``TypeError``.\n", + "\n", + "If ``ensure_ascii`` is false, then the strings written to ``fp`` can\n", + "contain non-ASCII characters if they appear in strings contained in\n", + "``obj``. Otherwise, all such characters are escaped in JSON strings.\n", + "\n", + "If ``check_circular`` is false, then the circular reference check\n", + "for container types will be skipped and a circular reference will\n", + "result in an ``OverflowError`` (or worse).\n", + "\n", + "If ``allow_nan`` is false, then it will be a ``ValueError`` to\n", + "serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)\n", + "in strict compliance of the JSON specification, instead of using the\n", + "JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).\n", + "\n", + "If ``indent`` is a non-negative integer, then JSON array elements and\n", + "object members will be pretty-printed with that indent level. An indent\n", + "level of 0 will only insert newlines. ``None`` is the most compact\n", + "representation.\n", + "\n", + "If specified, ``separators`` should be an ``(item_separator, key_separator)``\n", + "tuple. The default is ``(', ', ': ')`` if *indent* is ``None`` and\n", + "``(',', ': ')`` otherwise. To get the most compact JSON representation,\n", + "you should specify ``(',', ':')`` to eliminate whitespace.\n", + "\n", + "``default(obj)`` is a function that should return a serializable version\n", + "of obj or raise TypeError. The default simply raises TypeError.\n", + "\n", + "If *sort_keys* is true (default: ``False``), then the output of\n", + "dictionaries will be sorted by key.\n", + "\n", + "To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the\n", + "``.default()`` method to serialize additional types), specify it with\n", + "the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.\n", + "\u001b[0;31mFile:\u001b[0m /usr/lib/python3.9/json/__init__.py\n", + "\u001b[0;31mType:\u001b[0m function\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "?json.dump" + ] + }, + { + "cell_type": "code", + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -558,14 +693,35 @@ }, { "cell_type": "code", - "execution_count": 359, + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "ename": "NameError", + "evalue": "name '__file__' is not defined", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0m__file__\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;31mNameError\u001b[0m: name '__file__' is not defined" + ] + } + ], + "source": [ + "__file__\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "968\n" + "762\n" ] }, { @@ -573,33 +729,33 @@ "text/markdown": [ "| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |\n", "|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|\n", - "| | | | |**c**| |**a**|**e**|**r**|**o**|**p**|**h**|**o**|**b**|**i**|**c**| |**m**|**g**|**m**| |**f**|**a**|**d**|**d**|**y**| |**f**| | |**o**| |**c**| | |**g**|**r**|**a**|**y**| | | | |**q**|**u**|**a**|**y**| |\n", - "|**f**|**b**|**i**| |**l**| | | |**h**| | |**i**| |**f**| | | |**m**| | |**r**| |**c**| |**a**| | |**o**|**v**|**e**|**r**|**w**|**o**|**r**|**d**| |**p**| | |**t**| |**s**| |**u**| | | |**r**|\n", - "|**i**| | |**s**|**m**|**s**| | |**i**| | |**a**| | |**m**| | |**p**|**a**|**c**|**i**|**f**|**i**|**s**|**m**| | |**o**| |**x**| | |**m**| | |**p**|**a**|**i**|**g**|**e**| |**i**| |**a**| |**h**| |**e**|\n", - "|**g**|**l**|**e**|**e**| |**y**| |**c**|**a**|**r**|**o**|**t**|**e**|**n**|**o**|**l**| | | |**o**| | |**c**| | |**a**|**u**|**f**| |**p**|**o**|**p**|**p**|**l**|**e**| | |**m**| |**n**| |**l**| |**d**|**r**|**o**|**f**|**f**|\n", - "|**u**| | |**c**| |**m**| | |**n**| | |**t**| | |**r**| | |**d**|**o**|**g**|**g**|**i**|**l**|**y**| | | | |**s**| | | |**r**| | |**g**|**y**|**p**| |**t**| |**v**| |**r**| |**r**| |**a**|\n", - "|**r**| | |**o**|**r**|**p**|**h**|**a**|**n**|**r**|**y**| | | |**t**| |**e**| | |**n**| | |**e**| | | |**s**|**p**|**o**|**n**|**g**|**i**|**o**|**s**|**e**| | |**r**| | | |**e**| |**u**| |**s**| |**n**|\n", - "|**a**| | |**n**| |**t**| | |**o**| | | |**r**| |**a**|**f**|**r**|**o**|**d**|**i**|**t**|**e**| |**a**| |**a**| | |**l**| | | |**m**| | | |**c**|**o**|**l**| |**d**|**r**|**i**|**p**| |**e**| | |\n", - "|**l**| |**e**|**d**|**d**|**o**| | |**n**|**g**|**p**| |**y**| |**l**| |**v**| | |**z**| |**v**| |**m**| |**f**| | |**a**|**f**|**v**| |**i**| | | | |**p**| |**e**| |**i**| |**l**| |**l**| | |\n", - "| |**e**| |**e**| |**m**| |**s**| | | | |**n**| | |**n**| | |**w**|**a**|**g**|**e**|**n**|**b**|**o**|**o**|**m**| |**r**| |**a**|**r**|**s**|**e**|**w**|**i**|**p**|**e**| |**m**|**i**|**n**|**d**|**e**|**l**|**o**| |**u**|\n", - "|**u**|**l**|**l**|**r**| |**a**|**n**|**t**|**e**|**c**|**r**|**i**|**t**|**i**|**c**|**a**|**l**| | |**n**| |**n**| |**i**| |**u**| | |**y**| |**t**| |**e**| | |**m**| |**r**|**o**|**b**| |**g**| | | |**r**| |**n**|\n", - "| |**e**| | | |**t**| |**e**| |**r**| | | | | |**n**| |**p**| |**c**|**u**|**e**| |**t**| |**l**|**a**|**t**| |**m**| | | | | |**m**| | | |**r**| | |**t**| |**l**|**e**|**s**|**s**|\n", - "| |**c**|**u**|**r**|**r**|**i**|**e**|**r**| |**a**| |**o**|**x**|**a**|**z**|**o**|**l**|**i**|**n**|**e**| | | | |**w**| | | |**s**|**e**|**i**|**s**|**m**|**o**|**l**|**o**|**g**|**i**|**c**|**a**|**l**|**l**|**y**| | | | |**t**|\n", - "| |**t**| | | |**c**| |**c**| |**c**| | | | | |**m**| |**l**| | |**m**| |**s**| |**o**| | | |**h**| | |**c**| | | |**r**| | | |**i**| | |**p**| | | | |**i**|\n", - "|**c**|**r**|**a**|**m**|**p**| |**m**|**o**|**c**|**k**|**e**|**r**|**y**| |**a**|**a**|**a**|**e**| |**t**|**o**|**s**|**h**|**e**|**r**| |**r**|**h**|**a**|**p**|**s**|**o**|**d**|**i**|**s**|**t**|**i**|**c**| |**d**| |**p**|**a**|**p**|**p**|**y**| |**t**|\n", - "| |**e**| | | | | |**r**| |**i**| | | |**d**| |**c**| | | | |**g**| |**e**| |**m**| |**f**| | |**e**| | | | | |**a**| |**d**| | |**s**| |**l**| |**r**| |**o**|**c**|\n", - "| | |**d**|**m**| |**c**|**r**|**y**|**i**|**n**|**g**| |**p**|**u**|**s**|**h**|**b**|**a**|**l**|**l**| |**u**|**n**|**p**|**h**|**o**|**t**|**o**|**g**|**r**|**a**|**p**|**h**|**a**|**b**|**l**|**e**| |**m**| |**h**| | | |**i**| | |**h**|\n", - "| |**g**| |**u**| |**m**| | | |**g**| | | |**e**| |**i**| |**a**| | |**m**| |**a**| |**o**| | | | | |**a**| | |**l**| |**i**| | |**u**| |**e**|**s**|**k**|**i**|**m**|**o**| | |\n", - "| |**c**|**o**|**l**|**e**|**a**|**d**| | | | |**p**| | | |**n**| |**b**| | |**i**| |**n**| |**l**| |**u**|**n**|**v**|**i**|**s**|**u**|**a**|**l**|**i**|**z**|**a**|**b**|**l**|**e**| |**i**| | |**i**| | | |\n", - "| |**e**| |**t**| | | | | |**s**| |**l**|**e**|**t**|**t**|**e**|**r**| |**p**|**u**|**n**|**t**|**i**|**t**|**e**| | | | | | | |**d**| | |**e**| | |**t**| | |**m**| | |**g**| | | |\n", - "| | |**l**|**i**|**g**|**h**|**t**|**s**|**c**|**a**|**p**|**e**| | | |**r**| | | | | | |**g**| | | | |**c**|**t**|**c**| | |**s**|**i**|**e**| | |**l**|**a**|**m**|**b**|**a**|**s**|**t**|**e**|**d**| | |\n", - "| | | |**t**| | |**b**| | |**d**| |**a**| | |**p**|**y**|**r**|**a**|**z**|**o**|**l**|**e**|**a**|**m**|**i**|**d**|**e**| |**o**| |**f**| | | | | |**l**| |**n**| | | | | |**n**| | |**g**|\n", - "| | | |**h**| |**m**| |**b**| |**d**| |**d**| | |**a**| | | |**e**| | | |**n**| | |**r**| | |**i**| |**a**|**z**|**a**|**c**|**y**|**t**|**o**|**s**|**i**|**n**|**e**| | |**d**|**o**|**t**|**t**|**y**|\n", - "| | |**s**|**e**|**r**|**i**|**c**|**a**|**t**|**e**| |**i**| | |**l**| | | |**r**| |**n**| |**r**| | |**u**| | |**n**| |**w**| | | | | |**u**| |**m**| | | | | |**u**| | |**m**|\n", - "| |**j**| |**i**| |**n**| |**n**| |**n**| |**n**| |**d**|**e**|**p**|**o**|**s**|**i**|**t**|**a**|**r**|**y**| | |**m**|**o**|**r**|**g**|**e**|**n**| |**c**|**a**|**i**|**r**|**n**|**g**|**o**|**r**|**m**|**s**| | |**s**|**k**|**i**|**n**|\n", - "| |**o**| |**s**| |**y**| |**d**| | | |**g**| | | | |**u**| |**b**| |**i**| | |**r**| |**b**| |**a**| |**d**| |**v**| |**m**| | | | |**u**| | |**u**| |**r**| |**o**| |**i**|\n", - "| |**h**|**a**|**m**|**f**|**a**|**t**| |**c**|**y**|**c**|**l**|**o**|**p**|**a**|**e**|**d**|**i**|**a**| |**r**| |**c**|**o**|**l**|**l**|**a**|**r**| |**e**| |**h**|**e**|**a**|**d**|**h**|**o**|**u**|**s**|**e**| |**r**|**c**|**s**| |**k**| |**c**|\n", - "| |**n**| | | |**n**| | | | | |**y**| | | | | |**t**| |**t**|**a**|**u**| |**e**| |**e**| |**e**| |**n**| |**d**| |**r**| | | | | | | |**e**| |**o**| |**o**| | |\n" + "| | | | | |**d**|**e**|**n**|**s**|**i**|**t**|**o**|**m**|**e**|**t**|**e**|**r**| | |**h**| | |**z**| | | |**h**|**a**|**m**|**m**|**e**|**r**|**s**| | |**p**|**p**|**l**| | | | |**d**| |**h**|**a**|**w**|**k**|\n", + "| | | |**v**| | | |**o**| | | | | |**x**| | |**m**| |**w**|**o**|**r**|**k**|**e**|**r**|**y**| | |**u**| | | | | | |**d**| |**e**| |**t**|**e**|**n**|**o**|**u**|**s**| |**m**| | |\n", + "| | |**m**|**a**|**s**|**l**|**e**|**n**|**i**|**t**|**s**|**a**| | | | | | | |**i**| | |**k**| | | |**f**|**r**|**e**|**e**| |**c**|**u**|**m**|**m**|**e**|**r**| | |**c**| | |**f**| | |**i**| |**m**|\n", + "| | | |**g**| | | |**i**| |**h**| | |**c**| | |**p**|**l**|**e**|**c**|**t**|**i**|**l**|**e**| | |**d**| |**e**| | |**p**| |**n**| |**v**| |**u**| |**s**|**t**|**a**|**m**|**f**|**o**|**r**|**d**| |**r**|\n", + "| | | |**u**|**l**|**c**|**e**|**r**|**o**|**u**|**s**| |**o**| |**i**| |**i**| |**o**| | | | |**c**| |**a**|**j**|**o**|**g**| |**a**| |**j**| | | |**s**| | |**h**| | | | | |**s**|**e**|**t**|\n", + "| |**d**|**u**|**e**| | | |**r**| |**s**| |**a**|**m**|**e**|**n**| |**q**| |**i**| |**p**|**i**|**l**|**l**|**a**|**r**| |**l**| | |**n**| |**o**| | |**r**|**a**|**d**|**c**|**l**|**i**|**f**|**f**|**e**| |**t**| | |\n", + "| |**e**| | | |**b**| |**i**| | |**h**| |**m**| |**c**| |**u**| |**n**| |**o**| | |**a**| |**t**| |**e**| | |**t**| |**c**| |**a**| |**l**| | |**i**| | |**a**| |**l**| |**i**| |\n", + "| |**c**|**o**|**n**|**s**|**u**|**l**|**t**|**i**|**v**|**e**| |**e**|**x**|**o**|**t**|**i**|**c**| |**b**|**l**|**n**| |**d**| |**o**| | |**v**| |**s**|**q**|**u**|**a**|**s**|**h**| |**k**|**i**|**p**| | |**n**| |**i**| |**n**| |\n", + "|**m**|**i**| | | |**t**| |**a**| | |**x**| |**a**| |**n**| |**d**| | | |**y**| |**c**| |**w**|**i**|**t**|**h**|**e**| | | |**l**| |**t**| | | | |**s**| |**s**|**t**|**e**|**m**| |**s**| |\n", + "| |**d**| |**u**| |**t**|**u**|**t**| |**o**| | |**s**| |**s**| |**a**| |**s**| |**s**| |**r**|**x**| |**d**| | |**g**|**g**| | |**a**| | |**e**| |**b**| |**i**| | |**o**| |**n**| |**u**| |\n", + "| |**a**| |**p**| |**r**| |**i**|**n**|**s**|**t**|**r**|**u**|**m**|**e**|**n**|**t**|**a**|**l**|**l**|**y**| |**y**| | | | | |**i**| |**p**|**a**|**r**|**v**|**o**|**v**|**i**|**r**|**u**|**s**| | |**d**| |**e**|**o**|**f**| |\n", + "| |**b**|**a**|**w**|**n**|**e**|**e**|**n**| |**t**| | |**r**| |**q**| |**i**| |**i**| |**n**| |**s**|**h**|**r**|**o**|**u**|**d**|**e**|**d**| |**m**| |**a**| |**p**| |**i**| | | |**m**| | |**m**| |**f**| |\n", + "| |**l**| |**i**| |**s**| |**g**|**a**|**r**|**b**| |**a**| |**u**| |**o**| |**c**|**a**|**o**| |**t**| |**f**| | | | | |**s**|**h**|**a**|**r**|**p**| |**i**|**n**|**a**|**c**|**c**|**e**|**s**|**s**|**i**|**b**|**l**|**e**|\n", + "| |**e**| |**n**| |**s**| | | |**a**| | |**b**|**e**|**e**| |**n**| |**k**| |**d**| |**a**| |**s**| |**c**| |**s**| | |**e**| | |**w**| | |**e**| |**s**| |**t**| | |**c**| |**a**| |\n", + "| | |**e**|**g**|**g**| | |**r**|**i**|**c**|**h**| |**l**| |**n**|**p**| |**p**|**i**| |**y**|**e**|**l**|**l**| |**j**|**o**|**i**|**n**|**d**|**e**|**r**| | | |**s**| | | |**s**| |**a**| |**c**| | |**t**| |\n", + "| |**t**| | | | |**f**| | |**i**| | |**e**| |**t**| |**b**| |**n**| | | |**l**| |**p**| |**n**| |**i**| | |**s**| |**o**| |**t**| | |**u**| |**a**|**l**|**p**|**h**|**a**|**b**|**e**|**t**|\n", + "| |**y**| | |**b**|**a**|**l**|**m**|**l**|**i**|**k**|**e**| |**a**| | |**u**|**n**|**g**|**l**|**a**|**m**|**o**|**r**|**o**|**u**|**s**| |**t**| | |**t**| |**s**|**o**|**f**|**a**| |**n**| | |**l**| |**i**| | | |**e**|\n", + "| |**r**| | |**u**| |**c**| | |**f**| |**v**| |**k**| | |**l**| | | | | |**g**| |**o**| |**o**| | |**c**| | | |**c**| |**u**| | |**c**|**l**|**a**|**y**| |**l**|**e**|**o**|**l**|**a**|\n", + "|**s**|**o**|**d**| |**r**| | |**g**|**e**|**o**|**d**|**e**|**t**|**i**|**c**|**a**|**l**| | | |**w**| |**e**| |**r**| |**l**| |**p**|**o**|**i**|**n**|**t**|**e**| | |**w**| |**u**| | | | |**i**| | |**o**| |\n", + "|**k**| |**o**| |**p**|**l**| | | |**r**| |**n**| | | |**p**| | |**b**|**g**|**a**| |**n**| | |**s**|**i**|**c**| |**n**| | | |**o**| | |**r**| |**t**| | |**d**|**o**|**a**|**t**|**i**|**n**|**g**|\n", + "|**i**| |**w**| | | | |**s**|**i**|**m**| | |**n**|**a**|**g**|**p**|**u**|**r**| | |**l**| | |**w**| | |**d**| | |**t**| |**w**|**i**|**l**|**d**|**f**|**i**|**r**|**e**| |**e**| | |**s**| | |**g**| |\n", + "|**r**| |**n**| | |**f**|**d**|**m**| | |**p**|**s**| | | |**e**| | | | |**d**|**e**|**v**|**a**|**s**|**t**|**a**|**t**|**i**|**o**|**n**| | |**a**| | |**g**| | |**b**|**l**|**o**|**o**|**t**|**h**| |**v**| |\n", + "|**r**|**e**|**s**|**e**|**t**| | |**e**| | |**i**| | | | |**r**|**o**|**u**|**p**| |**r**| | |**t**| | |**t**| | |**r**| | | | |**p**|**i**|**g**|**g**|**y**| |**s**| | | |**d**| |**i**| |\n", + "| | |**t**| |**i**| |**c**|**a**|**p**|**i**|**t**|**a**|**l**|**i**|**s**|**t**| | |**r**| |**o**| | |**t**| |**b**|**e**|**a**|**s**|**t**| | | |**h**| | |**l**| | | |**e**|**n**|**r**|**o**|**l**|**l**|**e**|**d**|\n", + "|**m**|**e**|**a**|**s**|**l**|**y**| |**t**| | |**k**| | |**d**| |**a**|**l**|**l**|**y**| |**n**|**c**| |**l**| |**e**| | |**o**| |**m**| |**w**|**a**|**n**|**t**|**e**|**d**| | | | |**a**| | | |**w**| |\n", + "|**e**| |**g**| |**l**| | |**o**| |**p**|**i**|**p**| |**p**| |**i**| | | | | | | |**e**| |**n**| | |**p**| |**s**| | |**n**| | |**r**| | | |**a**| |**c**| | | | | |\n", + "| |**k**|**e**|**y**|**p**|**o**|**i**|**n**|**t**| |**n**| |**g**|**r**|**a**|**n**|**d**|**f**|**a**|**t**|**h**|**e**|**r**|**l**|**y**| | |**w**|**a**|**r**|**b**|**i**|**r**|**d**| | | | | | |**c**|**l**|**e**|**a**|**n**| | | |\n" ], "text/plain": [ "" @@ -607,245 +763,10 @@ }, "metadata": {}, "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - " " - ] - }, - { - "data": { - "text/plain": [ - " 854104 function calls (854099 primitive calls) in 0.447 seconds\n", - "\n", - " Ordered by: internal time\n", - "\n", - " ncalls tottime percall cumtime percall filename:lineno(function)\n", - " 385008 0.289 0.000 0.306 0.000 :111(check_if_fits)\n", - " 968 0.072 0.000 0.383 0.000 :174(get_crossover)\n", - " 395346 0.018 0.000 0.018 0.000 {built-in method builtins.len}\n", - " 969 0.017 0.000 0.027 0.000 :106(density)\n", - " 969 0.008 0.000 0.008 0.000 {method 'reduce' of 'numpy.ufunc' objects}\n", - " 973 0.007 0.000 0.016 0.000 :72(get_word)\n", - " 1 0.005 0.005 0.444 0.444 :54(create_word_grid)\n", - " 9573 0.005 0.000 0.007 0.000 random.py:238(_randbelow_with_getrandbits)\n", - " 5549 0.003 0.000 0.007 0.000 random.py:291(randrange)\n", - " 968 0.002 0.000 0.005 0.000 random.py:349(shuffle)\n", - " 1123 0.002 0.000 0.002 0.000 {method 'sub' of 're.Pattern' objects}\n", - " 17858 0.002 0.000 0.002 0.000 {method 'getrandbits' of '_random.Random' objects}\n", - " 5549 0.002 0.000 0.009 0.000 random.py:335(randint)\n", - " 162 0.001 0.000 0.005 0.000 :1(filter_senses)\n", - " 162 0.001 0.000 0.010 0.000 :88(place_word)\n", - " 1134 0.001 0.000 0.001 0.000 {method 'translate' of 'str' objects}\n", - " 18 0.001 0.000 0.001 0.000 {method 'acquire' of '_thread.lock' objects}\n", - " 9573 0.001 0.000 0.001 0.000 {method 'bit_length' of 'int' objects}\n", - " 922 0.001 0.000 0.001 0.000 :61(store_location)\n", - " 969 0.001 0.000 0.009 0.000 {method 'sum' of 'numpy.ndarray' objects}\n", - " 1134 0.001 0.000 0.002 0.000 :84(normalize_word)\n", - " 974 0.001 0.000 0.001 0.000 {built-in method builtins.min}\n", - " 1092 0.001 0.000 0.001 0.000 re.py:289(_compile)\n", - " 27 0.001 0.000 0.001 0.000 :9()\n", - " 1092 0.001 0.000 0.003 0.000 re.py:203(sub)\n", - " 162 0.000 0.000 0.007 0.000 :28(choose_info)\n", - " 973 0.000 0.000 0.000 0.000 {built-in method builtins.max}\n", - " 486 0.000 0.000 0.000 0.000 :4(get_attribute)\n", - " 969 0.000 0.000 0.009 0.000 _methods.py:45(_sum)\n", - " 1 0.000 0.000 0.447 0.447 {built-in method builtins.exec}\n", - " 1229 0.000 0.000 0.000 0.000 {built-in method builtins.isinstance}\n", - " 162 0.000 0.000 0.008 0.000 :6(__init__)\n", - " 162 0.000 0.000 0.001 0.000 :16(get_best_antonym)\n", - " 1083 0.000 0.000 0.000 0.000 {method 'isalnum' of 'str' objects}\n", - " 162 0.000 0.000 0.006 0.000 :24(get_best_sense)\n", - " 1134 0.000 0.000 0.000 0.000 {method 'lower' of 'str' objects}\n", - " 1542 0.000 0.000 0.000 0.000 {method 'append' of 'list' objects}\n", - " 548 0.000 0.000 0.000 0.000 {method 'replace' of 'str' objects}\n", - " 162 0.000 0.000 0.006 0.000 :12(get_senses)\n", - " 424 0.000 0.000 0.000 0.000 {method 'split' of 'str' objects}\n", - " 188 0.000 0.000 0.000 0.000 random.py:344(choice)\n", - " 162 0.000 0.000 0.000 0.000 :23(get_antonyms)\n", - " 546 0.000 0.000 0.000 0.000 {method 'strip' of 'str' objects}\n", - " 162 0.000 0.000 0.000 0.000 :20(get_best_synonym)\n", - " 162 0.000 0.000 0.000 0.000 :18(get_synonyms)\n", - " 12 0.000 0.000 0.000 0.000 inspect.py:2926(_bind)\n", - " 8 0.000 0.000 0.000 0.000 socket.py:438(send)\n", - " 155 0.000 0.000 0.000 0.000 traitlets.py:564(__get__)\n", - " 1 0.000 0.000 0.446 0.446 :1()\n", - " 11 0.000 0.000 0.000 0.000 formatters.py:397(lookup_by_type)\n", - " 1 0.000 0.000 0.001 0.001 :2(grid2mdown)\n", - " 155 0.000 0.000 0.000 0.000 traitlets.py:533(get)\n", - " 4 0.000 0.000 0.000 0.000 encoder.py:304(iterencode)\n", - " 6/1 0.000 0.000 0.000 0.000 jsonutil.py:73(json_clean)\n", - " 21 0.000 0.000 0.000 0.000 :1(filter_synonyms)\n", - " 5 0.000 0.000 0.000 0.000 {method 'update' of '_hashlib.HASH' objects}\n", - " 44 0.000 0.000 0.000 0.000 formatters.py:550(_in_deferred_types)\n", - " 1 0.000 0.000 0.001 0.001 formatters.py:89(format)\n", - " 12 0.000 0.000 0.000 0.000 inspect.py:2665(args)\n", - " 12 0.000 0.000 0.000 0.000 inspect.py:2718(apply_defaults)\n", - " 12 0.000 0.000 0.000 0.000 decorator.py:199(fix)\n", - " 8 0.000 0.000 0.000 0.000 iostream.py:195(schedule)\n", - " 1 0.000 0.000 0.000 0.000 {built-in method numpy.core._multiarray_umath.implement_array_function}\n", - " 129 0.000 0.000 0.000 0.000 {built-in method builtins.getattr}\n", - " 1 0.000 0.000 0.000 0.000 {built-in method numpy.empty}\n", - " 1 0.000 0.000 0.002 0.002 display.py:131(display)\n", - " 11 0.000 0.000 0.000 0.000 formatters.py:374(lookup)\n", - " 9 0.000 0.000 0.000 0.000 formatters.py:331(__call__)\n", - " 31 0.000 0.000 0.000 0.000 encoder.py:38(encode_basestring)\n", - " 12 0.000 0.000 0.001 0.000 decorator.py:229(fun)\n", - " 12 0.000 0.000 0.000 0.000 inspect.py:2688(kwargs)\n", - " 12 0.000 0.000 0.000 0.000 formatters.py:220(catch_format_error)\n", - " 1 0.000 0.000 0.001 0.001 zmqshell.py:97(publish)\n", - " 2 0.000 0.000 0.001 0.000 iostream.py:335(flush)\n", - " 1 0.000 0.000 0.000 0.000 {built-in method posix.stat}\n", - " 33 0.000 0.000 0.000 0.000 {method 'join' of 'str' objects}\n", - " 11 0.000 0.000 0.000 0.000 dir2.py:54(get_real_method)\n", - " 74 0.000 0.000 0.000 0.000 {built-in method builtins.next}\n", - " 1 0.000 0.000 0.000 0.000 pretty.py:356(pretty)\n", - " 134 0.000 0.000 0.000 0.000 inspect.py:2577(kind)\n", - " 4 0.000 0.000 0.000 0.000 __init__.py:294(dumps)\n", - " 10 0.000 0.000 0.000 0.000 threading.py:1093(is_alive)\n", - " 2 0.000 0.000 0.000 0.000 iostream.py:384(write)\n", - " 1 0.000 0.000 0.000 0.000 session.py:662(send)\n", - " 1 0.000 0.000 0.000 0.000 formatters.py:689(__call__)\n", - " 12 0.000 0.000 0.000 0.000 {method 'format' of 'str' objects}\n", - " 1 0.000 0.000 0.000 0.000 numeric.py:268(full)\n", - " 2 0.000 0.000 0.000 0.000 {method 'isoformat' of 'datetime.datetime' objects}\n", - " 4 0.000 0.000 0.000 0.000 jsonapi.py:32(dumps)\n", - " 2 0.000 0.000 0.001 0.000 threading.py:280(wait)\n", - " 2 0.000 0.000 0.000 0.000 threading.py:228(__init__)\n", - " 1 0.000 0.000 0.000 0.000 session.py:603(serialize)\n", - " 1 0.000 0.000 0.001 0.001 display.py:81(publish_display_data)\n", - " 4 0.000 0.000 0.000 0.000 encoder.py:275(encode)\n", - " 1 0.000 0.000 0.000 0.000 pretty.py:697(_repr_pprint)\n", - " 29 0.000 0.000 0.000 0.000 encoder.py:60(replace)\n", - " 1 0.000 0.000 0.000 0.000 <__array_function__ internals>:2(copyto)\n", - " 1 0.000 0.000 0.000 0.000 hmac.py:115(copy)\n", - " 1 0.000 0.000 0.000 0.000 pretty.py:185(__init__)\n", - " 1 0.000 0.000 0.000 0.000 display.py:591(__init__)\n", - " 10 0.000 0.000 0.000 0.000 threading.py:1039(_wait_for_tstate_lock)\n", - " 12 0.000 0.000 0.000 0.000 inspect.py:3057(bind)\n", - " 4 0.000 0.000 0.000 0.000 encoder.py:141(__init__)\n", - " 5 0.000 0.000 0.000 0.000 :1(filter_antonyms)\n", - " 48 0.000 0.000 0.000 0.000 inspect.py:2882(parameters)\n", - " 12 0.000 0.000 0.000 0.000 abc.py:96(__instancecheck__)\n", - " 12 0.000 0.000 0.000 0.000 {built-in method _abc._abc_instancecheck}\n", - " 8 0.000 0.000 0.000 0.000 iostream.py:91(_event_pipe)\n", - " 22 0.000 0.000 0.000 0.000 {built-in method builtins.hasattr}\n", - " 2 0.000 0.000 0.001 0.000 threading.py:556(wait)\n", - " 1 0.000 0.000 0.000 0.000 {built-in method builtins.print}\n", - " 1 0.000 0.000 0.000 0.000 session.py:588(sign)\n", - " 1 0.000 0.000 0.001 0.001 zmqshell.py:80(_flush_streams)\n", - " 51 0.000 0.000 0.000 0.000 inspect.py:2565(name)\n", - " 36 0.000 0.000 0.000 0.000 {method 'items' of 'mappingproxy' objects}\n", - " 12 0.000 0.000 0.000 0.000 pretty.py:305(_get_mro)\n", - " 12 0.000 0.000 0.000 0.000 inspect.py:2657(__init__)\n", - " 11 0.000 0.000 0.000 0.000 formatters.py:274(_get_type)\n", - " 1 0.000 0.000 0.000 0.000 formatters.py:903(__call__)\n", - " 2 0.000 0.000 0.000 0.000 threading.py:521(__init__)\n", - " 24 0.000 0.000 0.000 0.000 {built-in method builtins.iter}\n", - " 1 0.000 0.000 0.000 0.000 session.py:149(utcnow)\n", - " 3 0.000 0.000 0.000 0.000 pretty.py:479(enq)\n", - " 12 0.000 0.000 0.000 0.000 {method 'values' of 'mappingproxy' objects}\n", - " 4 0.000 0.000 0.000 0.000 session.py:82()\n", - " 2 0.000 0.000 0.000 0.000 jsonutil.py:84(date_default)\n", - " 1 0.000 0.000 0.000 0.000 session.py:569(msg)\n", - " 1 0.000 0.000 0.000 0.000 contextlib.py:86(__init__)\n", - " 2 0.000 0.000 0.000 0.000 threading.py:259(__exit__)\n", - " 2 0.000 0.000 0.000 0.000 iostream.py:308(_is_master_process)\n", - " 2 0.000 0.000 0.000 0.000 pretty.py:264(begin_group)\n", - " 2 0.000 0.000 0.000 0.000 pretty.py:288(end_group)\n", - " 11 0.000 0.000 0.000 0.000 inspect.py:73(isclass)\n", - " 4 0.000 0.000 0.000 0.000 hmac.py:111(update)\n", - " 1 0.000 0.000 0.000 0.000 genericpath.py:16(exists)\n", - " 29 0.000 0.000 0.000 0.000 {method 'group' of 're.Match' objects}\n", - " 1 0.000 0.000 0.000 0.000 pretty.py:216(text)\n", - " 3 0.000 0.000 0.000 0.000 {method 'copy' of '_hashlib.HASH' objects}\n", - " 11 0.000 0.000 0.000 0.000 formatters.py:359(_check_return)\n", - " 1 0.000 0.000 0.000 0.000 {method 'replace' of 'datetime.datetime' objects}\n", - " 1 0.000 0.000 0.000 0.000 formatters.py:949(__call__)\n", - " 1 0.000 0.000 0.000 0.000 pretty.py:339(__init__)\n", - " 3 0.000 0.000 0.000 0.000 pretty.py:466(__init__)\n", - " 12 0.000 0.000 0.000 0.000 {built-in method builtins.id}\n", - " 1 0.000 0.000 0.000 0.000 {built-in method maketrans}\n", - " 3 0.000 0.000 0.000 0.000 pretty.py:401(_in_deferred_types)\n", - " 1 0.000 0.000 0.000 0.000 display.py:34(_safe_exists)\n", - " 1 0.000 0.000 0.000 0.000 session.py:566(msg_header)\n", - " 1 0.000 0.000 0.000 0.000 zmqshell.py:90(_hooks)\n", - " 10 0.000 0.000 0.000 0.000 threading.py:529(is_set)\n", - " 1 0.000 0.000 0.000 0.000 hmac.py:128(_current)\n", - " 2 0.000 0.000 0.000 0.000 threading.py:256(__enter__)\n", - " 1 0.000 0.000 0.000 0.000 pretty.py:297(flush)\n", - " 1 0.000 0.000 0.000 0.000 contextlib.py:242(helper)\n", - " 1 0.000 0.000 0.000 0.000 iostream.py:260(send_multipart)\n", - " 1 0.000 0.000 0.000 0.000 configurable.py:551(initialized)\n", - " 5 0.000 0.000 0.000 0.000 {method 'encode' of 'str' objects}\n", - " 1 0.000 0.000 0.000 0.000 display.py:640(__repr__)\n", - " 2 0.000 0.000 0.000 0.000 threading.py:268(_acquire_restore)\n", - " 1 0.000 0.000 0.000 0.000 formatters.py:940(_check_return)\n", - " 2 0.000 0.000 0.000 0.000 pretty.py:168(group)\n", - " 14 0.000 0.000 0.000 0.000 {built-in method builtins.callable}\n", - " 1 0.000 0.000 0.000 0.000 session.py:224(extract_header)\n", - " 1 0.000 0.000 0.000 0.000 displaypub.py:43(_validate_data)\n", - " 1 0.000 0.000 0.000 0.000 session.py:513(msg_id)\n", - " 7 0.000 0.000 0.000 0.000 pretty.py:102(_safe_getattr)\n", - " 3 0.000 0.000 0.000 0.000 {built-in method posix.getpid}\n", - " 2 0.000 0.000 0.000 0.000 configurable.py:507(instance)\n", - " 1 0.000 0.000 0.000 0.000 session.py:744()\n", - " 2 0.000 0.000 0.000 0.000 iostream.py:321(_schedule_flush)\n", - " 2 0.000 0.000 0.000 0.000 pretty.py:496(remove)\n", - " 2 0.000 0.000 0.000 0.000 threading.py:265(_release_save)\n", - " 10 0.000 0.000 0.000 0.000 {method 'append' of 'collections.deque' objects}\n", - " 1 0.000 0.000 0.000 0.000 hmac.py:147(hexdigest)\n", - " 1 0.000 0.000 0.000 0.000 session.py:218(msg_header)\n", - " 1 0.000 0.000 0.000 0.000 {built-in method builtins.repr}\n", - " 1 0.000 0.000 0.000 0.000 contextlib.py:121(__exit__)\n", - " 1 0.000 0.000 0.000 0.000 pretty.py:474(__init__)\n", - " 1 0.000 0.000 0.000 0.000 contextlib.py:112(__enter__)\n", - " 4 0.000 0.000 0.000 0.000 {built-in method _thread.allocate_lock}\n", - " 5 0.000 0.000 0.000 0.000 {method 'items' of 'dict' objects}\n", - " 1 0.000 0.000 0.000 0.000 {method 'digest' of '_hashlib.HASH' objects}\n", - " 1 0.000 0.000 0.000 0.000 display.py:741(_repr_markdown_)\n", - " 4 0.000 0.000 0.000 0.000 {method 'clear' of 'dict' objects}\n", - " 2 0.000 0.000 0.000 0.000 jsonutil.py:31(_ensure_tzinfo)\n", - " 1 0.000 0.000 0.000 0.000 {built-in method utcnow}\n", - " 3 0.000 0.000 0.000 0.000 {method 'get' of 'mappingproxy' objects}\n", - " 2 0.000 0.000 0.000 0.000 threading.py:271(_is_owned)\n", - " 1 0.000 0.000 0.000 0.000 display.py:659(reload)\n", - " 1 0.000 0.000 0.000 0.000 multiarray.py:1043(copyto)\n", - " 1 0.000 0.000 0.000 0.000 iostream.py:207(send_multipart)\n", - " 1 0.000 0.000 0.000 0.000 {built-in method builtins.locals}\n", - " 2 0.000 0.000 0.000 0.000 {method 'remove' of 'list' objects}\n", - " 1 0.000 0.000 0.000 0.000 {method 'hexdigest' of '_hashlib.HASH' objects}\n", - " 3 0.000 0.000 0.000 0.000 {method 'pop' of 'list' objects}\n", - " 1 0.000 0.000 0.000 0.000 display.py:652(_data_and_metadata)\n", - " 1 0.000 0.000 0.000 0.000 {method 'splitlines' of 'str' objects}\n", - " 3 0.000 0.000 0.000 0.000 {method 'get' of 'dict' objects}\n", - " 4 0.000 0.000 0.000 0.000 {method 'pop' of 'dict' objects}\n", - " 1 0.000 0.000 0.000 0.000 display.py:698(_check_data)\n", - " 2 0.000 0.000 0.000 0.000 {built-in method _imp.lock_held}\n", - " 2 0.000 0.000 0.000 0.000 {method '__enter__' of '_thread.lock' objects}\n", - " 1 0.000 0.000 0.000 0.000 {built-in method __new__ of type object at 0x90efa0}\n", - " 2 0.000 0.000 0.000 0.000 {method 'release' of '_thread.lock' objects}\n", - " 1 0.000 0.000 0.000 0.000 {method 'getvalue' of '_io.StringIO' objects}\n", - " 2 0.000 0.000 0.000 0.000 {method '__exit__' of '_thread.lock' objects}\n", - " 1 0.000 0.000 0.000 0.000 {method 'startswith' of 'str' objects}\n", - " 1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}\n", - " 1 0.000 0.000 0.000 0.000 {method 'write' of '_io.StringIO' objects}\n", - " 2 0.000 0.000 0.000 0.000 {method 'extend' of 'list' objects}\n", - " 1 0.000 0.000 0.000 0.000 {method 'clear' of 'collections.deque' objects}\n", - " 1 0.000 0.000 0.000 0.000 jsonutil.py:46(encode_images)\n", - " 1 0.000 0.000 0.000 0.000 formatters.py:824(_check_return)\n", - " 1 0.000 0.000 0.000 0.000 tz.py:74(utcoffset)\n", - " 1 0.000 0.000 0.000 0.000 {method 'copy' of 'dict' objects}" - ] - }, - "metadata": {}, - "output_type": "display_data" } ], "source": [ - "%%prun\n", + "#%%prun\n", "gr, infos = create_word_grid(16*3,9*3, target_density=0.55)\n", "def grid2mdown(grid):\n", " h,w = grid.shape\n", @@ -925,7 +846,7 @@ }, { "cell_type": "code", - "execution_count": 374, + "execution_count": 30, "metadata": {}, "outputs": [], "source": [ @@ -1054,14 +975,14 @@ }, { "cell_type": "code", - "execution_count": 375, + "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "234\n" + "209\n" ] } ], @@ -1069,6 +990,1396 @@ "cw = Crossword(16*3, 9*3, english_vocab_db)" ] }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[[<__main__.HintField at 0x7f207d65a820>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.HintField at 0x7f207d64a280>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.HintField at 0x7f207ef54eb0>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>,\n", + " <__main__.Field at 0x7f207eadd460>],\n", + " [<__main__.Field at 0x7f207eadd100>,\n", + " <__main__.Field at 0x7f207eadd4f0>,\n", + " <__main__.LetterField at 0x7f207eadd580>,\n", + " <__main__.LetterField at 0x7f207ed42970>,\n", + " <__main__.LetterField at 0x7f207ed42790>,\n", + " <__main__.LetterField at 0x7f207ed42130>,\n", + " <__main__.Field at 0x7f207ed42190>,\n", + " <__main__.Field at 0x7f207ed42370>,\n", + " <__main__.Field at 0x7f207ed423a0>,\n", + " <__main__.LetterField at 0x7f207ed42160>,\n", + " <__main__.LetterField at 0x7f207ed42610>,\n", + " <__main__.LetterField at 0x7f207ed42490>,\n", + " <__main__.LetterField at 0x7f207ed42670>,\n", + " <__main__.LetterField at 0x7f207ed42a90>,\n", + " <__main__.HintField at 0x7f207ef5dee0>,\n", + " <__main__.LetterField at 0x7f207ed42ac0>,\n", + " <__main__.Field at 0x7f207ed427f0>,\n", + " <__main__.Field at 0x7f207ed42dc0>,\n", + " <__main__.Field at 0x7f207ed42be0>,\n", + " <__main__.Field at 0x7f207ed429d0>,\n", + " <__main__.Field at 0x7f207ed42f10>,\n", + " <__main__.HintField at 0x7f207ebfc6a0>,\n", + " <__main__.Field at 0x7f207ed42a00>,\n", + " <__main__.LetterField at 0x7f207ed424f0>,\n", + " <__main__.LetterField at 0x7f207ed42520>,\n", + " <__main__.LetterField at 0x7f207ed42d60>,\n", + " <__main__.LetterField at 0x7f207ed42c10>,\n", + " <__main__.LetterField at 0x7f207ed42f40>,\n", + " <__main__.LetterField at 0x7f207ec58e80>,\n", + " <__main__.LetterField at 0x7f207ec58f10>,\n", + " <__main__.HintField at 0x7f207d6484c0>,\n", + " <__main__.HintField at 0x7f207d665fa0>,\n", + " <__main__.Field at 0x7f207ec58e20>,\n", + " <__main__.HintField at 0x7f207d65fb80>,\n", + " <__main__.Field at 0x7f207ec58c70>,\n", + " <__main__.Field at 0x7f207ec58df0>,\n", + " <__main__.Field at 0x7f207ec58b20>,\n", + " <__main__.LetterField at 0x7f207ec58bb0>,\n", + " <__main__.Field at 0x7f207ec58a90>,\n", + " <__main__.HintField at 0x7f207ed5a910>,\n", + " <__main__.Field at 0x7f207ec58b80>,\n", + " <__main__.LetterField at 0x7f207ec58b50>,\n", + " <__main__.Field at 0x7f207ec58d00>,\n", + " <__main__.Field at 0x7f207ec58c40>,\n", + " <__main__.Field at 0x7f207ec588e0>,\n", + " <__main__.Field at 0x7f207ec587c0>,\n", + " <__main__.Field at 0x7f207ec58700>,\n", + " <__main__.Field at 0x7f207ec58790>,\n", + " <__main__.Field at 0x7f207ec58940>],\n", + " [<__main__.Field at 0x7f207eadd0a0>,\n", + " <__main__.Field at 0x7f207ec58760>,\n", + " <__main__.LetterField at 0x7f207ec58dc0>,\n", + " <__main__.LetterField at 0x7f207ebfcdc0>,\n", + " <__main__.LetterField at 0x7f207ebfc1f0>,\n", + " <__main__.LetterField at 0x7f207ebfc790>,\n", + " <__main__.LetterField at 0x7f207ebfc280>,\n", + " <__main__.LetterField at 0x7f207ebfc760>,\n", + " <__main__.Field at 0x7f207ebfc5b0>,\n", + " <__main__.HintField at 0x7f207d66fb80>,\n", + " <__main__.Field at 0x7f207ebfc220>,\n", + " <__main__.LetterField at 0x7f207ebfc910>,\n", + " <__main__.LetterField at 0x7f207ebfce80>,\n", + " <__main__.LetterField at 0x7f207ebfcac0>,\n", + " <__main__.LetterField at 0x7f207ebfc100>,\n", + " <__main__.LetterField at 0x7f207ebfceb0>,\n", + " <__main__.LetterField at 0x7f207ebfc4c0>,\n", + " <__main__.LetterField at 0x7f207ebfca00>,\n", + " <__main__.LetterField at 0x7f207ebfcfa0>,\n", + " <__main__.HintField at 0x7f207ebe9250>,\n", + " <__main__.Field at 0x7f207ebfc190>,\n", + " <__main__.Field at 0x7f207ebfc850>,\n", + " <__main__.Field at 0x7f207ebfc8b0>,\n", + " <__main__.Field at 0x7f207ebfccd0>,\n", + " <__main__.LetterField at 0x7f207ebfcd00>,\n", + " <__main__.Field at 0x7f207ebfcca0>,\n", + " <__main__.LetterField at 0x7f207ebfcc10>,\n", + " <__main__.Field at 0x7f207ebfc130>,\n", + " <__main__.Field at 0x7f207ebfcee0>,\n", + " <__main__.LetterField at 0x7f207ebfce50>,\n", + " <__main__.Field at 0x7f207ebfce20>,\n", + " <__main__.LetterField at 0x7f207ebfcf40>,\n", + " <__main__.Field at 0x7f207ebfc880>,\n", + " <__main__.Field at 0x7f207ebfc040>,\n", + " <__main__.LetterField at 0x7f207ebfcd60>,\n", + " <__main__.Field at 0x7f207ebfc970>,\n", + " <__main__.Field at 0x7f207ebfcdf0>,\n", + " <__main__.Field at 0x7f207ed5a880>,\n", + " <__main__.HintField at 0x7f207d66fc40>,\n", + " <__main__.LetterField at 0x7f207f13f0d0>,\n", + " <__main__.LetterField at 0x7f207f13f610>,\n", + " <__main__.LetterField at 0x7f207f13f0a0>,\n", + " <__main__.LetterField at 0x7f207ec74100>,\n", + " <__main__.LetterField at 0x7f207ec740d0>,\n", + " <__main__.LetterField at 0x7f207ec74130>,\n", + " <__main__.Field at 0x7f207ec74580>,\n", + " <__main__.Field at 0x7f207ec741f0>,\n", + " <__main__.Field at 0x7f207ec74340>,\n", + " <__main__.Field at 0x7f207ec74490>],\n", + " [<__main__.Field at 0x7f207ec58850>,\n", + " <__main__.HintField at 0x7f207ebfca90>,\n", + " <__main__.Field at 0x7f207ed75250>,\n", + " <__main__.Field at 0x7f207ed75ee0>,\n", + " <__main__.LetterField at 0x7f207ed75f40>,\n", + " <__main__.Field at 0x7f207ed75fa0>,\n", + " <__main__.LetterField at 0x7f207ed75c10>,\n", + " <__main__.Field at 0x7f207ed75400>,\n", + " <__main__.LetterField at 0x7f207ed754c0>,\n", + " <__main__.Field at 0x7f207ed75430>,\n", + " <__main__.Field at 0x7f207ed753d0>,\n", + " <__main__.Field at 0x7f207ed75a60>,\n", + " <__main__.Field at 0x7f207ed75bb0>,\n", + " <__main__.LetterField at 0x7f207ed75b20>,\n", + " <__main__.Field at 0x7f207ed75a90>,\n", + " <__main__.LetterField at 0x7f207ed75790>,\n", + " <__main__.Field at 0x7f207ed757c0>,\n", + " <__main__.Field at 0x7f207ed757f0>,\n", + " <__main__.Field at 0x7f207ed75eb0>,\n", + " <__main__.Field at 0x7f207ed75e80>,\n", + " <__main__.LetterField at 0x7f207ed75dc0>,\n", + " <__main__.Field at 0x7f207ed75d90>,\n", + " <__main__.Field at 0x7f207ed75820>,\n", + " <__main__.LetterField at 0x7f207ed75d60>,\n", + " <__main__.LetterField at 0x7f207ed75d00>,\n", + " <__main__.LetterField at 0x7f207eae4160>,\n", + " <__main__.LetterField at 0x7f207eae4130>,\n", + " <__main__.LetterField at 0x7f207eae44c0>,\n", + " <__main__.LetterField at 0x7f207eae46a0>,\n", + " <__main__.LetterField at 0x7f207eae4af0>,\n", + " <__main__.LetterField at 0x7f207eae4a60>,\n", + " <__main__.LetterField at 0x7f207eae4fa0>,\n", + " <__main__.Field at 0x7f207eae4c70>,\n", + " <__main__.LetterField at 0x7f207eae4700>,\n", + " <__main__.LetterField at 0x7f207eae4d00>,\n", + " <__main__.LetterField at 0x7f207eae4430>,\n", + " <__main__.LetterField at 0x7f207eae4d90>,\n", + " <__main__.LetterField at 0x7f207eae4ac0>,\n", + " <__main__.LetterField at 0x7f207ef54970>,\n", + " <__main__.Field at 0x7f207ef549a0>,\n", + " <__main__.LetterField at 0x7f207ef54e80>,\n", + " <__main__.Field at 0x7f207ef548e0>,\n", + " <__main__.LetterField at 0x7f207ef54850>,\n", + " <__main__.HintField at 0x7f207d64ec40>,\n", + " <__main__.HintField at 0x7f207d65ca00>,\n", + " <__main__.Field at 0x7f207ef54f70>,\n", + " <__main__.HintField at 0x7f207d65fe80>,\n", + " <__main__.Field at 0x7f207ef54fd0>,\n", + " <__main__.Field at 0x7f207ef54c40>],\n", + " [<__main__.Field at 0x7f207ed752b0>,\n", + " <__main__.Field at 0x7f207ef54d30>,\n", + " <__main__.LetterField at 0x7f207ef54cd0>,\n", + " <__main__.Field at 0x7f207ef54af0>,\n", + " <__main__.LetterField at 0x7f207ef54a00>,\n", + " <__main__.Field at 0x7f207ef54a60>,\n", + " <__main__.LetterField at 0x7f207ef54bb0>,\n", + " <__main__.Field at 0x7f207ef54b50>,\n", + " <__main__.LetterField at 0x7f207ef544f0>,\n", + " <__main__.Field at 0x7f207ef54c70>,\n", + " <__main__.HintField at 0x7f207eadd5e0>,\n", + " <__main__.LetterField at 0x7f207ef546d0>,\n", + " <__main__.LetterField at 0x7f207ef54760>,\n", + " <__main__.LetterField at 0x7f207ef54730>,\n", + " <__main__.LetterField at 0x7f207ef546a0>,\n", + " <__main__.LetterField at 0x7f207ef54c10>,\n", + " <__main__.LetterField at 0x7f207ef542e0>,\n", + " <__main__.LetterField at 0x7f207ef54610>,\n", + " <__main__.Field at 0x7f207ef545e0>,\n", + " <__main__.LetterField at 0x7f207ef54670>,\n", + " <__main__.LetterField at 0x7f207ef54640>,\n", + " <__main__.LetterField at 0x7f207f153af0>,\n", + " <__main__.LetterField at 0x7f207f153100>,\n", + " <__main__.Field at 0x7f207f1535e0>,\n", + " <__main__.LetterField at 0x7f207f153070>,\n", + " <__main__.Field at 0x7f207f153340>,\n", + " <__main__.LetterField at 0x7f207f153190>,\n", + " <__main__.Field at 0x7f207f153820>,\n", + " <__main__.Field at 0x7f207f153220>,\n", + " <__main__.LetterField at 0x7f207f153880>,\n", + " <__main__.Field at 0x7f207f153d00>,\n", + " <__main__.LetterField at 0x7f207f1539d0>,\n", + " <__main__.Field at 0x7f207f153550>,\n", + " <__main__.Field at 0x7f207eae0670>,\n", + " <__main__.LetterField at 0x7f207ef45c40>,\n", + " <__main__.Field at 0x7f207ef45bb0>,\n", + " <__main__.Field at 0x7f207ef45820>,\n", + " <__main__.Field at 0x7f207ef45580>,\n", + " <__main__.Field at 0x7f207ef45340>,\n", + " <__main__.Field at 0x7f207ef45be0>,\n", + " <__main__.LetterField at 0x7f207ebe25e0>,\n", + " <__main__.LetterField at 0x7f207ebe24f0>,\n", + " <__main__.LetterField at 0x7f207ebe2640>,\n", + " <__main__.LetterField at 0x7f207ebe2ca0>,\n", + " <__main__.Field at 0x7f207ebe28e0>,\n", + " <__main__.LetterField at 0x7f207ebe2f40>,\n", + " <__main__.Field at 0x7f207ebe2910>,\n", + " <__main__.LetterField at 0x7f207ebe23a0>,\n", + " <__main__.Field at 0x7f207ebe2fa0>],\n", + " [<__main__.Field at 0x7f207ef54d60>,\n", + " <__main__.LetterField at 0x7f207ebe2880>,\n", + " <__main__.LetterField at 0x7f207ebe24c0>,\n", + " <__main__.HintField at 0x7f207d6612e0>,\n", + " <__main__.Field at 0x7f207ebe23d0>,\n", + " <__main__.Field at 0x7f207ebe2b50>,\n", + " <__main__.LetterField at 0x7f207ebe2a30>,\n", + " <__main__.Field at 0x7f207ebe2f10>,\n", + " <__main__.LetterField at 0x7f207ebe2610>,\n", + " <__main__.LetterField at 0x7f207ebe2be0>,\n", + " <__main__.LetterField at 0x7f207ebe2bb0>,\n", + " <__main__.Field at 0x7f207ebe2a90>,\n", + " <__main__.Field at 0x7f207ebe2d00>,\n", + " <__main__.LetterField at 0x7f207ebe2b80>,\n", + " <__main__.Field at 0x7f207ebe27f0>,\n", + " <__main__.HintField at 0x7f207d657460>,\n", + " <__main__.Field at 0x7f207ebe2df0>,\n", + " <__main__.Field at 0x7f207ebf3dc0>,\n", + " <__main__.HintField at 0x7f207ef54b20>,\n", + " <__main__.Field at 0x7f207ebf3550>,\n", + " <__main__.LetterField at 0x7f207ebf3670>,\n", + " <__main__.Field at 0x7f207ebf36a0>,\n", + " <__main__.Field at 0x7f207ebf3610>,\n", + " <__main__.Field at 0x7f207ebf3370>,\n", + " <__main__.LetterField at 0x7f207ebf3340>,\n", + " <__main__.Field at 0x7f207ebf3820>,\n", + " <__main__.LetterField at 0x7f207ebf3850>,\n", + " <__main__.Field at 0x7f207ebf33d0>,\n", + " <__main__.Field at 0x7f207ebf3fa0>,\n", + " <__main__.Field at 0x7f207ebf3f70>,\n", + " <__main__.LetterField at 0x7f207ebf3fd0>,\n", + " <__main__.LetterField at 0x7f207ebf3f10>,\n", + " <__main__.LetterField at 0x7f207ebf3d00>,\n", + " <__main__.LetterField at 0x7f207ebf31f0>,\n", + " <__main__.LetterField at 0x7f207ebf31c0>,\n", + " <__main__.LetterField at 0x7f207ebf3280>,\n", + " <__main__.LetterField at 0x7f207ebf3100>,\n", + " <__main__.LetterField at 0x7f207ebf3730>,\n", + " <__main__.LetterField at 0x7f207ebf32b0>,\n", + " <__main__.Field at 0x7f207ef4a580>,\n", + " <__main__.LetterField at 0x7f207ef4ab50>,\n", + " <__main__.Field at 0x7f207ef4a8b0>,\n", + " <__main__.LetterField at 0x7f207ef4afd0>,\n", + " <__main__.Field at 0x7f207ef4a370>,\n", + " <__main__.Field at 0x7f207ef4a5b0>,\n", + " <__main__.LetterField at 0x7f207ef4a490>,\n", + " <__main__.LetterField at 0x7f207ef4a5e0>,\n", + " <__main__.LetterField at 0x7f207ef4a7c0>,\n", + " <__main__.LetterField at 0x7f207ef4a1f0>],\n", + " [<__main__.HintField at 0x7f207ed42a30>,\n", + " <__main__.Field at 0x7f207ef4adc0>,\n", + " <__main__.LetterField at 0x7f207ef4ad60>,\n", + " <__main__.Field at 0x7f207ef4aaf0>,\n", + " <__main__.LetterField at 0x7f207ef4adf0>,\n", + " <__main__.Field at 0x7f207ebeeb80>,\n", + " <__main__.LetterField at 0x7f207ebee550>,\n", + " <__main__.Field at 0x7f207ebeeca0>,\n", + " <__main__.LetterField at 0x7f207ebee1c0>,\n", + " <__main__.Field at 0x7f207ebeec70>,\n", + " <__main__.HintField at 0x7f207d6512e0>,\n", + " <__main__.Field at 0x7f207ebee160>,\n", + " <__main__.LetterField at 0x7f207ebeef40>,\n", + " <__main__.LetterField at 0x7f207ebee2b0>,\n", + " <__main__.LetterField at 0x7f207ebee070>,\n", + " <__main__.LetterField at 0x7f207ebee7c0>,\n", + " <__main__.LetterField at 0x7f207ebee280>,\n", + " <__main__.LetterField at 0x7f207ebee850>,\n", + " <__main__.LetterField at 0x7f207ebeef70>,\n", + " <__main__.LetterField at 0x7f207ebeedc0>,\n", + " <__main__.LetterField at 0x7f207ebeefd0>,\n", + " <__main__.LetterField at 0x7f207ebeedf0>,\n", + " <__main__.LetterField at 0x7f207ebeed00>,\n", + " <__main__.LetterField at 0x7f207ebee940>,\n", + " <__main__.LetterField at 0x7f207ebee430>,\n", + " <__main__.Field at 0x7f207ebeecd0>,\n", + " <__main__.LetterField at 0x7f207ebee640>,\n", + " <__main__.Field at 0x7f207ebee490>,\n", + " <__main__.Field at 0x7f207ebee460>,\n", + " <__main__.Field at 0x7f207ebe99a0>,\n", + " <__main__.Field at 0x7f207ebe99d0>,\n", + " <__main__.Field at 0x7f207ebe98b0>,\n", + " <__main__.Field at 0x7f207ebe92b0>,\n", + " <__main__.HintField at 0x7f207d64b7c0>,\n", + " <__main__.LetterField at 0x7f207ebe9040>,\n", + " <__main__.HintField at 0x7f207d650160>,\n", + " <__main__.Field at 0x7f207ebe9640>,\n", + " <__main__.HintField at 0x7f207ed42af0>,\n", + " <__main__.Field at 0x7f207ebe9490>,\n", + " <__main__.HintField at 0x7f207ef5ddf0>,\n", + " <__main__.LetterField at 0x7f207ebe9820>,\n", + " <__main__.Field at 0x7f207ebe96d0>,\n", + " <__main__.LetterField at 0x7f207ebe9340>,\n", + " <__main__.HintField at 0x7f207d6626a0>,\n", + " <__main__.Field at 0x7f207ef5d2b0>,\n", + " <__main__.LetterField at 0x7f207ef5d940>,\n", + " <__main__.Field at 0x7f207ef5d8b0>,\n", + " <__main__.LetterField at 0x7f207ef5dc70>,\n", + " <__main__.Field at 0x7f207ef5db50>],\n", + " [<__main__.Field at 0x7f207ef4ab20>,\n", + " <__main__.Field at 0x7f207ef5d610>,\n", + " <__main__.LetterField at 0x7f207ef5d7f0>,\n", + " <__main__.Field at 0x7f207ef5da90>,\n", + " <__main__.LetterField at 0x7f207ef5d370>,\n", + " <__main__.Field at 0x7f207ef5d9d0>,\n", + " <__main__.LetterField at 0x7f207ef5d4f0>,\n", + " <__main__.Field at 0x7f207ef5d3a0>,\n", + " <__main__.LetterField at 0x7f207ef5d400>,\n", + " <__main__.LetterField at 0x7f207ef5d430>,\n", + " <__main__.LetterField at 0x7f207ef5dd30>,\n", + " <__main__.LetterField at 0x7f207ef5df10>,\n", + " <__main__.Field at 0x7f207ef5d250>,\n", + " <__main__.HintField at 0x7f207ec58f40>,\n", + " <__main__.Field at 0x7f207ef5dd90>,\n", + " <__main__.Field at 0x7f207ef5d280>,\n", + " <__main__.LetterField at 0x7f207ef5de20>,\n", + " <__main__.Field at 0x7f207ef5de80>,\n", + " <__main__.Field at 0x7f207ef5db20>,\n", + " <__main__.LetterField at 0x7f207ef5dac0>,\n", + " <__main__.Field at 0x7f207ef5dca0>,\n", + " <__main__.Field at 0x7f207ef5df70>,\n", + " <__main__.Field at 0x7f207ef5d070>,\n", + " <__main__.Field at 0x7f207ef5d130>,\n", + " <__main__.Field at 0x7f207ef5d4c0>,\n", + " <__main__.LetterField at 0x7f207eaf1550>,\n", + " <__main__.Field at 0x7f207eaf1040>,\n", + " <__main__.LetterField at 0x7f207eaf1820>,\n", + " <__main__.Field at 0x7f207eaf15e0>,\n", + " <__main__.Field at 0x7f207eaf1340>,\n", + " <__main__.Field at 0x7f207eaf1fd0>,\n", + " <__main__.Field at 0x7f207eaf1610>,\n", + " <__main__.Field at 0x7f207eaf1bb0>,\n", + " <__main__.Field at 0x7f207d648040>,\n", + " <__main__.Field at 0x7f207d6480a0>,\n", + " <__main__.Field at 0x7f207d648100>,\n", + " <__main__.LetterField at 0x7f207d648160>,\n", + " <__main__.Field at 0x7f207d6481c0>,\n", + " <__main__.LetterField at 0x7f207d648220>,\n", + " <__main__.Field at 0x7f207d648280>,\n", + " <__main__.LetterField at 0x7f207d6482e0>,\n", + " <__main__.Field at 0x7f207d648340>,\n", + " <__main__.LetterField at 0x7f207d6483a0>,\n", + " <__main__.Field at 0x7f207d648400>,\n", + " <__main__.LetterField at 0x7f207d648460>,\n", + " <__main__.HintField at 0x7f207ed75310>,\n", + " <__main__.Field at 0x7f207d648520>,\n", + " <__main__.LetterField at 0x7f207d648580>,\n", + " <__main__.Field at 0x7f207d6485e0>],\n", + " [<__main__.HintField at 0x7f207d657940>,\n", + " <__main__.Field at 0x7f207d648670>,\n", + " <__main__.LetterField at 0x7f207d648700>,\n", + " <__main__.LetterField at 0x7f207d648760>,\n", + " <__main__.LetterField at 0x7f207d6487c0>,\n", + " <__main__.LetterField at 0x7f207d648820>,\n", + " <__main__.LetterField at 0x7f207d648880>,\n", + " <__main__.LetterField at 0x7f207d6488e0>,\n", + " <__main__.Field at 0x7f207d648940>,\n", + " <__main__.LetterField at 0x7f207d6489a0>,\n", + " <__main__.HintField at 0x7f207ebf3ac0>,\n", + " <__main__.Field at 0x7f207d648a60>,\n", + " <__main__.LetterField at 0x7f207d648ac0>,\n", + " <__main__.LetterField at 0x7f207d648b20>,\n", + " <__main__.LetterField at 0x7f207d648b80>,\n", + " <__main__.Field at 0x7f207d648be0>,\n", + " <__main__.LetterField at 0x7f207d648c40>,\n", + " <__main__.LetterField at 0x7f207d648ca0>,\n", + " <__main__.LetterField at 0x7f207d648d00>,\n", + " <__main__.LetterField at 0x7f207d648d60>,\n", + " <__main__.LetterField at 0x7f207d648dc0>,\n", + " <__main__.LetterField at 0x7f207d648e20>,\n", + " <__main__.LetterField at 0x7f207d648e80>,\n", + " <__main__.LetterField at 0x7f207d648ee0>,\n", + " <__main__.LetterField at 0x7f207d648f40>,\n", + " <__main__.LetterField at 0x7f207d648fa0>,\n", + " <__main__.Field at 0x7f207d64a040>,\n", + " <__main__.LetterField at 0x7f207d64a0a0>,\n", + " <__main__.HintField at 0x7f207d64b0a0>,\n", + " <__main__.Field at 0x7f207d64a160>,\n", + " <__main__.Field at 0x7f207d64a1c0>,\n", + " <__main__.Field at 0x7f207d64a220>,\n", + " <__main__.HintField at 0x7f207ebe2d30>,\n", + " <__main__.HintField at 0x7f207d6595e0>,\n", + " <__main__.Field at 0x7f207d64a340>,\n", + " <__main__.LetterField at 0x7f207d64a3a0>,\n", + " <__main__.LetterField at 0x7f207d64a400>,\n", + " <__main__.LetterField at 0x7f207d64a460>,\n", + " <__main__.LetterField at 0x7f207d64a4c0>,\n", + " <__main__.LetterField at 0x7f207d64a520>,\n", + " <__main__.Field at 0x7f207d64a580>,\n", + " <__main__.LetterField at 0x7f207d64a5e0>,\n", + " <__main__.LetterField at 0x7f207d64a640>,\n", + " <__main__.LetterField at 0x7f207d64a6a0>,\n", + " <__main__.LetterField at 0x7f207d64a700>,\n", + " <__main__.LetterField at 0x7f207d64a760>,\n", + " <__main__.LetterField at 0x7f207d64a7c0>,\n", + " <__main__.LetterField at 0x7f207d64a820>,\n", + " <__main__.Field at 0x7f207d64a880>],\n", + " [<__main__.Field at 0x7f207d6486a0>,\n", + " <__main__.Field at 0x7f207d64a910>,\n", + " <__main__.LetterField at 0x7f207d64a9a0>,\n", + " <__main__.Field at 0x7f207d64aa00>,\n", + " <__main__.LetterField at 0x7f207d64aa60>,\n", + " <__main__.Field at 0x7f207d64aac0>,\n", + " <__main__.LetterField at 0x7f207d64ab20>,\n", + " <__main__.Field at 0x7f207d64ab80>,\n", + " <__main__.Field at 0x7f207d64abe0>,\n", + " <__main__.LetterField at 0x7f207d64ac40>,\n", + " <__main__.Field at 0x7f207d64aca0>,\n", + " <__main__.LetterField at 0x7f207d64ad00>,\n", + " <__main__.Field at 0x7f207d64ad60>,\n", + " <__main__.Field at 0x7f207d64adc0>,\n", + " <__main__.LetterField at 0x7f207d64ae20>,\n", + " <__main__.Field at 0x7f207d64ae80>,\n", + " <__main__.LetterField at 0x7f207d64aee0>,\n", + " <__main__.Field at 0x7f207d64af40>,\n", + " <__main__.Field at 0x7f207d64afa0>,\n", + " <__main__.LetterField at 0x7f207d64b040>,\n", + " <__main__.HintField at 0x7f207d659fa0>,\n", + " <__main__.Field at 0x7f207d64b100>,\n", + " <__main__.Field at 0x7f207d64b160>,\n", + " <__main__.Field at 0x7f207d64b1c0>,\n", + " <__main__.Field at 0x7f207d64b220>,\n", + " <__main__.LetterField at 0x7f207d64b280>,\n", + " <__main__.Field at 0x7f207d64b2e0>,\n", + " <__main__.LetterField at 0x7f207d64b340>,\n", + " <__main__.Field at 0x7f207d64b3a0>,\n", + " <__main__.LetterField at 0x7f207d64b400>,\n", + " <__main__.LetterField at 0x7f207d64b460>,\n", + " <__main__.LetterField at 0x7f207d64b4c0>,\n", + " <__main__.Field at 0x7f207d64b520>,\n", + " <__main__.Field at 0x7f207d64b580>,\n", + " <__main__.LetterField at 0x7f207d64b5e0>,\n", + " <__main__.Field at 0x7f207d64b640>,\n", + " <__main__.LetterField at 0x7f207d64b6a0>,\n", + " <__main__.Field at 0x7f207d64b700>,\n", + " <__main__.LetterField at 0x7f207d64b760>,\n", + " <__main__.HintField at 0x7f207d6668e0>,\n", + " <__main__.Field at 0x7f207d64b820>,\n", + " <__main__.Field at 0x7f207d64b880>,\n", + " <__main__.Field at 0x7f207d64b8e0>,\n", + " <__main__.Field at 0x7f207d64b940>,\n", + " <__main__.LetterField at 0x7f207d64b9a0>,\n", + " <__main__.Field at 0x7f207d64ba00>,\n", + " <__main__.LetterField at 0x7f207d64ba60>,\n", + " <__main__.Field at 0x7f207d64bac0>,\n", + " <__main__.Field at 0x7f207d64bb20>],\n", + " [<__main__.Field at 0x7f207d64a940>,\n", + " <__main__.HintField at 0x7f207d651460>,\n", + " <__main__.LetterField at 0x7f207d64bc40>,\n", + " <__main__.LetterField at 0x7f207d64bca0>,\n", + " <__main__.LetterField at 0x7f207d64bd00>,\n", + " <__main__.LetterField at 0x7f207d64bd60>,\n", + " <__main__.LetterField at 0x7f207d64bdc0>,\n", + " <__main__.Field at 0x7f207d64be20>,\n", + " <__main__.Field at 0x7f207d64be80>,\n", + " <__main__.LetterField at 0x7f207d64bee0>,\n", + " <__main__.Field at 0x7f207d64bf40>,\n", + " <__main__.LetterField at 0x7f207d64bfa0>,\n", + " <__main__.LetterField at 0x7f207d64d040>,\n", + " <__main__.LetterField at 0x7f207d64d0a0>,\n", + " <__main__.LetterField at 0x7f207d64d100>,\n", + " <__main__.LetterField at 0x7f207d64d160>,\n", + " <__main__.LetterField at 0x7f207d64d1c0>,\n", + " <__main__.LetterField at 0x7f207d64d220>,\n", + " <__main__.LetterField at 0x7f207d64d280>,\n", + " <__main__.LetterField at 0x7f207d64d2e0>,\n", + " <__main__.LetterField at 0x7f207d64d340>,\n", + " <__main__.Field at 0x7f207d64d3a0>,\n", + " <__main__.Field at 0x7f207d64d400>,\n", + " <__main__.Field at 0x7f207d64d460>,\n", + " <__main__.Field at 0x7f207d64d4c0>,\n", + " <__main__.LetterField at 0x7f207d64d520>,\n", + " <__main__.Field at 0x7f207d64d580>,\n", + " <__main__.LetterField at 0x7f207d64d5e0>,\n", + " <__main__.Field at 0x7f207d64d640>,\n", + " <__main__.LetterField at 0x7f207d64d6a0>,\n", + " <__main__.Field at 0x7f207d64d700>,\n", + " <__main__.Field at 0x7f207d64d760>,\n", + " <__main__.LetterField at 0x7f207d64d7c0>,\n", + " <__main__.Field at 0x7f207d64d820>,\n", + " <__main__.LetterField at 0x7f207d64d880>,\n", + " <__main__.LetterField at 0x7f207d64d8e0>,\n", + " <__main__.LetterField at 0x7f207d64d940>,\n", + " <__main__.LetterField at 0x7f207d64d9a0>,\n", + " <__main__.LetterField at 0x7f207d64da00>,\n", + " <__main__.Field at 0x7f207d64da60>,\n", + " <__main__.LetterField at 0x7f207d64dac0>,\n", + " <__main__.HintField at 0x7f207d659160>,\n", + " <__main__.Field at 0x7f207d64db80>,\n", + " <__main__.Field at 0x7f207d64dbe0>,\n", + " <__main__.LetterField at 0x7f207d64dc40>,\n", + " <__main__.Field at 0x7f207d64dca0>,\n", + " <__main__.LetterField at 0x7f207d64dd00>,\n", + " <__main__.Field at 0x7f207d64dd60>,\n", + " <__main__.Field at 0x7f207d64ddc0>],\n", + " [<__main__.Field at 0x7f207d64bbe0>,\n", + " <__main__.Field at 0x7f207d64de50>,\n", + " <__main__.Field at 0x7f207d64dee0>,\n", + " <__main__.Field at 0x7f207d64df40>,\n", + " <__main__.LetterField at 0x7f207d64dfa0>,\n", + " <__main__.Field at 0x7f207d64e040>,\n", + " <__main__.LetterField at 0x7f207d64e0a0>,\n", + " <__main__.Field at 0x7f207d64e100>,\n", + " <__main__.Field at 0x7f207d64e160>,\n", + " <__main__.LetterField at 0x7f207d64e1c0>,\n", + " <__main__.Field at 0x7f207d64e220>,\n", + " <__main__.LetterField at 0x7f207d64e280>,\n", + " <__main__.Field at 0x7f207d64e2e0>,\n", + " <__main__.Field at 0x7f207d64e340>,\n", + " <__main__.LetterField at 0x7f207d64e3a0>,\n", + " <__main__.Field at 0x7f207d64e400>,\n", + " <__main__.LetterField at 0x7f207d64e460>,\n", + " <__main__.Field at 0x7f207d64e4c0>,\n", + " <__main__.Field at 0x7f207d64e520>,\n", + " <__main__.LetterField at 0x7f207d64e580>,\n", + " <__main__.Field at 0x7f207d64e5e0>,\n", + " <__main__.Field at 0x7f207d64e640>,\n", + " <__main__.LetterField at 0x7f207d64e6a0>,\n", + " <__main__.LetterField at 0x7f207d64e700>,\n", + " <__main__.LetterField at 0x7f207d64e760>,\n", + " <__main__.LetterField at 0x7f207d64e7c0>,\n", + " <__main__.LetterField at 0x7f207d64e820>,\n", + " <__main__.LetterField at 0x7f207d64e880>,\n", + " <__main__.LetterField at 0x7f207d64e8e0>,\n", + " <__main__.LetterField at 0x7f207d64e940>,\n", + " <__main__.LetterField at 0x7f207d64e9a0>,\n", + " <__main__.LetterField at 0x7f207d64ea00>,\n", + " <__main__.LetterField at 0x7f207d64ea60>,\n", + " <__main__.LetterField at 0x7f207d64eac0>,\n", + " <__main__.LetterField at 0x7f207d64eb20>,\n", + " <__main__.Field at 0x7f207d64eb80>,\n", + " <__main__.LetterField at 0x7f207d64ebe0>,\n", + " <__main__.HintField at 0x7f207d65aac0>,\n", + " <__main__.Field at 0x7f207d64eca0>,\n", + " <__main__.Field at 0x7f207d64ed00>,\n", + " <__main__.LetterField at 0x7f207d64ed60>,\n", + " <__main__.Field at 0x7f207d64edc0>,\n", + " <__main__.LetterField at 0x7f207d64ee20>,\n", + " <__main__.Field at 0x7f207d64ee80>,\n", + " <__main__.LetterField at 0x7f207d64eee0>,\n", + " <__main__.Field at 0x7f207d64ef40>,\n", + " <__main__.LetterField at 0x7f207d64efa0>,\n", + " <__main__.Field at 0x7f207d650040>,\n", + " <__main__.Field at 0x7f207d6500a0>],\n", + " [<__main__.Field at 0x7f207d64de80>,\n", + " <__main__.Field at 0x7f207d650130>,\n", + " <__main__.Field at 0x7f207d6501c0>,\n", + " <__main__.LetterField at 0x7f207d650220>,\n", + " <__main__.LetterField at 0x7f207d650280>,\n", + " <__main__.LetterField at 0x7f207d6502e0>,\n", + " <__main__.LetterField at 0x7f207d650340>,\n", + " <__main__.LetterField at 0x7f207d6503a0>,\n", + " <__main__.LetterField at 0x7f207d650400>,\n", + " <__main__.LetterField at 0x7f207d650460>,\n", + " <__main__.LetterField at 0x7f207d6504c0>,\n", + " <__main__.LetterField at 0x7f207d650520>,\n", + " <__main__.LetterField at 0x7f207d650580>,\n", + " <__main__.LetterField at 0x7f207d6505e0>,\n", + " <__main__.Field at 0x7f207d650640>,\n", + " <__main__.Field at 0x7f207d6506a0>,\n", + " <__main__.Field at 0x7f207d650700>,\n", + " <__main__.Field at 0x7f207d650760>,\n", + " <__main__.Field at 0x7f207d6507c0>,\n", + " <__main__.LetterField at 0x7f207d650820>,\n", + " <__main__.HintField at 0x7f207d64bbb0>,\n", + " <__main__.Field at 0x7f207d6508e0>,\n", + " <__main__.Field at 0x7f207d650940>,\n", + " <__main__.Field at 0x7f207d6509a0>,\n", + " <__main__.Field at 0x7f207d650a00>,\n", + " <__main__.Field at 0x7f207d650a60>,\n", + " <__main__.Field at 0x7f207d650ac0>,\n", + " <__main__.LetterField at 0x7f207d650b20>,\n", + " <__main__.Field at 0x7f207d650b80>,\n", + " <__main__.LetterField at 0x7f207d650be0>,\n", + " <__main__.Field at 0x7f207d650c40>,\n", + " <__main__.Field at 0x7f207d650ca0>,\n", + " <__main__.LetterField at 0x7f207d650d00>,\n", + " <__main__.Field at 0x7f207d650d60>,\n", + " <__main__.LetterField at 0x7f207d650dc0>,\n", + " <__main__.Field at 0x7f207d650e20>,\n", + " <__main__.Field at 0x7f207d650e80>,\n", + " <__main__.Field at 0x7f207d650ee0>,\n", + " <__main__.LetterField at 0x7f207d650f40>,\n", + " <__main__.Field at 0x7f207d650fa0>,\n", + " <__main__.LetterField at 0x7f207d651040>,\n", + " <__main__.LetterField at 0x7f207d6510a0>,\n", + " <__main__.LetterField at 0x7f207d651100>,\n", + " <__main__.LetterField at 0x7f207d651160>,\n", + " <__main__.LetterField at 0x7f207d6511c0>,\n", + " <__main__.Field at 0x7f207d651220>,\n", + " <__main__.LetterField at 0x7f207d651280>,\n", + " <__main__.HintField at 0x7f207ef54e20>,\n", + " <__main__.Field at 0x7f207d651340>],\n", + " [<__main__.HintField at 0x7f207ebe9580>,\n", + " <__main__.LetterField at 0x7f207d6513d0>,\n", + " <__main__.HintField at 0x7f207d65e400>,\n", + " <__main__.Field at 0x7f207d6514c0>,\n", + " <__main__.Field at 0x7f207d651520>,\n", + " <__main__.LetterField at 0x7f207d651580>,\n", + " <__main__.Field at 0x7f207d6515e0>,\n", + " <__main__.Field at 0x7f207d651640>,\n", + " <__main__.Field at 0x7f207d6516a0>,\n", + " <__main__.Field at 0x7f207d651700>,\n", + " <__main__.Field at 0x7f207d651760>,\n", + " <__main__.LetterField at 0x7f207d6517c0>,\n", + " <__main__.Field at 0x7f207d651820>,\n", + " <__main__.Field at 0x7f207d651880>,\n", + " <__main__.Field at 0x7f207d6518e0>,\n", + " <__main__.Field at 0x7f207d651940>,\n", + " <__main__.LetterField at 0x7f207d6519a0>,\n", + " <__main__.LetterField at 0x7f207d651a00>,\n", + " <__main__.LetterField at 0x7f207d651a60>,\n", + " <__main__.LetterField at 0x7f207d651ac0>,\n", + " <__main__.LetterField at 0x7f207d651b20>,\n", + " <__main__.LetterField at 0x7f207d651b80>,\n", + " <__main__.LetterField at 0x7f207d651be0>,\n", + " <__main__.LetterField at 0x7f207d651c40>,\n", + " <__main__.LetterField at 0x7f207d651ca0>,\n", + " <__main__.LetterField at 0x7f207d651d00>,\n", + " <__main__.Field at 0x7f207d651d60>,\n", + " <__main__.LetterField at 0x7f207d651dc0>,\n", + " <__main__.Field at 0x7f207d651e20>,\n", + " <__main__.LetterField at 0x7f207d651e80>,\n", + " <__main__.Field at 0x7f207d651ee0>,\n", + " <__main__.Field at 0x7f207d651f40>,\n", + " <__main__.LetterField at 0x7f207d651fa0>,\n", + " <__main__.Field at 0x7f207d654040>,\n", + " <__main__.LetterField at 0x7f207d6540a0>,\n", + " <__main__.LetterField at 0x7f207d654100>,\n", + " <__main__.LetterField at 0x7f207d654160>,\n", + " <__main__.LetterField at 0x7f207d6541c0>,\n", + " <__main__.LetterField at 0x7f207d654220>,\n", + " <__main__.LetterField at 0x7f207d654280>,\n", + " <__main__.Field at 0x7f207d6542e0>,\n", + " <__main__.Field at 0x7f207d654340>,\n", + " <__main__.LetterField at 0x7f207d6543a0>,\n", + " <__main__.Field at 0x7f207d654400>,\n", + " <__main__.Field at 0x7f207d654460>,\n", + " <__main__.Field at 0x7f207d6544c0>,\n", + " <__main__.LetterField at 0x7f207d654520>,\n", + " <__main__.Field at 0x7f207d654580>,\n", + " <__main__.LetterField at 0x7f207d6545e0>],\n", + " [<__main__.Field at 0x7f207d651400>,\n", + " <__main__.LetterField at 0x7f207d654670>,\n", + " <__main__.Field at 0x7f207d654700>,\n", + " <__main__.LetterField at 0x7f207d654760>,\n", + " <__main__.Field at 0x7f207d6547c0>,\n", + " <__main__.LetterField at 0x7f207d654820>,\n", + " <__main__.HintField at 0x7f207d648a00>,\n", + " <__main__.Field at 0x7f207d6548e0>,\n", + " <__main__.HintField at 0x7f207d65ff40>,\n", + " <__main__.Field at 0x7f207d6549a0>,\n", + " <__main__.Field at 0x7f207d654a00>,\n", + " <__main__.LetterField at 0x7f207d654a60>,\n", + " <__main__.Field at 0x7f207d654ac0>,\n", + " <__main__.Field at 0x7f207d654b20>,\n", + " <__main__.Field at 0x7f207d654b80>,\n", + " <__main__.Field at 0x7f207d654be0>,\n", + " <__main__.Field at 0x7f207d654c40>,\n", + " <__main__.Field at 0x7f207d654ca0>,\n", + " <__main__.Field at 0x7f207d654d00>,\n", + " <__main__.LetterField at 0x7f207d654d60>,\n", + " <__main__.Field at 0x7f207d654dc0>,\n", + " <__main__.LetterField at 0x7f207d654e20>,\n", + " <__main__.Field at 0x7f207d654e80>,\n", + " <__main__.Field at 0x7f207d654ee0>,\n", + " <__main__.Field at 0x7f207d654f40>,\n", + " <__main__.Field at 0x7f207d654fa0>,\n", + " <__main__.Field at 0x7f207d655040>,\n", + " <__main__.LetterField at 0x7f207d6550a0>,\n", + " <__main__.Field at 0x7f207d655100>,\n", + " <__main__.LetterField at 0x7f207d655160>,\n", + " <__main__.Field at 0x7f207d6551c0>,\n", + " <__main__.Field at 0x7f207d655220>,\n", + " <__main__.LetterField at 0x7f207d655280>,\n", + " <__main__.Field at 0x7f207d6552e0>,\n", + " <__main__.LetterField at 0x7f207d655340>,\n", + " <__main__.HintField at 0x7f207d659e80>,\n", + " <__main__.Field at 0x7f207d655400>,\n", + " <__main__.Field at 0x7f207d655460>,\n", + " <__main__.LetterField at 0x7f207d6554c0>,\n", + " <__main__.HintField at 0x7f207ebe2790>,\n", + " <__main__.Field at 0x7f207d655580>,\n", + " <__main__.Field at 0x7f207d6555e0>,\n", + " <__main__.LetterField at 0x7f207d655640>,\n", + " <__main__.LetterField at 0x7f207d6556a0>,\n", + " <__main__.LetterField at 0x7f207d655700>,\n", + " <__main__.LetterField at 0x7f207d655760>,\n", + " <__main__.LetterField at 0x7f207d6557c0>,\n", + " <__main__.Field at 0x7f207d655820>,\n", + " <__main__.LetterField at 0x7f207d655880>],\n", + " [<__main__.Field at 0x7f207d6546a0>,\n", + " <__main__.LetterField at 0x7f207d655910>,\n", + " <__main__.LetterField at 0x7f207d6559a0>,\n", + " <__main__.LetterField at 0x7f207d655a00>,\n", + " <__main__.Field at 0x7f207d655a60>,\n", + " <__main__.LetterField at 0x7f207d655ac0>,\n", + " <__main__.Field at 0x7f207d655b20>,\n", + " <__main__.LetterField at 0x7f207d655b80>,\n", + " <__main__.LetterField at 0x7f207d655be0>,\n", + " <__main__.LetterField at 0x7f207d655c40>,\n", + " <__main__.LetterField at 0x7f207d655ca0>,\n", + " <__main__.LetterField at 0x7f207d655d00>,\n", + " <__main__.LetterField at 0x7f207d655d60>,\n", + " <__main__.LetterField at 0x7f207d655dc0>,\n", + " <__main__.LetterField at 0x7f207d655e20>,\n", + " <__main__.LetterField at 0x7f207d655e80>,\n", + " <__main__.LetterField at 0x7f207d655ee0>,\n", + " <__main__.LetterField at 0x7f207d655f40>,\n", + " <__main__.Field at 0x7f207d655fa0>,\n", + " <__main__.LetterField at 0x7f207d657040>,\n", + " <__main__.LetterField at 0x7f207d6570a0>,\n", + " <__main__.LetterField at 0x7f207d657100>,\n", + " <__main__.LetterField at 0x7f207d657160>,\n", + " <__main__.LetterField at 0x7f207d6571c0>,\n", + " <__main__.LetterField at 0x7f207d657220>,\n", + " <__main__.LetterField at 0x7f207d657280>,\n", + " <__main__.LetterField at 0x7f207d6572e0>,\n", + " <__main__.LetterField at 0x7f207d657340>,\n", + " <__main__.Field at 0x7f207d6573a0>,\n", + " <__main__.LetterField at 0x7f207d657400>,\n", + " <__main__.HintField at 0x7f207d64a2e0>,\n", + " <__main__.Field at 0x7f207d6574c0>,\n", + " <__main__.LetterField at 0x7f207d657520>,\n", + " <__main__.Field at 0x7f207d657580>,\n", + " <__main__.LetterField at 0x7f207d6575e0>,\n", + " <__main__.Field at 0x7f207d657640>,\n", + " <__main__.LetterField at 0x7f207d6576a0>,\n", + " <__main__.Field at 0x7f207d657700>,\n", + " <__main__.LetterField at 0x7f207d657760>,\n", + " <__main__.Field at 0x7f207d6577c0>,\n", + " <__main__.LetterField at 0x7f207d657820>,\n", + " <__main__.Field at 0x7f207d657880>,\n", + " <__main__.LetterField at 0x7f207d6578e0>,\n", + " <__main__.HintField at 0x7f207d6553a0>,\n", + " <__main__.Field at 0x7f207d6579a0>,\n", + " <__main__.Field at 0x7f207d657a00>,\n", + " <__main__.Field at 0x7f207d657a60>,\n", + " <__main__.Field at 0x7f207d657ac0>,\n", + " <__main__.LetterField at 0x7f207d657b20>],\n", + " [<__main__.Field at 0x7f207d655940>,\n", + " <__main__.LetterField at 0x7f207d657bb0>,\n", + " <__main__.Field at 0x7f207d657c40>,\n", + " <__main__.LetterField at 0x7f207d657ca0>,\n", + " <__main__.LetterField at 0x7f207d657d00>,\n", + " <__main__.LetterField at 0x7f207d657d60>,\n", + " <__main__.Field at 0x7f207d657dc0>,\n", + " <__main__.LetterField at 0x7f207d657e20>,\n", + " <__main__.Field at 0x7f207d657e80>,\n", + " <__main__.LetterField at 0x7f207d657ee0>,\n", + " <__main__.Field at 0x7f207d657f40>,\n", + " <__main__.LetterField at 0x7f207d657fa0>,\n", + " <__main__.Field at 0x7f207d659040>,\n", + " <__main__.Field at 0x7f207d6590a0>,\n", + " <__main__.Field at 0x7f207d659100>,\n", + " <__main__.HintField at 0x7f207d655520>,\n", + " <__main__.Field at 0x7f207d6591c0>,\n", + " <__main__.Field at 0x7f207d659220>,\n", + " <__main__.LetterField at 0x7f207d659280>,\n", + " <__main__.Field at 0x7f207d6592e0>,\n", + " <__main__.Field at 0x7f207d659340>,\n", + " <__main__.LetterField at 0x7f207d6593a0>,\n", + " <__main__.Field at 0x7f207d659400>,\n", + " <__main__.Field at 0x7f207d659460>,\n", + " <__main__.Field at 0x7f207d6594c0>,\n", + " <__main__.Field at 0x7f207d659520>,\n", + " <__main__.Field at 0x7f207d659580>,\n", + " <__main__.HintField at 0x7f207d64a100>,\n", + " <__main__.Field at 0x7f207d659640>,\n", + " <__main__.LetterField at 0x7f207d6596a0>,\n", + " <__main__.Field at 0x7f207d659700>,\n", + " <__main__.LetterField at 0x7f207d659760>,\n", + " <__main__.Field at 0x7f207d6597c0>,\n", + " <__main__.Field at 0x7f207d659820>,\n", + " <__main__.LetterField at 0x7f207d659880>,\n", + " <__main__.Field at 0x7f207d6598e0>,\n", + " <__main__.LetterField at 0x7f207d659940>,\n", + " <__main__.Field at 0x7f207d6599a0>,\n", + " <__main__.Field at 0x7f207d659a00>,\n", + " <__main__.Field at 0x7f207d659a60>,\n", + " <__main__.LetterField at 0x7f207d659ac0>,\n", + " <__main__.Field at 0x7f207d659b20>,\n", + " <__main__.LetterField at 0x7f207d659b80>,\n", + " <__main__.Field at 0x7f207d659be0>,\n", + " <__main__.LetterField at 0x7f207d659c40>,\n", + " <__main__.Field at 0x7f207d659ca0>,\n", + " <__main__.Field at 0x7f207d659d00>,\n", + " <__main__.Field at 0x7f207d659d60>,\n", + " <__main__.LetterField at 0x7f207d659dc0>],\n", + " [<__main__.Field at 0x7f207d657be0>,\n", + " <__main__.LetterField at 0x7f207d659e50>,\n", + " <__main__.Field at 0x7f207d659ee0>,\n", + " <__main__.LetterField at 0x7f207d659f40>,\n", + " <__main__.HintField at 0x7f207d650880>,\n", + " <__main__.LetterField at 0x7f207d65a040>,\n", + " <__main__.LetterField at 0x7f207d65a0a0>,\n", + " <__main__.LetterField at 0x7f207d65a100>,\n", + " <__main__.Field at 0x7f207d65a160>,\n", + " <__main__.LetterField at 0x7f207d65a1c0>,\n", + " <__main__.LetterField at 0x7f207d65a220>,\n", + " <__main__.LetterField at 0x7f207d65a280>,\n", + " <__main__.LetterField at 0x7f207d65a2e0>,\n", + " <__main__.LetterField at 0x7f207d65a340>,\n", + " <__main__.LetterField at 0x7f207d65a3a0>,\n", + " <__main__.LetterField at 0x7f207d65a400>,\n", + " <__main__.LetterField at 0x7f207d65a460>,\n", + " <__main__.Field at 0x7f207d65a4c0>,\n", + " <__main__.LetterField at 0x7f207d65a520>,\n", + " <__main__.Field at 0x7f207d65a580>,\n", + " <__main__.Field at 0x7f207d65a5e0>,\n", + " <__main__.LetterField at 0x7f207d65a640>,\n", + " <__main__.LetterField at 0x7f207d65a6a0>,\n", + " <__main__.LetterField at 0x7f207d65a700>,\n", + " <__main__.LetterField at 0x7f207d65a760>,\n", + " <__main__.LetterField at 0x7f207d65a7c0>,\n", + " <__main__.HintField at 0x7f207d64db20>,\n", + " <__main__.Field at 0x7f207d65a880>,\n", + " <__main__.Field at 0x7f207d65a8e0>,\n", + " <__main__.LetterField at 0x7f207d65a940>,\n", + " <__main__.Field at 0x7f207d65a9a0>,\n", + " <__main__.LetterField at 0x7f207d65aa00>,\n", + " <__main__.Field at 0x7f207d65aa60>,\n", + " <__main__.HintField at 0x7f207d65c520>,\n", + " <__main__.LetterField at 0x7f207d65ab20>,\n", + " <__main__.LetterField at 0x7f207d65ab80>,\n", + " <__main__.LetterField at 0x7f207d65abe0>,\n", + " <__main__.LetterField at 0x7f207d65ac40>,\n", + " <__main__.LetterField at 0x7f207d65aca0>,\n", + " <__main__.LetterField at 0x7f207d65ad00>,\n", + " <__main__.LetterField at 0x7f207d65ad60>,\n", + " <__main__.LetterField at 0x7f207d65adc0>,\n", + " <__main__.LetterField at 0x7f207d65ae20>,\n", + " <__main__.Field at 0x7f207d65ae80>,\n", + " <__main__.LetterField at 0x7f207d65aee0>,\n", + " <__main__.LetterField at 0x7f207d65af40>,\n", + " <__main__.LetterField at 0x7f207d65afa0>,\n", + " <__main__.LetterField at 0x7f207d65c040>,\n", + " <__main__.LetterField at 0x7f207d65c0a0>],\n", + " [<__main__.HintField at 0x7f207ec58ac0>,\n", + " <__main__.Field at 0x7f207d65c130>,\n", + " <__main__.Field at 0x7f207d65c1c0>,\n", + " <__main__.LetterField at 0x7f207d65c220>,\n", + " <__main__.Field at 0x7f207d65c280>,\n", + " <__main__.Field at 0x7f207d65c2e0>,\n", + " <__main__.Field at 0x7f207d65c340>,\n", + " <__main__.LetterField at 0x7f207d65c3a0>,\n", + " <__main__.Field at 0x7f207d65c400>,\n", + " <__main__.Field at 0x7f207d65c460>,\n", + " <__main__.Field at 0x7f207d65c4c0>,\n", + " <__main__.HintField at 0x7f207d668160>,\n", + " <__main__.Field at 0x7f207d65c580>,\n", + " <__main__.Field at 0x7f207d65c5e0>,\n", + " <__main__.Field at 0x7f207d65c640>,\n", + " <__main__.Field at 0x7f207d65c6a0>,\n", + " <__main__.LetterField at 0x7f207d65c700>,\n", + " <__main__.Field at 0x7f207d65c760>,\n", + " <__main__.LetterField at 0x7f207d65c7c0>,\n", + " <__main__.Field at 0x7f207d65c820>,\n", + " <__main__.Field at 0x7f207d65c880>,\n", + " <__main__.LetterField at 0x7f207d65c8e0>,\n", + " <__main__.Field at 0x7f207d65c940>,\n", + " <__main__.Field at 0x7f207d65c9a0>,\n", + " <__main__.HintField at 0x7f207ebee400>,\n", + " <__main__.Field at 0x7f207d65ca60>,\n", + " <__main__.Field at 0x7f207d65cac0>,\n", + " <__main__.LetterField at 0x7f207d65cb20>,\n", + " <__main__.Field at 0x7f207d65cb80>,\n", + " <__main__.LetterField at 0x7f207d65cbe0>,\n", + " <__main__.LetterField at 0x7f207d65cc40>,\n", + " <__main__.LetterField at 0x7f207d65cca0>,\n", + " <__main__.LetterField at 0x7f207d65cd00>,\n", + " <__main__.LetterField at 0x7f207d65cd60>,\n", + " <__main__.LetterField at 0x7f207d65cdc0>,\n", + " <__main__.Field at 0x7f207d65ce20>,\n", + " <__main__.LetterField at 0x7f207d65ce80>,\n", + " <__main__.Field at 0x7f207d65cee0>,\n", + " <__main__.Field at 0x7f207d65cf40>,\n", + " <__main__.Field at 0x7f207d65cfa0>,\n", + " <__main__.LetterField at 0x7f207d65e040>,\n", + " <__main__.Field at 0x7f207d65e0a0>,\n", + " <__main__.LetterField at 0x7f207d65e100>,\n", + " <__main__.Field at 0x7f207d65e160>,\n", + " <__main__.LetterField at 0x7f207d65e1c0>,\n", + " <__main__.Field at 0x7f207d65e220>,\n", + " <__main__.Field at 0x7f207d65e280>,\n", + " <__main__.Field at 0x7f207d65e2e0>,\n", + " <__main__.Field at 0x7f207d65e340>],\n", + " [<__main__.Field at 0x7f207d65c160>,\n", + " <__main__.Field at 0x7f207d65e3d0>,\n", + " <__main__.Field at 0x7f207d65e460>,\n", + " <__main__.LetterField at 0x7f207d65e4c0>,\n", + " <__main__.Field at 0x7f207d65e520>,\n", + " <__main__.Field at 0x7f207d65e580>,\n", + " <__main__.LetterField at 0x7f207d65e5e0>,\n", + " <__main__.LetterField at 0x7f207d65e640>,\n", + " <__main__.LetterField at 0x7f207d65e6a0>,\n", + " <__main__.LetterField at 0x7f207d65e700>,\n", + " <__main__.LetterField at 0x7f207d65e760>,\n", + " <__main__.LetterField at 0x7f207d65e7c0>,\n", + " <__main__.LetterField at 0x7f207d65e820>,\n", + " <__main__.LetterField at 0x7f207d65e880>,\n", + " <__main__.Field at 0x7f207d65e8e0>,\n", + " <__main__.Field at 0x7f207d65e940>,\n", + " <__main__.LetterField at 0x7f207d65e9a0>,\n", + " <__main__.Field at 0x7f207d65ea00>,\n", + " <__main__.LetterField at 0x7f207d65ea60>,\n", + " <__main__.LetterField at 0x7f207d65eac0>,\n", + " <__main__.LetterField at 0x7f207d65eb20>,\n", + " <__main__.LetterField at 0x7f207d65eb80>,\n", + " <__main__.LetterField at 0x7f207d65ebe0>,\n", + " <__main__.LetterField at 0x7f207d65ec40>,\n", + " <__main__.LetterField at 0x7f207d65eca0>,\n", + " <__main__.LetterField at 0x7f207d65ed00>,\n", + " <__main__.Field at 0x7f207d65ed60>,\n", + " <__main__.LetterField at 0x7f207d65edc0>,\n", + " <__main__.Field at 0x7f207d65ee20>,\n", + " <__main__.LetterField at 0x7f207d65ee80>,\n", + " <__main__.Field at 0x7f207d65eee0>,\n", + " <__main__.LetterField at 0x7f207d65ef40>,\n", + " <__main__.Field at 0x7f207d65efa0>,\n", + " <__main__.Field at 0x7f207d65f040>,\n", + " <__main__.Field at 0x7f207d65f0a0>,\n", + " <__main__.LetterField at 0x7f207d65f100>,\n", + " <__main__.LetterField at 0x7f207d65f160>,\n", + " <__main__.LetterField at 0x7f207d65f1c0>,\n", + " <__main__.LetterField at 0x7f207d65f220>,\n", + " <__main__.Field at 0x7f207d65f280>,\n", + " <__main__.LetterField at 0x7f207d65f2e0>,\n", + " <__main__.Field at 0x7f207d65f340>,\n", + " <__main__.Field at 0x7f207d65f3a0>,\n", + " <__main__.LetterField at 0x7f207d65f400>,\n", + " <__main__.LetterField at 0x7f207d65f460>,\n", + " <__main__.LetterField at 0x7f207d65f4c0>,\n", + " <__main__.LetterField at 0x7f207d65f520>,\n", + " <__main__.LetterField at 0x7f207d65f580>,\n", + " <__main__.Field at 0x7f207d65f5e0>],\n", + " [<__main__.HintField at 0x7f207d654880>,\n", + " <__main__.LetterField at 0x7f207d65f670>,\n", + " <__main__.LetterField at 0x7f207d65f700>,\n", + " <__main__.LetterField at 0x7f207d65f760>,\n", + " <__main__.LetterField at 0x7f207d65f7c0>,\n", + " <__main__.Field at 0x7f207d65f820>,\n", + " <__main__.Field at 0x7f207d65f880>,\n", + " <__main__.LetterField at 0x7f207d65f8e0>,\n", + " <__main__.Field at 0x7f207d65f940>,\n", + " <__main__.Field at 0x7f207d65f9a0>,\n", + " <__main__.Field at 0x7f207d65fa00>,\n", + " <__main__.Field at 0x7f207d65fa60>,\n", + " <__main__.LetterField at 0x7f207d65fac0>,\n", + " <__main__.Field at 0x7f207d65fb20>,\n", + " <__main__.HintField at 0x7f207d669b80>,\n", + " <__main__.Field at 0x7f207d65fbe0>,\n", + " <__main__.LetterField at 0x7f207d65fc40>,\n", + " <__main__.Field at 0x7f207d65fca0>,\n", + " <__main__.LetterField at 0x7f207d65fd00>,\n", + " <__main__.Field at 0x7f207d65fd60>,\n", + " <__main__.Field at 0x7f207d65fdc0>,\n", + " <__main__.Field at 0x7f207d65fe20>,\n", + " <__main__.HintField at 0x7f207ec58c10>,\n", + " <__main__.Field at 0x7f207d65fee0>,\n", + " <__main__.HintField at 0x7f207d665b80>,\n", + " <__main__.Field at 0x7f207d65ffa0>,\n", + " <__main__.LetterField at 0x7f207d661040>,\n", + " <__main__.LetterField at 0x7f207d6610a0>,\n", + " <__main__.LetterField at 0x7f207d661100>,\n", + " <__main__.HintField at 0x7f207ebe2940>,\n", + " <__main__.Field at 0x7f207d6611c0>,\n", + " <__main__.LetterField at 0x7f207d661220>,\n", + " <__main__.LetterField at 0x7f207d661280>,\n", + " <__main__.HintField at 0x7f207d661160>,\n", + " <__main__.Field at 0x7f207d661340>,\n", + " <__main__.Field at 0x7f207d6613a0>,\n", + " <__main__.Field at 0x7f207d661400>,\n", + " <__main__.Field at 0x7f207d661460>,\n", + " <__main__.Field at 0x7f207d6614c0>,\n", + " <__main__.Field at 0x7f207d661520>,\n", + " <__main__.LetterField at 0x7f207d661580>,\n", + " <__main__.Field at 0x7f207d6615e0>,\n", + " <__main__.Field at 0x7f207d661640>,\n", + " <__main__.Field at 0x7f207d6616a0>,\n", + " <__main__.LetterField at 0x7f207d661700>,\n", + " <__main__.Field at 0x7f207d661760>,\n", + " <__main__.Field at 0x7f207d6617c0>,\n", + " <__main__.Field at 0x7f207d661820>,\n", + " <__main__.LetterField at 0x7f207d661880>],\n", + " [<__main__.Field at 0x7f207d65f6a0>,\n", + " <__main__.LetterField at 0x7f207d661910>,\n", + " <__main__.Field at 0x7f207d6619a0>,\n", + " <__main__.LetterField at 0x7f207d661a00>,\n", + " <__main__.Field at 0x7f207d661a60>,\n", + " <__main__.Field at 0x7f207d661ac0>,\n", + " <__main__.Field at 0x7f207d661b20>,\n", + " <__main__.LetterField at 0x7f207d661b80>,\n", + " <__main__.Field at 0x7f207d661be0>,\n", + " <__main__.Field at 0x7f207d661c40>,\n", + " <__main__.LetterField at 0x7f207d661ca0>,\n", + " <__main__.LetterField at 0x7f207d661d00>,\n", + " <__main__.LetterField at 0x7f207d661d60>,\n", + " <__main__.Field at 0x7f207d661dc0>,\n", + " <__main__.LetterField at 0x7f207d661e20>,\n", + " <__main__.LetterField at 0x7f207d661e80>,\n", + " <__main__.LetterField at 0x7f207d661ee0>,\n", + " <__main__.LetterField at 0x7f207d661f40>,\n", + " <__main__.LetterField at 0x7f207d661fa0>,\n", + " <__main__.LetterField at 0x7f207d662040>,\n", + " <__main__.Field at 0x7f207d6620a0>,\n", + " <__main__.Field at 0x7f207d662100>,\n", + " <__main__.Field at 0x7f207d662160>,\n", + " <__main__.LetterField at 0x7f207d6621c0>,\n", + " <__main__.Field at 0x7f207d662220>,\n", + " <__main__.LetterField at 0x7f207d662280>,\n", + " <__main__.Field at 0x7f207d6622e0>,\n", + " <__main__.LetterField at 0x7f207d662340>,\n", + " <__main__.Field at 0x7f207d6623a0>,\n", + " <__main__.LetterField at 0x7f207d662400>,\n", + " <__main__.LetterField at 0x7f207d662460>,\n", + " <__main__.LetterField at 0x7f207d6624c0>,\n", + " <__main__.Field at 0x7f207d662520>,\n", + " <__main__.Field at 0x7f207d662580>,\n", + " <__main__.LetterField at 0x7f207d6625e0>,\n", + " <__main__.Field at 0x7f207d662640>,\n", + " <__main__.HintField at 0x7f207d66fbe0>,\n", + " <__main__.Field at 0x7f207d662700>,\n", + " <__main__.Field at 0x7f207d662760>,\n", + " <__main__.LetterField at 0x7f207d6627c0>,\n", + " <__main__.LetterField at 0x7f207d662820>,\n", + " <__main__.LetterField at 0x7f207d662880>,\n", + " <__main__.LetterField at 0x7f207d6628e0>,\n", + " <__main__.LetterField at 0x7f207d662940>,\n", + " <__main__.LetterField at 0x7f207d6629a0>,\n", + " <__main__.LetterField at 0x7f207d662a00>,\n", + " <__main__.Field at 0x7f207d662a60>,\n", + " <__main__.Field at 0x7f207d662ac0>,\n", + " <__main__.LetterField at 0x7f207d662b20>],\n", + " [<__main__.Field at 0x7f207d661940>,\n", + " <__main__.LetterField at 0x7f207d662bb0>,\n", + " <__main__.LetterField at 0x7f207d662c40>,\n", + " <__main__.LetterField at 0x7f207d662ca0>,\n", + " <__main__.LetterField at 0x7f207d662d00>,\n", + " <__main__.LetterField at 0x7f207d662d60>,\n", + " <__main__.LetterField at 0x7f207d662dc0>,\n", + " <__main__.LetterField at 0x7f207d662e20>,\n", + " <__main__.LetterField at 0x7f207d662e80>,\n", + " <__main__.LetterField at 0x7f207d662ee0>,\n", + " <__main__.Field at 0x7f207d662f40>,\n", + " <__main__.Field at 0x7f207d662fa0>,\n", + " <__main__.LetterField at 0x7f207d665040>,\n", + " <__main__.Field at 0x7f207d6650a0>,\n", + " <__main__.Field at 0x7f207d665100>,\n", + " <__main__.LetterField at 0x7f207d665160>,\n", + " <__main__.Field at 0x7f207d6651c0>,\n", + " <__main__.LetterField at 0x7f207d665220>,\n", + " <__main__.Field at 0x7f207d665280>,\n", + " <__main__.Field at 0x7f207d6652e0>,\n", + " <__main__.LetterField at 0x7f207d665340>,\n", + " <__main__.LetterField at 0x7f207d6653a0>,\n", + " <__main__.LetterField at 0x7f207d665400>,\n", + " <__main__.LetterField at 0x7f207d665460>,\n", + " <__main__.LetterField at 0x7f207d6654c0>,\n", + " <__main__.LetterField at 0x7f207d665520>,\n", + " <__main__.LetterField at 0x7f207d665580>,\n", + " <__main__.LetterField at 0x7f207d6655e0>,\n", + " <__main__.LetterField at 0x7f207d665640>,\n", + " <__main__.Field at 0x7f207d6656a0>,\n", + " <__main__.Field at 0x7f207d665700>,\n", + " <__main__.LetterField at 0x7f207d665760>,\n", + " <__main__.LetterField at 0x7f207d6657c0>,\n", + " <__main__.LetterField at 0x7f207d665820>,\n", + " <__main__.LetterField at 0x7f207d665880>,\n", + " <__main__.LetterField at 0x7f207d6658e0>,\n", + " <__main__.Field at 0x7f207d665940>,\n", + " <__main__.LetterField at 0x7f207d6659a0>,\n", + " <__main__.Field at 0x7f207d665a00>,\n", + " <__main__.Field at 0x7f207d665a60>,\n", + " <__main__.LetterField at 0x7f207d665ac0>,\n", + " <__main__.Field at 0x7f207d665b20>,\n", + " <__main__.HintField at 0x7f207ebe9070>,\n", + " <__main__.Field at 0x7f207d665be0>,\n", + " <__main__.Field at 0x7f207d665c40>,\n", + " <__main__.Field at 0x7f207d665ca0>,\n", + " <__main__.Field at 0x7f207d665d00>,\n", + " <__main__.Field at 0x7f207d665d60>,\n", + " <__main__.LetterField at 0x7f207d665dc0>],\n", + " [<__main__.Field at 0x7f207d662be0>,\n", + " <__main__.LetterField at 0x7f207d665e50>,\n", + " <__main__.Field at 0x7f207d665ee0>,\n", + " <__main__.LetterField at 0x7f207d665f40>,\n", + " <__main__.HintField at 0x7f207ef5da30>,\n", + " <__main__.Field at 0x7f207d666040>,\n", + " <__main__.Field at 0x7f207d6660a0>,\n", + " <__main__.LetterField at 0x7f207d666100>,\n", + " <__main__.Field at 0x7f207d666160>,\n", + " <__main__.Field at 0x7f207d6661c0>,\n", + " <__main__.LetterField at 0x7f207d666220>,\n", + " <__main__.HintField at 0x7f207d654940>,\n", + " <__main__.Field at 0x7f207d6662e0>,\n", + " <__main__.LetterField at 0x7f207d666340>,\n", + " <__main__.LetterField at 0x7f207d6663a0>,\n", + " <__main__.LetterField at 0x7f207d666400>,\n", + " <__main__.Field at 0x7f207d666460>,\n", + " <__main__.LetterField at 0x7f207d6664c0>,\n", + " <__main__.Field at 0x7f207d666520>,\n", + " <__main__.Field at 0x7f207d666580>,\n", + " <__main__.LetterField at 0x7f207d6665e0>,\n", + " <__main__.Field at 0x7f207d666640>,\n", + " <__main__.Field at 0x7f207d6666a0>,\n", + " <__main__.LetterField at 0x7f207d666700>,\n", + " <__main__.Field at 0x7f207d666760>,\n", + " <__main__.LetterField at 0x7f207d6667c0>,\n", + " <__main__.Field at 0x7f207d666820>,\n", + " <__main__.LetterField at 0x7f207d666880>,\n", + " <__main__.HintField at 0x7f207ef54fa0>,\n", + " <__main__.Field at 0x7f207d666940>,\n", + " <__main__.Field at 0x7f207d6669a0>,\n", + " <__main__.LetterField at 0x7f207d666a00>,\n", + " <__main__.Field at 0x7f207d666a60>,\n", + " <__main__.Field at 0x7f207d666ac0>,\n", + " <__main__.LetterField at 0x7f207d666b20>,\n", + " <__main__.Field at 0x7f207d666b80>,\n", + " <__main__.Field at 0x7f207d666be0>,\n", + " <__main__.LetterField at 0x7f207d666c40>,\n", + " <__main__.Field at 0x7f207d666ca0>,\n", + " <__main__.Field at 0x7f207d666d00>,\n", + " <__main__.Field at 0x7f207d666d60>,\n", + " <__main__.LetterField at 0x7f207d666dc0>,\n", + " <__main__.Field at 0x7f207d666e20>,\n", + " <__main__.LetterField at 0x7f207d666e80>,\n", + " <__main__.Field at 0x7f207d666ee0>,\n", + " <__main__.Field at 0x7f207d666f40>,\n", + " <__main__.Field at 0x7f207d666fa0>,\n", + " <__main__.Field at 0x7f207d668040>,\n", + " <__main__.LetterField at 0x7f207d6680a0>],\n", + " [<__main__.Field at 0x7f207d665e80>,\n", + " <__main__.LetterField at 0x7f207d668130>,\n", + " <__main__.LetterField at 0x7f207d6681c0>,\n", + " <__main__.Field at 0x7f207d668220>,\n", + " <__main__.LetterField at 0x7f207d668280>,\n", + " <__main__.LetterField at 0x7f207d6682e0>,\n", + " <__main__.LetterField at 0x7f207d668340>,\n", + " <__main__.LetterField at 0x7f207d6683a0>,\n", + " <__main__.LetterField at 0x7f207d668400>,\n", + " <__main__.LetterField at 0x7f207d668460>,\n", + " <__main__.LetterField at 0x7f207d6684c0>,\n", + " <__main__.LetterField at 0x7f207d668520>,\n", + " <__main__.LetterField at 0x7f207d668580>,\n", + " <__main__.Field at 0x7f207d6685e0>,\n", + " <__main__.Field at 0x7f207d668640>,\n", + " <__main__.LetterField at 0x7f207d6686a0>,\n", + " <__main__.Field at 0x7f207d668700>,\n", + " <__main__.LetterField at 0x7f207d668760>,\n", + " <__main__.Field at 0x7f207d6687c0>,\n", + " <__main__.Field at 0x7f207d668820>,\n", + " <__main__.LetterField at 0x7f207d668880>,\n", + " <__main__.Field at 0x7f207d6688e0>,\n", + " <__main__.Field at 0x7f207d668940>,\n", + " <__main__.LetterField at 0x7f207d6689a0>,\n", + " <__main__.Field at 0x7f207d668a00>,\n", + " <__main__.Field at 0x7f207d668a60>,\n", + " <__main__.Field at 0x7f207d668ac0>,\n", + " <__main__.LetterField at 0x7f207d668b20>,\n", + " <__main__.Field at 0x7f207d668b80>,\n", + " <__main__.LetterField at 0x7f207d668be0>,\n", + " <__main__.Field at 0x7f207d668c40>,\n", + " <__main__.LetterField at 0x7f207d668ca0>,\n", + " <__main__.Field at 0x7f207d668d00>,\n", + " <__main__.Field at 0x7f207d668d60>,\n", + " <__main__.LetterField at 0x7f207d668dc0>,\n", + " <__main__.Field at 0x7f207d668e20>,\n", + " <__main__.Field at 0x7f207d668e80>,\n", + " <__main__.LetterField at 0x7f207d668ee0>,\n", + " <__main__.LetterField at 0x7f207d668f40>,\n", + " <__main__.LetterField at 0x7f207d668fa0>,\n", + " <__main__.LetterField at 0x7f207d669040>,\n", + " <__main__.LetterField at 0x7f207d6690a0>,\n", + " <__main__.LetterField at 0x7f207d669100>,\n", + " <__main__.LetterField at 0x7f207d669160>,\n", + " <__main__.LetterField at 0x7f207d6691c0>,\n", + " <__main__.LetterField at 0x7f207d669220>,\n", + " <__main__.Field at 0x7f207d669280>,\n", + " <__main__.Field at 0x7f207d6692e0>,\n", + " <__main__.LetterField at 0x7f207d669340>],\n", + " [<__main__.HintField at 0x7f207ebe9400>,\n", + " <__main__.LetterField at 0x7f207d6693d0>,\n", + " <__main__.LetterField at 0x7f207d669460>,\n", + " <__main__.Field at 0x7f207d6694c0>,\n", + " <__main__.Field at 0x7f207d669520>,\n", + " <__main__.LetterField at 0x7f207d669580>,\n", + " <__main__.Field at 0x7f207d6695e0>,\n", + " <__main__.LetterField at 0x7f207d669640>,\n", + " <__main__.Field at 0x7f207d6696a0>,\n", + " <__main__.Field at 0x7f207d669700>,\n", + " <__main__.LetterField at 0x7f207d669760>,\n", + " <__main__.Field at 0x7f207d6697c0>,\n", + " <__main__.LetterField at 0x7f207d669820>,\n", + " <__main__.Field at 0x7f207d669880>,\n", + " <__main__.Field at 0x7f207d6698e0>,\n", + " <__main__.LetterField at 0x7f207d669940>,\n", + " <__main__.Field at 0x7f207d6699a0>,\n", + " <__main__.LetterField at 0x7f207d669a00>,\n", + " <__main__.Field at 0x7f207d669a60>,\n", + " <__main__.Field at 0x7f207d669ac0>,\n", + " <__main__.LetterField at 0x7f207d669b20>,\n", + " <__main__.HintField at 0x7f207ec58f70>,\n", + " <__main__.Field at 0x7f207d669be0>,\n", + " <__main__.LetterField at 0x7f207d669c40>,\n", + " <__main__.Field at 0x7f207d669ca0>,\n", + " <__main__.LetterField at 0x7f207d669d00>,\n", + " <__main__.LetterField at 0x7f207d669d60>,\n", + " <__main__.LetterField at 0x7f207d669dc0>,\n", + " <__main__.LetterField at 0x7f207d669e20>,\n", + " <__main__.LetterField at 0x7f207d669e80>,\n", + " <__main__.LetterField at 0x7f207d669ee0>,\n", + " <__main__.LetterField at 0x7f207d669f40>,\n", + " <__main__.LetterField at 0x7f207d669fa0>,\n", + " <__main__.Field at 0x7f207d66b040>,\n", + " <__main__.LetterField at 0x7f207d66b0a0>,\n", + " <__main__.Field at 0x7f207d66b100>,\n", + " <__main__.Field at 0x7f207d66b160>,\n", + " <__main__.LetterField at 0x7f207d66b1c0>,\n", + " <__main__.Field at 0x7f207d66b220>,\n", + " <__main__.Field at 0x7f207d66b280>,\n", + " <__main__.Field at 0x7f207d66b2e0>,\n", + " <__main__.LetterField at 0x7f207d66b340>,\n", + " <__main__.Field at 0x7f207d66b3a0>,\n", + " <__main__.LetterField at 0x7f207d66b400>,\n", + " <__main__.Field at 0x7f207d66b460>,\n", + " <__main__.Field at 0x7f207d66b4c0>,\n", + " <__main__.Field at 0x7f207d66b520>,\n", + " <__main__.Field at 0x7f207d66b580>,\n", + " <__main__.LetterField at 0x7f207d66b5e0>],\n", + " [<__main__.Field at 0x7f207d669400>,\n", + " <__main__.LetterField at 0x7f207d66b670>,\n", + " <__main__.LetterField at 0x7f207d66b700>,\n", + " <__main__.Field at 0x7f207d66b760>,\n", + " <__main__.Field at 0x7f207d66b7c0>,\n", + " <__main__.LetterField at 0x7f207d66b820>,\n", + " <__main__.Field at 0x7f207d66b880>,\n", + " <__main__.Field at 0x7f207d66b8e0>,\n", + " <__main__.Field at 0x7f207d66b940>,\n", + " <__main__.Field at 0x7f207d66b9a0>,\n", + " <__main__.LetterField at 0x7f207d66ba00>,\n", + " <__main__.Field at 0x7f207d66ba60>,\n", + " <__main__.LetterField at 0x7f207d66bac0>,\n", + " <__main__.Field at 0x7f207d66bb20>,\n", + " <__main__.Field at 0x7f207d66bb80>,\n", + " <__main__.LetterField at 0x7f207d66bbe0>,\n", + " <__main__.Field at 0x7f207d66bc40>,\n", + " <__main__.LetterField at 0x7f207d66bca0>,\n", + " <__main__.Field at 0x7f207d66bd00>,\n", + " <__main__.Field at 0x7f207d66bd60>,\n", + " <__main__.LetterField at 0x7f207d66bdc0>,\n", + " <__main__.Field at 0x7f207d66be20>,\n", + " <__main__.Field at 0x7f207d66be80>,\n", + " <__main__.Field at 0x7f207d66bee0>,\n", + " <__main__.Field at 0x7f207d66bf40>,\n", + " <__main__.Field at 0x7f207d66bfa0>,\n", + " <__main__.Field at 0x7f207d66c040>,\n", + " <__main__.LetterField at 0x7f207d66c0a0>,\n", + " <__main__.Field at 0x7f207d66c100>,\n", + " <__main__.LetterField at 0x7f207d66c160>,\n", + " <__main__.Field at 0x7f207d66c1c0>,\n", + " <__main__.LetterField at 0x7f207d66c220>,\n", + " <__main__.Field at 0x7f207d66c280>,\n", + " <__main__.LetterField at 0x7f207d66c2e0>,\n", + " <__main__.LetterField at 0x7f207d66c340>,\n", + " <__main__.LetterField at 0x7f207d66c3a0>,\n", + " <__main__.LetterField at 0x7f207d66c400>,\n", + " <__main__.LetterField at 0x7f207d66c460>,\n", + " <__main__.LetterField at 0x7f207d66c4c0>,\n", + " <__main__.LetterField at 0x7f207d66c520>,\n", + " <__main__.Field at 0x7f207d66c580>,\n", + " <__main__.LetterField at 0x7f207d66c5e0>,\n", + " <__main__.LetterField at 0x7f207d66c640>,\n", + " <__main__.LetterField at 0x7f207d66c6a0>,\n", + " <__main__.LetterField at 0x7f207d66c700>,\n", + " <__main__.LetterField at 0x7f207d66c760>,\n", + " <__main__.LetterField at 0x7f207d66c7c0>,\n", + " <__main__.LetterField at 0x7f207d66c820>,\n", + " <__main__.LetterField at 0x7f207d66c880>],\n", + " [<__main__.Field at 0x7f207d66b6a0>,\n", + " <__main__.Field at 0x7f207d66c910>,\n", + " <__main__.LetterField at 0x7f207d66c9a0>,\n", + " <__main__.LetterField at 0x7f207d66ca00>,\n", + " <__main__.LetterField at 0x7f207d66ca60>,\n", + " <__main__.LetterField at 0x7f207d66cac0>,\n", + " <__main__.Field at 0x7f207d66cb20>,\n", + " <__main__.Field at 0x7f207d66cb80>,\n", + " <__main__.Field at 0x7f207d66cbe0>,\n", + " <__main__.LetterField at 0x7f207d66cc40>,\n", + " <__main__.LetterField at 0x7f207d66cca0>,\n", + " <__main__.LetterField at 0x7f207d66cd00>,\n", + " <__main__.LetterField at 0x7f207d66cd60>,\n", + " <__main__.LetterField at 0x7f207d66cdc0>,\n", + " <__main__.Field at 0x7f207d66ce20>,\n", + " <__main__.LetterField at 0x7f207d66ce80>,\n", + " <__main__.Field at 0x7f207d66cee0>,\n", + " <__main__.Field at 0x7f207d66cf40>,\n", + " <__main__.Field at 0x7f207d66cfa0>,\n", + " <__main__.Field at 0x7f207d66f040>,\n", + " <__main__.Field at 0x7f207d66f0a0>,\n", + " <__main__.Field at 0x7f207d66f100>,\n", + " <__main__.Field at 0x7f207d66f160>,\n", + " <__main__.LetterField at 0x7f207d66f1c0>,\n", + " <__main__.LetterField at 0x7f207d66f220>,\n", + " <__main__.LetterField at 0x7f207d66f280>,\n", + " <__main__.LetterField at 0x7f207d66f2e0>,\n", + " <__main__.LetterField at 0x7f207d66f340>,\n", + " <__main__.LetterField at 0x7f207d66f3a0>,\n", + " <__main__.LetterField at 0x7f207d66f400>,\n", + " <__main__.Field at 0x7f207d66f460>,\n", + " <__main__.Field at 0x7f207d66f4c0>,\n", + " <__main__.Field at 0x7f207d66f520>,\n", + " <__main__.Field at 0x7f207d66f580>,\n", + " <__main__.Field at 0x7f207d66f5e0>,\n", + " <__main__.Field at 0x7f207d66f640>,\n", + " <__main__.Field at 0x7f207d66f6a0>,\n", + " <__main__.LetterField at 0x7f207d66f700>,\n", + " <__main__.Field at 0x7f207d66f760>,\n", + " <__main__.Field at 0x7f207d66f7c0>,\n", + " <__main__.Field at 0x7f207d66f820>,\n", + " <__main__.LetterField at 0x7f207d66f880>,\n", + " <__main__.Field at 0x7f207d66f8e0>,\n", + " <__main__.Field at 0x7f207d66f940>,\n", + " <__main__.Field at 0x7f207d66f9a0>,\n", + " <__main__.Field at 0x7f207d66fa00>,\n", + " <__main__.Field at 0x7f207d66fa60>,\n", + " <__main__.Field at 0x7f207d66fac0>,\n", + " <__main__.Field at 0x7f207d66fb20>]]" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cw._grid._grid" + ] + }, { "cell_type": "code", "execution_count": null, diff --git a/js_client/assets/hint_both.svg b/js_client/assets/hint_both.svg new file mode 100644 index 0000000..f334524 --- /dev/null +++ b/js_client/assets/hint_both.svg @@ -0,0 +1,94 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/js_client/assets/hint_horizontal.svg b/js_client/assets/hint_horizontal.svg new file mode 100644 index 0000000..627d536 --- /dev/null +++ b/js_client/assets/hint_horizontal.svg @@ -0,0 +1,78 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/js_client/assets/hint_vertical.svg b/js_client/assets/hint_vertical.svg new file mode 100644 index 0000000..f7bca1b --- /dev/null +++ b/js_client/assets/hint_vertical.svg @@ -0,0 +1,34 @@ + + + + + + + image/svg+xml + + + + + + + + + diff --git a/js_client/cookie.js b/js_client/cookie.js new file mode 100644 index 0000000..56b35eb --- /dev/null +++ b/js_client/cookie.js @@ -0,0 +1,23 @@ +export function setCookie(cname, cvalue, exdays) { + var d = new Date(); + d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000)); + var expires = "expires=" + d.toUTCString(); + document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/"; +} + +export function getCookie(cname) { + var name = cname + "="; + var decodedCookie = decodeURIComponent(document.cookie); + var ca = decodedCookie.split(';'); + for (var i = 0; i < ca.length; i++) { + var c = ca[i]; + while (c.charAt(0) == ' ') { + c = c.substring(1); + } + if (c.indexOf(name) == 0) { + return c.substring(name.length, c.length); + } + } + return ""; +} + diff --git a/js_client/grid.js b/js_client/grid.js new file mode 100644 index 0000000..5be412e --- /dev/null +++ b/js_client/grid.js @@ -0,0 +1,772 @@ +import { html, css, LitElement, unsafeCSS } from 'https://unpkg.com/lit-element/lit-element.js?module'; +import './infoBox.js' + +const gridType = { + EMPTY: 0, + HINT: 1, + LETTER: 2 +}; + +export class GridElement { + constructor(x, y, grid, type) { + this.x = x; + this.y = y; + this.type = type + this.grid = grid; + + + this.gridLetter = null; + this.hintBox = null; + this.emptyBox = null; + } + + setGridLetter(gridLetter) { + this.gridLetter = gridLetter; + } + + getGridLetter() { + return this.gridLetter; + } + + setHintBox(hintBox) { + this.hintBox = hintBox; + } + + getHintBox() { + return this.hintBox; + } + + setEmptyBox(emptyBox) { + this.emptyBox = emptyBox; + } + + getEmptyBox() { + return this.emptyBox; + } + + getGridType() { + return this.type; + } + +} + +export class GridBox extends LitElement { + static get styles() { + return css` + input[type='text'] { + width: 1.5em; + height: 1.5em; + text-align: center; + border-style: solid; + border-color: black; + border-width: 0.2 em; + background-color: black; + outline: none; + color: transparent; + text-shadow: 0 0 1 black; + font-size: 2em; + user-select: none; + text-transform: uppercase; + } + `; + } + + static get properties() { + return { + x: { type: Number }, + y: { type: Number }, + grid_id: { type: String } + } + } + + constructor() { + super(); + this.x = 0; + this.y = 0; + this.gridElement = null; + this.grid_id = null; + this.crosswordGrid = null; + this.isRevealed = false; + } + + update(props) { + super.update(); + if (props.has("grid_id")) { + this.updateGridElement(); + } + } + + updateGridElement() { + if (this.grid_id != null) { + + this.crosswordGrid = document.getElementById(this.grid_id); + this.gridElement = this.crosswordGrid.getGridElement(this.x, this.y); + this.gridElement.setEmptyBox(this); + } + } + + render() { + return html``; + } +} + +customElements.define('grid-box', GridBox); + + +export class GridLetter extends GridBox { + static get styles() { + return css` + input[type='text'] { + width: 1.5em; + height: 1.5em; + text-align: center; + border-style: solid; + border-width: 0.2 em; + border-color: black; + outline: none; + color: black; + font-size: 2em; + user-select: none; + text-transform: capitalize; + } + + input[type='text']:focus { + background-color: LightYellow; + border-color: Yellow; + + } + + input[type='text']:read-only { + background-color: LightGreen; + } + + input[type='text']:selection { + background: transparent; + } + `; + } + + static get properties() { + return { + letter: { type: String }, + x: { type: Number }, + y: { type: Number }, + grid_id: { type: String } + } + } + + constructor() { + super(); + this._value = ''; + this.is_focused = false; + this.key_delay = false; + this.updateGridElement(); + } + + + + set value(value) { + const oldValue = this.value; + console.log("update value to: " + value); + + this._value = value; + this.requestUpdate('value', oldValue); + } + + get value() { + return this._value; + } + + onInput(e) { + + if (!this.is_focused) { + return; + } + + //if (this.key_delay){ + // var el = this.shadowRoot.getElementById(`${this.x}-${this.y}`); + // el.value = this.value; + // el.select(); + // e.handled = true; + // return; + //} + + var oldVal = this.value; + this.value = e.target.value + + if (this.revealed) { + this.value = oldVal; + return + } + + if (this.value.length > 1) { + this.value = str.slice(0); + e.target.value = this.value + e.handled = true; + } + + if (!e.handled && this.value === " ") { + this.value = ""; + e.target.value = ""; + e.handled = true; + } + + if (!e.handled && this.value.length === 0) { + this.crosswordGrid.focusPrevCell(this.x, this.y); + e.handled = true; + } + else if (!e.handled && this.value.length === 1) { + this.crosswordGrid.focusNextCell(this.x, this.y); + e.handled = true; + } + else { + this.focus(); + } + + if (oldVal != this.value) { + this.crosswordGrid.sendMessage({ + 'type': 'update', + 'x': this.x, + 'y': this.y, + 'letter': this.value + }) + } + + if (!e.handled){ + + e.target.select(); + + e.handled = true; + } + + } + + onKeydown(e) { + + if (!this.is_focused) { + return; + } + + this.key_delay = false; + + var key = e.key; + + console.log(key); + + + if (this.value.length == 0) { + if (key === 'Backspace' || key === 'Delete') { + this.crosswordGrid.focusPrevCell(this.x, this.y); + e.handled = true; + return + + } + } + + // check arrow keys + if (key === "ArrowLeft") { + // left + this.crosswordGrid.focusPrevCellHorizontal(this.x, this.y); + e.handled = true; + return; + } + else if (key === "ArrowUp") { + // up + this.crosswordGrid.focusPrevCellVertical(this.x, this.y); + e.handled = true; + return; + + } + else if (key === "ArrowRight") { + //right + this.crosswordGrid.focusNextCellHorizontal(this.x, this.y); + e.handled = true; + return; + } + else if (key === "ArrowDown") { + //down + this.crosswordGrid.focusNextCellVertical(this.x, this.y); + e.handled = true; + return; + } + + + + e.target.select(); + + + } + + onFocus(e) { + e.target.select(); + this.is_focused = true; + this.key_delay = true; + + this.crosswordGrid.updateHints(this.x, this.y); + } + + focus() { + var element = this.shadowRoot.getElementById(`${this.x}-${this.y}`); + element.focus(); + } + + blur() { + var element = this.shadowRoot.getElementById(`${this.x}-${this.y}`); + element.blur(); + this.is_focused = false; + } + + updateGridElement() { + super.updateGridElement() + + if (this.grid_id != null) { + + this.gridElement.setGridLetter(this); + } + } + + updateLetter(letter, revealed) { + this.value = letter; + if (revealed) + { + console.log("rec") + this.shadowRoot.getElementById(`${this.x}-${this.y}`).readOnly = true; + this.blur(); + this.revealed = true; + } + } + + render() { + this.updateGridElement(); + return html``; + } +} + +customElements.define('grid-letter', GridLetter); + + + +export class HintBox extends GridBox { + + static get styles() { + + return css` + + .hint { + display: grid; + } + + + .triangle-down { + position: relative; + top: 3em; + left: 1em; + z-index: 10; + grid-column: 1; + grid-row: 1; + width: 0; + height: 0; + border-left: 0.75em solid transparent; + border-right: 0.75em solid transparent; + border-top: 1.3em solid #555; + + } + + .triangle-right { + position: relative; + top: 1em; + left: 3em; + z-index: 10; + grid-column: 1; + grid-row: 1; + width: 0; + height: 0; + border-top: 0.75em solid transparent; + border-bottom: 0.75em solid transparent; + border-left: 1.3em solid #555; + + } + + input[type='text']{ + grid-column: 1; + grid-row: 1; + width: 1.5em; + height: 1.5em; + text-align: center; + border-style: solid; + border-color: black; + border-width: 0.2 em; + background-color: #555; + outline: none; + color: white; + text-shadow: 0 0 1 black; + font-size: 2em; + user-select: none; + text-transform: uppercase; + } + `; + } + + static get properties() { + return { + x: { type: Number }, + y: { type: Number }, + grid_id: { type: String }, + horizontal_hint: { type: String }, + vertical_hint: { type: String }, + hint_id: { type: String } + } + } + + constructor() { + super(); + this.vertical_hint = ""; + this.horizontal_hint = ""; + this.hint_id = 0; + + } + + + + getVerticalHint() { + return this.vertical_hint; + } + + getHorizontalHint() { + return this.horizontal_hint; + } + + hasVerticalHint() { + return this.vertical_hint.length > 0; + } + + hasHorizontalHint() { + return this.horizontal_hint.length > 0; + } + + updateGridElement() { + super.updateGridElement() + + if (this.grid_id != null) { + + this.gridElement.setHintBox(this); + } + } + + render() { + + this.updateGridElement(); + + var verticalArrow = html``; + var horizontalArrow = html``; + + if (this.hasVerticalHint()) { + verticalArrow = html`
`; + } + + if (this.hasHorizontalHint()) { + horizontalArrow = html`
`; + } + + return html` +
+ + ${verticalArrow} + ${horizontalArrow} +
+ `; + } +} + +customElements.define('hint-box', HintBox); + +export class CrosswordGrid extends LitElement { + static get styles() { + return css` + body { + background-color: black; + } + + table { + position: relative; + top: 5em; + border-spacing: 0px; + border-style: solid; + border-color: black; + border-width: 1em; + } + + td { + padding: 0px; + } + `; + } + + static get properties() { + return { + id: { type: String }, + width: { type: Number }, + height: { type: Number }, + infobox_id: {type: String} + } + } + + constructor() { + super(); + this.width = 10; + this.height = 10; + this.grid = []; + + this.json_grid = null; + + this.num_hints = 0; + + this.lastMoveVertical = false; + + this.infobox = null; + + this.serverConnection = null; + } + + createGridByJson(json_grid) { + this.num_hints = 0; + this.json_grid = json_grid; + this.grid = []; + const width = json_grid.w; + const height = json_grid.h; + + var y; + var x; + + for (y = 0; y < height; y++) { + var row = []; + for (x = 0; x < width; x++) { + const json_cell = json_grid.grid[y][x]; + const cell_type = json_cell.cell_type; + + switch (cell_type) { + case "empty": { + row.push(new GridElement(x, y, this, gridType.EMPTY)); + break; + } + case "hint": { + row.push(new GridElement(x, y, this, gridType.HINT)); + break; + } + case "letter": { + row.push(new GridElement(x, y, this, gridType.LETTER)); + break; + } + + }; + } + this.grid.push(row); + } + + this.width = width; + this.height = height; + } + + focusNextCellHorizontal(x, y) { + if (x + 1 < this.width && this.grid[y][x + 1].getGridType() === gridType.LETTER) { + if (this.grid[y][x].getGridType() === gridType.LETTER) { + this.grid[y][x].getGridLetter().blur(); + } + this.grid[y][x + 1].getGridLetter().focus(); + + + return true; + } + + return false; + } + + focusPrevCellHorizontal(x, y) { + if (x - 1 >= 0 && this.grid[y][x - 1].getGridType() === gridType.LETTER) { + if (this.grid[y][x].getGridType() === gridType.LETTER) { + this.grid[y][x].getGridLetter().blur(); + } + this.grid[y][x - 1].getGridLetter().focus(); + + + return true; + } + + return false; + } + + focusNextCellVertical(x, y) { + if (y + 1 < this.height && this.grid[y + 1][x].getGridType() === gridType.LETTER) { + if (this.grid[y][x].getGridType() === gridType.LETTER) { + this.grid[y][x].getGridLetter().blur(); + } + this.grid[y + 1][x].getGridLetter().focus(); + + return true; + } + + return false; + } + + focusPrevCellVertical(x, y) { + if (y - 1 >= 0 && this.grid[y - 1][x].getGridType() === gridType.LETTER) { + if (this.grid[y][x].getGridType() === gridType.LETTER) { + this.grid[y][x].getGridLetter().blur(); + } + this.grid[y - 1][x].getGridLetter().focus(); + + + return true; + } + + return false; + } + + focusNextCell(x, y) { + if (this.lastMoveVertical) { + if (this.focusNextCellVertical(x, y)) { + return; + } + if (this.focusNextCellHorizontal(x, y)) { + this.lastMoveVertical = false; + } + } + else { + if (this.focusNextCellHorizontal(x, y)) { + return; + } + if (this.focusNextCellVertical(x, y)) { + this.lastMoveVertical = true; + } + } + } + + focusPrevCell(x, y) { + if (this.lastMoveVertical) { + if (this.focusPrevCellVertical(x, y)) { + return; + } + if (this.focusPrevCellHorizontal(x, y)) { + this.lastMoveVertical = false; + } + } + else { + if (this.focusPrevCellHorizontal(x, y)) { + return; + } + if (this.focusPrevCellVertical(x, y)) { + this.lastMoveVertical = true; + } + } + } + + getGridElement(x, y) { + return this.grid[y][x]; + } + + update(props) { + if (props.has("width") || props.has("height")) { + // + } + if (props.has("infobox_id")) { + this.infobox = document.getElementById(this.infobox_id); + } + super.update() + } + + updateHints(x,y) { + var cell = this.grid[y][x]; + if (cell.getGridType() != gridType.LETTER){ + console.error("cannot get hints for non letter cell"); + } + + //get horizontal hint: + var upper_end = cell; + while (upper_end.getGridType() === gridType.LETTER) { + upper_end = this.grid[upper_end.y - 1][x] + } + + var left_end = cell; + while (left_end.getGridType() === gridType.LETTER) { + left_end = this.grid[y][left_end.x - 1] + } + + var hHint = ""; + var vHint = ""; + + if (left_end.getGridType() === gridType.HINT) { + var box = left_end.getHintBox(); + hHint = `${box.hint_id}: ${box.horizontal_hint}`; + } + + if (upper_end.getGridType() === gridType.HINT) { + var box = upper_end.getHintBox() + vHint = `${box.hint_id}: ${box.vertical_hint}`; + } + + this.infobox.horizontal_hint = hHint; + this.infobox.vertical_hint = vHint; + } + + renderCell(el) { + switch (el.type) { + case gridType.LETTER: { + return html``; + + } + case gridType.EMPTY: { + return html``; + + } + case gridType.HINT: { + var vertical_hint = this.json_grid.grid[el.y][el.x].vertical_hint; + var horizontal_hint = this.json_grid.grid[el.y][el.x].horizontal_hint; + + if (!vertical_hint){ + vertical_hint = ""; + } + if (!horizontal_hint){ + horizontal_hint = ""; + } + + this.num_hints += 1; + + return html` + + `; + + } + } + } + + updateLetter(x,y,letter,revealed) { + var cell = this.grid[y][x]; + if (cell.getGridType() != gridType.LETTER){ + console.error("received bad message"); + } + cell.getGridLetter().updateLetter(letter, revealed) + } + + registerServerConnection(connection){ + this.serverConnection = connection + } + + sendMessage(msg){ + if (!this.serverConnection) { + console.error("no server connection registered") + } + this.serverConnection.sendMessage(msg) + } + + render() { + this.num_hints = 0; + console.log("refreshing grid"); + return html` + + ${this.grid.map((row) => html`${row.map((el) => html``)}`)} +
${this.renderCell(el)}
+ `; + } +} + +customElements.define('crossword-grid', CrosswordGrid); \ No newline at end of file diff --git a/js_client/index.html b/js_client/index.html new file mode 100644 index 0000000..c519bc6 --- /dev/null +++ b/js_client/index.html @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js_client/infoBox.js b/js_client/infoBox.js new file mode 100644 index 0000000..94abc4a --- /dev/null +++ b/js_client/infoBox.js @@ -0,0 +1,55 @@ +import { html, css, LitElement, unsafeCSS } from 'https://unpkg.com/lit-element/lit-element.js?module'; + +export class InfoBox extends LitElement { + static get styles() { + return css` + .hinttext { + color: white; + margin-left: 1em; + margin-top: 0.8em; + + + } + + .infobox { + z-index: 20; + position: fixed; + top: 0em; + left: 0em; + right: 0em; + height: 6em; + + border-style: solid; + border-color: white; + border-width: 0.2 em; + background-color: #333; + color: white; + } + `; + } + + static get properties() { + return { + horizontal_hint: { type: String }, + vertical_hint: { type: String } + }; + } + + constructor() { + super(); + this.vertical_hint = ""; + this.horizontal_hint = ""; + } + + render() { + return html` +
+
▶ ${this.horizontal_hint}
+
▼ ${this.vertical_hint}
+
+ `; + } + +} + +customElements.define('info-box', InfoBox); diff --git a/js_client/main.js b/js_client/main.js new file mode 100644 index 0000000..d573507 --- /dev/null +++ b/js_client/main.js @@ -0,0 +1,3 @@ +import '/grid.js' +import '/serverConnection.js' + diff --git a/js_client/serve.py b/js_client/serve.py new file mode 100644 index 0000000..134cc5a --- /dev/null +++ b/js_client/serve.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 +from http.server import HTTPServer, SimpleHTTPRequestHandler, test +import sys + +class CORSRequestHandler (SimpleHTTPRequestHandler): + def end_headers (self): + self.send_header('Access-Control-Allow-Origin', '*') + SimpleHTTPRequestHandler.end_headers(self) + +if __name__ == '__main__': + test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000) + diff --git a/js_client/serverConnection.js b/js_client/serverConnection.js new file mode 100644 index 0000000..af8a8a9 --- /dev/null +++ b/js_client/serverConnection.js @@ -0,0 +1,141 @@ +import { html, css, LitElement } from 'https://unpkg.com/lit-element/lit-element.js?module'; +import { WebsocketConnection } from '/websocket.js'; +import { getCookie, setCookie } from '/cookie.js'; + +export class ServerConnection extends WebsocketConnection { + static get styles() { + return css``; + } + + static get properties() { + return { + url: { type: String }, + grid_id: { type: String } + } + } + + constructor() { + super(); + this.sessionId = null; + this.isRegistered = false; + this.crossword_grid = null; + } + + update(props) { + if (props.has("grid_id")) { + this.crossword_grid = document.getElementById(this.grid_id); + this.crossword_grid.registerServerConnection(this); + } + super.update(props) + } + + updateLocalSessionId() { + // look whether the session id is given in url params + // or stored as cookie + const queryString = window.location.search; + const params = new URLSearchParams(queryString); + if (params.has('session')) { + this.sessionId = params.get('session'); + return; + } + const cookie_session = getCookie('session'); + if (cookie_session != "") { + this.sessionId = cookie_session; + return; + } + + } + + register() { + this.updateLocalSessionId(); + console.log("register", this.sessionId); + this.sendMessage({ + 'type': 'register', + 'sessionId': this.sessionId + }); + } + + onopen(event) { + super.onopen(event); + console.log("overloaded", this); + this.register(); + } + + handleRegistration(sessionId) { + if (!sessionId) { + console.warn("got undefined session id"); + return; + } + this.sessionId = sessionId; + console.log("stored session", sessionId, "as cookie") + setCookie("session", sessionId, 2); + const urlparams = new URLSearchParams(window.location.search); + if (urlparams.has('session') && this.sessionId === urlparams.get('session')){ + return; + } + urlparams.set('session', sessionId); + var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?session=' + sessionId; + window.history.pushState({ path: newurl }, '', newurl); + + } + + handleCrossword(crossword) { + this.crossword_grid.createGridByJson(crossword); + } + + handleUpdate(updates) { + var i = 0; + for (i = 0; i < updates.length; i++) { + const item = updates[i]; + + const x = item['x']; + const y = item['y']; + + if (item.hasOwnProperty("user_input")) { + const letter = item['user_input']; + this.crossword_grid.updateLetter(x, y, letter, false); + } + if (item.hasOwnProperty("revealed")) { + console.log("update"); + const letter = item['revealed']; + this.crossword_grid.updateLetter(x, y, letter, true); + } + + } + } + + onmessage(event) { + super.onmessage(event) + try { + const msg = JSON.parse(event.data); + if (!msg.type) { + throw "missing type" + } + switch (msg.type) { + case 'register': { + this.handleRegistration(msg.sessionId); + break; + } + case 'crossword': { + this.handleCrossword(msg.crossword); + break; + } + case 'update': { + this.handleUpdate(msg.updates); + break + } + + } + + } + catch (err) { + console.error("could not parse servermessage", err); + return + } + + } + + +} + +customElements.define('server-connection', ServerConnection); \ No newline at end of file diff --git a/js_client/websocket.js b/js_client/websocket.js new file mode 100644 index 0000000..5f0cff7 --- /dev/null +++ b/js_client/websocket.js @@ -0,0 +1,88 @@ +import { html, css, LitElement } from 'https://unpkg.com/lit-element/lit-element.js?module'; + +export class WebsocketConnection extends LitElement { + static get styles() { + return css``; + } + + static get properties() { + return { + url: { type: String } + } + } + + constructor() { + super(); + + this.url = ''; + this.socket = null; + } + + + onopen(event){ + console.log("websocket connected"); + } + + onclose(event){ + console.log("websocket closed"); + } + + onerror(event){ + console.log("websocket error, closing..."); + if (this.socket && this.socket.readyState === WebSocket.OPEN) { + this.socket.close(); + } + } + + onmessage(event){ + console.log("received message:", event.data); + } + + isSocketConnected(){ + if (! this.socket){ + return false; + } + + if (this.socket.readyState === WebSocket.OPEN) { + return true; + } + return false; + } + + sendMessage(msg){ + + if (this.isSocketConnected()) { + var string_msg = JSON.stringify(msg); + this.socket.send(string_msg); + } + else { + console.error("cannot send message, websocket disconnected"); + } + + } + + connect() { + console.log(`connect to ${this.url}...`); + this.socket = new WebSocket(this.url); + this.socket.onopen = (event) => this.onopen(event); + this.socket.onclose = (event) => this.onclose(event); + this.socket.onerror = (event) => this.onerror(event); + this.socket.onmessage = (event) => this.onmessage(event); + } + + update(props) { + if (props.has("url")){ + this.connect(); + } + super.update(props); + } + + + + render() { + // do nothing + return html``; + } +} + +customElements.define('websocket-connection', WebsocketConnection); \ No newline at end of file diff --git a/server/.gitattributes b/server/.gitattributes new file mode 100644 index 0000000..2e2f2f3 --- /dev/null +++ b/server/.gitattributes @@ -0,0 +1 @@ +en.json filter=lfs diff=lfs merge=lfs -text diff --git a/server/crossword.py b/server/crossword.py new file mode 100644 index 0000000..754be7e --- /dev/null +++ b/server/crossword.py @@ -0,0 +1,320 @@ +import enum +import json +import logging +import numpy as np + +from . import crossword_generator + +from enum import Enum + +import traceback + + +class HintOrientation(Enum): + VERTICAL = 0 + HORIZONTAL = 1 + BOTH = 2 + + +class FieldType(Enum): + EMPTY = 0 + HINT = 1 + LETTER = 2 + + +class Field(object): + def __init__(self, field_type: FieldType = FieldType.EMPTY): + self._field_type = field_type + + def get_type(self) -> FieldType: + return self._field_type + + def get_content(self) -> str: + return None + + def serialize(self): + type_names = { + FieldType.EMPTY: "empty", + FieldType.HINT: "hint", + FieldType.LETTER: "letter" + } + + return { + 'cell_type': type_names[self._field_type] + } + + +class HintField(Field): + def __init__(self, horizontal_hint: str = None, vertical_hint: str = None): + super().__init__(field_type=FieldType.HINT) + + self._horizontal_hint = horizontal_hint + self._vertical_hint = vertical_hint + + def get_horizontal_hint(self) -> str: + return self._horizontal_hint + + def get_vertical_hint(self) -> str: + return self._vertical_hint + + def set_horizintal_hint(self, hint: str): + self._horizontal_hint = hint + + def set_vertical_hint(self, hint: str): + self._vertical_hint = hint + + def serialize(self): + result = super().serialize() + result['vertical_hint'] = self._vertical_hint + result['horizontal_hint'] = self._horizontal_hint + + return result + + +class LetterField(Field): + def __init__(self, letter: str): + assert len(letter) <= 1 + + super().__init__(field_type=FieldType.LETTER) + + self._letter = letter.lower() + self._revealed = False + self._user_letter = "" + + def get_content(self) -> str: + return self._letter.upper() + + def get_user_content(self) -> str: + return self._user_letter.upper() + + def reveal(self): + self._revealed = True + + def user_input(self, input_letter): + assert len(input_letter) <= 1 + self._user_letter = input_letter.lower() + + def is_revealed(self) -> bool: + return self._revealed + + def serialize(self): + result = super().serialize() + result['letter'] = self._letter + + return result + + +class Grid(object): + def __init__(self, width: int, height: int, lang_code: str, density=0.5): + self._width = width + self._height = height + self._lang_code = lang_code + self._density = density + self._grid = [] + try: + self._build_grid() + except Exception as e: + logging.error("error in generation", str(e)) + traceback.print_exc() + + def serialize(self): + return [ + [cell.serialize() for cell in row] for row in self._grid + ] + + def get_status(self): + status = [] + for y, row in enumerate(self._grid): + for x, cell in enumerate(row): + if cell.get_type() == FieldType.LETTER: + + user_content = cell.get_user_content() + if cell.is_revealed(): + status.append({ + 'x': x, + 'y': y, + 'revealed': cell.get_content() + }) + elif len(user_content) > 0: + status.append({ + 'x': x, + 'y': y, + 'user_input': user_content + }) + return status + + def check_and_reveal_horizontal(self, x: int, y: int) -> list: + # TODO: this would be much more perfomant and elegant, if every cell would hold a reference + # to it's own word^^ + + status_update = [] + cells_to_reveal = [] + + x_start = x + while (self._grid[y][x_start-1].get_type() == FieldType.LETTER): + x_start -= 1 + + x_i = x_start - 1 + while(x_i + 1 < self._width and self._grid[y][x_i+1].get_type() == FieldType.LETTER): + + x_i += 1 + cell = self._grid[y][x_i] + if cell.get_user_content() != cell.get_content(): + return [] + cells_to_reveal.append(cell) + + if x_start - x_i == 0: + # we have a single letter, not a word + return [] + + for i, cell in enumerate(cells_to_reveal): + status_update.append({ + 'x': x_start + i, + 'y': y, + 'revealed': cell.get_content() + }) + cell.reveal() + + return status_update + + def check_and_reveal_vertical(self, x: int, y: int) -> list: + # TODO: this would be much more perfomant and elegant, if every cell would hold a reference + # to it's own word^^ + + status_update = [] + cells_to_reveal = [] + + y_start = y + while (self._grid[y_start - 1][x].get_type() == FieldType.LETTER): + y_start -= 1 + + y_i = y_start - 1 + while(y_i + 1 < self._width and self._grid[y_i+1][x].get_type() == FieldType.LETTER): + + y_i += 1 + cell = self._grid[y_i][x] + if cell.get_user_content() != cell.get_content(): + return [] + cells_to_reveal.append(cell) + + if y_start - y_i == 0: + # we have a single letter, not a word + return [] + + for i, cell in enumerate(cells_to_reveal): + status_update.append({ + 'x': x, + 'y': y + i, + 'revealed': cell.get_content() + }) + cell.reveal() + + return status_update + + def check_and_reveal_word(self, x: int, y: int): + return self.check_and_reveal_horizontal(x, y) + self.check_and_reveal_vertival(x, y) + + def user_input(self, x: int, y: int, letter: str) -> list: + assert len(letter) <= 1 + + cell = self._grid[y][x] + + if cell.get_type() != FieldType.LETTER: + # should not happen if the client does everything right + logging.warning("try to modify wrong cell") + return [] + + if cell.is_revealed(): + # user tries to modify already revealed change, telling him it's already revealed ;) + return [{ + 'x': x, + 'y': y, + 'revealed': cell.get_content() + }] + + letter = letter.lower() + + cell.user_input(letter.lower()) + + revealed_changes = self.check_and_reveal_vertical( + x, y) + self.check_and_reveal_horizontal(x, y) + + if len(revealed_changes) == 0: + return [{ + 'x': x, + 'y': y, + 'user_input': cell.get_user_content() + }] + + return revealed_changes + + def _build_grid(self): + raw_grid, word_infos = crossword_generator.create_word_grid( + self._width - 1, self._height - 1, lang_code="en", target_density=self._density) + + # note: we will append an additional row and column, to have enough space to place hint fields + + self._grid = [[Field()] * self._width] # initialize with empty row + + for y in range(self._height - 1): + row = [Field()] # initialize row with empty column + for x in range(self._width - 1): + raw_cell = raw_grid[y, x] + if raw_cell == " ": + row.append(Field()) + else: + row.append(LetterField(raw_cell)) + + self._grid.append(row) + + # place hint fields: + for word, info in word_infos.items(): + y, x = info.get_hint_location() + # correct offset + y += 1 + x += 1 + + cell = self._grid[y][x] + + # check if we already have a hint here: + if cell.get_type() == FieldType.HINT: + if info.is_vertical(): + cell.set_vertical_hint(info.get_hint()) + else: + cell.set_horizintal_hint(info.get_hint()) + elif cell.get_type() == FieldType.LETTER: + # edge case: a word has "eaten up" another one, skipping that case + pass + + else: + if info.is_vertical(): + self._grid[y][x] = HintField(vertical_hint=info.get_hint()) + else: + self._grid[y][x] = HintField( + horizontal_hint=info.get_hint()) + + +class Crossword(object): + def __init__(self, width: int, height: int, lang_code: str = "en"): + self._width = width + self._height = height + self._grid = Grid(width, height, lang_code) + + def serialize(self): + return { + 'w': self._width, + 'h': self._height, + 'grid': self._grid.serialize() + } + + def user_input(self, x: int, y: int, letter: str) -> list: + return self._grid.user_input(x=x, y=y, letter=letter) + + def get_status(self) -> list: + return self._grid.get_status() + + +if __name__ == "__main__": + logging.basicConfig(level=logging.INFO) + cw = Crossword(15, 15, "en") + print(cw.serialize()) diff --git a/server/crossword_connection.py b/server/crossword_connection.py new file mode 100644 index 0000000..f51502c --- /dev/null +++ b/server/crossword_connection.py @@ -0,0 +1,112 @@ +import logging +import uuid + +from . import json_websockets +from . import session + + +class CrosswordConnection(json_websockets.JsonWebsocketConnection): + + sessions = {} + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + self._session = None + + async def send_crossword(self, sessionId: str): + if sessionId not in CrosswordConnection.sessions: + await self.send_error(msg="unknown session") + return + + sess = CrosswordConnection.sessions[sessionId] + + # NOTE: if there will be the possibility of private + # sessions, this has to be changed since this is leaking + # the information that a certain session exists! + if self not in sess.get_sockets(): + await self.send_error(msg="you are not registered to given session") + return + + crossword = sess.get_crossword() + await self.send({ + 'type': 'crossword', + 'crossword': crossword.serialize() + }) + + # sending also the status as update: + await self.send({ + 'type': 'update', + 'updates': crossword.get_status() + }) + + async def user_update(self, x: int, y: int, letter: str): + if len(letter) > 1: + await self.send_error(msg="received invalid userinput") + return + + update_message = self._session.get_crossword().user_input(x=x, y=y, letter=letter) + + for connection in self._session.get_sockets(): + await connection.send({ + 'type': 'update', + 'updates': update_message + }) + + async def register(self, sessionId: str = None): + + if sessionId is None: + + sessionId = uuid.uuid4().hex + while sessionId in CrosswordConnection.sessions: + sessionId = uuid.uuid4().hex + + new_session = session.Session() + CrosswordConnection.sessions[sessionId] = new_session + + if sessionId not in CrosswordConnection.sessions: + await self.send_error("unknown session id") + + # register with new id: + await self.register() + return + + sess = CrosswordConnection.sessions[sessionId] + sess.connect_socket(self) + + self._session = sess + + await self.send({ + 'type': 'register', + 'sessionId': sessionId + }) + + await self.send_crossword(sessionId) + + async def send_error(self, msg: str): + await self.send({ + 'type': 'error', + 'message': msg + }) + + async def handle_message(self, message: dict): + logging.info("incoming message: %s", str(message)) + if not "type" in message: + logging.error("received malformated message") + await self.send_error(msg="i do not understand the request") + return + + if message['type'] == 'register': + sessionId = None + if 'sessionId' in message: + sessionId = message['sessionId'] + await self.register(sessionId=sessionId) + return + + if self._session is None: + await self.send_error(msg="you are not registered properly") + return + + if message['type'] == "update": + await self.user_update(x=message['x'], y=message['y'], letter=message['letter']) + return diff --git a/server/crossword_generator.py b/server/crossword_generator.py new file mode 100644 index 0000000..0248f57 --- /dev/null +++ b/server/crossword_generator.py @@ -0,0 +1,286 @@ +import json +import random +import numpy as np +from string import digits +import pathlib +import logging + + +def get_database(lang: str = "en") -> dict: + if lang not in get_database._dbs: + current_folder = pathlib.Path(__file__).parents[0] + db_file = str(current_folder / f"{lang}.json") + + logging.info("loading database: %s", lang) + + with open(db_file, "r") as f: + db = json.load(f) + get_database._dbs[lang] = db + + logging.info("database loaded") + + return get_database._dbs[lang] + +get_database._dbs = {} + +class NoDataException(Exception): + pass + +class WordInfo(object): + def __init__(self, word:str, y:int, x:int, is_vertical: bool, database: dict): + self._dictionary_database = database + self._y = y + self._x = x + self._word = word + self._hint = None + self._is_vertical = is_vertical + + self.choose_info() + + def get_attribute(self, attr: str): + attr = self._dictionary_database[self._word][attr] + if attr is None: + raise NoDataException + return attr + + def get_best_antonym(self) -> str: + antonyms = self.get_attribute("antonyms") + return random.choice(antonyms) + + def get_best_synonym(self) -> str: + synonyms = self.get_attribute("synonyms") + return random.choice(synonyms) + + def get_best_sense(self) -> str: + senses = self.get_attribute("senses") + return random.choice(senses) + + def choose_info(self): + # first choose antonyms, then synonyms, then senses + + try: + self._hint = f"opposite of {self.get_best_antonym()}" + return + except NoDataException: + pass + + try: + self._hint = f"other word for {self.get_best_synonym()}" + return + except NoDataException: + pass + + self._hint = self.get_best_sense() + + def get_hint(self) -> str: + return self._hint + + def get_hint_location(self): + x = self._x if self._is_vertical else self._x - 1 + y = self._y - 1 if self._is_vertical else self._y + return (y, x) + + def is_vertical(self): + return self._is_vertical + +def create_word_grid(w: int, h: int, lang_code: str = "en", target_density = 0.5): + logging.info("generate new crossword") + + database = get_database(lang = lang_code) + list_words = list(database.keys()) + + grid = np.full(shape=(h,w), dtype=np.unicode, fill_value = ' ') + + locations = {} + + word_hints = {} + + def store_location(char: str, y: int, x: int): + assert len(char) == 1 + + if char not in locations: + locations[char] = [] + + locations[char].append([y,x]) + + remove_digits = str.maketrans('', '', digits) + n_words = len(list_words) + + def get_word(max_length: int, min_length = 0): + assert max_length > 1 + + index = random.randint(0,n_words-1) + word = list_words[index][:] + + while len(word) >= max_length or not word.isalnum() or len(word) <= min_length: + index = random.randint(0,n_words-1) + word = list_words[index][:] + + return word + + def normalize_word(word:str): + word = word.translate(remove_digits) + return word.lower() + + def place_word(word:str, y: int, x:int, vertical:bool = False): + normalized_word = normalize_word(word) + n = len(normalized_word) + if vertical: + assert grid.shape[0] - n >= y + for i, char in enumerate(normalized_word): + grid[y + i,x] = char + store_location(char, y+i, x) + else: + assert grid.shape[1] - n >= x + for i, char in enumerate(normalized_word): + grid[y,x + i] = char + store_location(char, y, x+i) + + word_hints[normalized_word] = WordInfo(word, y, x, vertical, database) + + + + def density(): + return 1 - (grid == " ").sum() / (w * h) + + + + def check_if_fits(word:str, y:int, x:int, vertical:bool): + n = len(word) + if vertical: + + # check if there is space before and after + if y - 1 >= 0 and grid[y - 1, x] != " ": + return False + if y + n < grid.shape[0] - 1 and grid[y+n,x] != " ": + return False + + if grid.shape[0] - n < y or y < 0: + # print("over board") + return False + + for i, char in enumerate(word): + char_x = x + char_y = y + i + + if not (grid[char_y, char_x] == " " or grid[char_y, char_x] == char): + # print("not matching") + return False + + if grid[char_y, char_x] == " ": + # check for horizonatal neighbors: + if char_x - 1 >= 0 and grid[char_y, char_x - 1] != " ": + # print("3") + return False + if char_x + 1 < grid.shape[1] and grid[char_y, char_x + 1] != " ": + # print("4") + return False + + else: + + # check if there is space before and after + if x - 1 >= 0 and grid[y, x - 1] != " ": + return False + if x + n < grid.shape[1] - 1 and grid[y,x + n] != " ": + return False + + if grid.shape[1] - n < x or x < 0: + # print("over board") + return False + + for i, char in enumerate(word): + char_x = x + i + char_y = y + + if not (grid[char_y, char_x] == " " or grid[char_y, char_x] == char): + # print("not matching") + return False + + if grid[char_y, char_x] == " ": + # check for vertical neighbors: + if char_y - 1 >= 0 and grid[char_y - 1, char_x] != " ": + # print("1") + return False + if char_y + 1 < grid.shape[0] and grid[char_y + 1, char_x] != " ": + # print("2") + return False + + return True + + + def get_crossover(word: str): + # returns Tuple of: (y,x, is_vertical?) or None + + shuffled_order = list(range(len(word))) + random.shuffle(shuffled_order) + + for index in shuffled_order: + # check for existing locations + char = word[index] + if char in locations: + char_locations = locations[char] + + for char_loc in char_locations: + # test vertical + y = char_loc[0] - index + x = char_loc[1] + + if check_if_fits(word, y, x, vertical=True): + return (y,x,True) + + # test horizontal + y = char_loc[0] + x = char_loc[1] - index + + if check_if_fits(word, y, x, vertical=False): + return (y,x,False) + + return None + + min_shape = min(w,h,30) + + # place first word: + first_word = get_word(max_length=min_shape, min_length=min(10,grid.shape[1] - 2)) + + # find random place: + x = random.randint(0, grid.shape[1] - len(first_word) - 1) + y = random.randint(0, grid.shape[0] - 1) + + place_word(first_word, y, x, vertical=False) + + i = 0 + + + current_density = density() + + while current_density < target_density: + word = get_word(max_length=(1 - current_density ** 0.4) * min_shape, + min_length=max(min(10, 0.5 * (1 - current_density ** 0.3) * min_shape), 2)) + + normalized_word = normalize_word(word) + + if normalized_word in word_hints: + continue + + # check if matching characters exist: + crossover = get_crossover(normalized_word) + + i += 1 + if i % 100000 == 0: + print(i) + if i > 100000: + break + + if crossover == None: + current_density = density() + continue + + y,x,is_vertical = crossover + + place_word(word, y,x, is_vertical) + + current_density = density() + + logging.info("crossword generation done after %s iterations", str(i)) + return grid, word_hints + diff --git a/server/en.json b/server/en.json new file mode 100644 index 0000000..c85baab --- /dev/null +++ b/server/en.json @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bb190fc29b24b23c11cf63d887dd272b4f1e5f217da090210c8d2a7bc446e936 +size 24746055 diff --git a/server/json_websockets.py b/server/json_websockets.py new file mode 100644 index 0000000..729c18e --- /dev/null +++ b/server/json_websockets.py @@ -0,0 +1,80 @@ +import websockets +import asyncio +import json +import logging + +logging.basicConfig(level=logging.INFO) + +class JsonWebsocketConnection(object): + + def __init__(self, + websocket: websockets.WebSocketServerProtocol): + + logging.info("incoming connection") + self._websocket = websocket + self._is_closed = False; + + def is_closed(self): + return self._is_closed + + async def close(self): + logging.info("closing connection") + try: + if self._is_closed: + return + self._websocket.close() + self._is_closed = True + except Exception as e: + logging.warning("error closing connection: %s", str(e)) + + async def send(self, message: dict): + string_message = json.dumps(message) + logging.debug("sending message: %s", string_message) + try: + await self._websocket.send(string_message) + except Exception as e: + logging.warning("error sending message: %s", str(e)) + + async def handle_message(self, message: dict): + pass # override this function + + async def run(self): + try: + async for message in self._websocket: + try: + json_message = json.loads(message) + await self.handle_message(json_message) + except ValueError as e: + logging.warning("received unprocessable message %s", str(e)) + + + except Exception as e: + logging.warning("error in websocket connection: %s", str(e)) + self._is_closed = True + finally: + self._is_closed = True + + + + + +class JsonWebsocketServer(object): + def __init__(self, handler_class: JsonWebsocketConnection, host:str = 'localhost', port:int = 8765): + self._host = host + self._port = port + self._handler_class = handler_class + + def run(self): + async def main(websocket: websockets.WebSocketServerProtocol, + path: str): + + connection = self._handler_class(websocket) + + await connection.run() + + start_server = websockets.serve(main, self._host, self._port) + + asyncio.get_event_loop().run_until_complete(start_server) + asyncio.get_event_loop().run_forever() + + diff --git a/server/main.py b/server/main.py new file mode 100644 index 0000000..73e0810 --- /dev/null +++ b/server/main.py @@ -0,0 +1,7 @@ +from . import json_websockets +from . import crossword_connection + +server = json_websockets.JsonWebsocketServer( + crossword_connection.CrosswordConnection +) +server.run() \ No newline at end of file diff --git a/server/session.py b/server/session.py new file mode 100644 index 0000000..e8bfcce --- /dev/null +++ b/server/session.py @@ -0,0 +1,48 @@ +import datetime as dt +from . import json_websockets +from . import crossword + + +class Session(object): + def __init__(self) -> None: + self.crossword = None + self.datetime_created = dt.datetime.utcnow() + self.connected_sockets = set() + + def cleanup(self): + sockets_to_remove = [] + for socket in self.connected_sockets: + if socket.is_closed(): + sockets_to_remove.append(socket) + + for socket in sockets_to_remove: + self.connected_sockets.remove(socket) + + def connect_socket(self, + websocket: json_websockets.JsonWebsocketConnection) -> None: + + self.cleanup() + self.connected_sockets.add(websocket) + + def disconnect_socket(self, + websocket: json_websockets.JsonWebsocketConnection) -> None: + if websocket in self.connected_sockets: + self.connected_sockets.remove(websocket) + + def get_sockets(self) -> json_websockets.JsonWebsocketConnection: + self.cleanup() + return self.connected_sockets + + def get_datetime_created(self) -> dt.datetime: + return self.datetime_created + + def create_crossword(self, width: int = 30, height: int = 30): + self.crossword = crossword.Crossword(width=width, + height=height, + lang_code="en") + + def get_crossword(self) -> crossword.Crossword: + if self.crossword is None: + self.create_crossword() + + return self.crossword diff --git a/server/websockets.ipynb b/server/websockets.ipynb new file mode 100644 index 0000000..f79fff0 --- /dev/null +++ b/server/websockets.ipynb @@ -0,0 +1,154 @@ +{ + "metadata": { + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.5" + }, + "orig_nbformat": 2, + "kernelspec": { + "name": "python395jvsc74a57bd0916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1", + "display_name": "Python 3.9.5 64-bit" + }, + "metadata": { + "interpreter": { + "hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1" + } + } + }, + "nbformat": 4, + "nbformat_minor": 2, + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import websockets\n", + "import asyncio\n", + "import json\n", + "import logging" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "class JsonWebsocketConnection(object):\n", + "\n", + " def __init__(self,\n", + " websocket: websockets.WebSocketServerProtocol):\n", + " \n", + " logging.debug(\"incoming connection\")\n", + " self._websocket = websocket\n", + " self._is_closed = False;\n", + " \n", + " def is_closed(self):\n", + " return self.is_closed\n", + " \n", + " async def close(self):\n", + " logging.debug(\"closing connection\")\n", + " try:\n", + " if self._is_closed:\n", + " return\n", + " self._websocket.close()\n", + " self._is_closed = True\n", + " except Exception as e:\n", + " logging.warning(\"error closing connection: %s\", str(e))\n", + " \n", + " async def send(self, message: dict):\n", + " string_message = json.dumps(message)\n", + " logging.debug(\"sending message: %s\", string_message)\n", + " try:\n", + " await self._websocket.send(string_message)\n", + " except Exception as e:\n", + " logging.warning(\"error sending message: %s\", str(e))\n", + " \n", + " async def handle_message(self, message: dict):\n", + " pass # override this function\n", + "\n", + " async def run(self):\n", + " try:\n", + " async for message in self._websocket:\n", + " try:\n", + " json_message = json.loads(message)\n", + " except ValueError as e:\n", + " logging.warning(\"received unprocessable message %s\", str(e))\n", + " await self.handle_message(message) \n", + " \n", + " except Exception as e:\n", + " logging.warning(\"error in websocket connection: %s\", str(e))\n", + "\n", + "\n", + "\n", + "class JsonWebsocketServer(object):\n", + " def __init__(self, handler_class: JsonWebsocketConnection, host:str = 'localhost', port:int = 8765):\n", + " self._host = host\n", + " self._port = port\n", + " self._handler_class = handler_class\n", + "\n", + " def run(self):\n", + " async def main(websocket: websockets.WebSocketServerProtocol,\n", + " path: str):\n", + "\n", + " connection = self._handler_class(websocket)\n", + "\n", + " connection.run()\n", + " \n", + " start_server = websockets.serve(main, self._host, self._port)\n", + "\n", + " asyncio.get_event_loop().run_until_complete(start_server)\n", + " asyncio.get_event_loop().run_forever()\n", + " \n", + "\n", + "def CrosswordConnection(JsonWebsocketConnection): \n", + " async def handle_message(self, message: dict):\n", + " await self.send({\"message\": \"hello\"})\n", + " \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "output_type": "error", + "ename": "RuntimeError", + "evalue": "This event loop is already running", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mRuntimeError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mserver\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mJsonWebsocketServer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mCrosswordConnection\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mserver\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 62\u001b[0m \u001b[0mstart_server\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mwebsockets\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mserve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmain\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_host\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_port\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 63\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 64\u001b[0;31m \u001b[0masyncio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_event_loop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_until_complete\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstart_server\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 65\u001b[0m \u001b[0masyncio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_event_loop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun_forever\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 66\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/lib/python3.9/asyncio/base_events.py\u001b[0m in \u001b[0;36mrun_until_complete\u001b[0;34m(self, future)\u001b[0m\n\u001b[1;32m 616\u001b[0m \"\"\"\n\u001b[1;32m 617\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_check_closed\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 618\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_check_running\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 619\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 620\u001b[0m \u001b[0mnew_task\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mfutures\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misfuture\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfuture\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m/usr/lib/python3.9/asyncio/base_events.py\u001b[0m in \u001b[0;36m_check_running\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 576\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m_check_running\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 577\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mis_running\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 578\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mRuntimeError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'This event loop is already running'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 579\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mevents\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_get_running_loop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32mNone\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 580\u001b[0m raise RuntimeError(\n", + "\u001b[0;31mRuntimeError\u001b[0m: This event loop is already running" + ] + } + ], + "source": [ + "server = JsonWebsocketServer(CrosswordConnection)\n", + "server.run()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ] +} \ No newline at end of file