In the middle of the desert you can say anything you want
I decided that I should go back to the digital garden roots of this, and use this note as a small journey of conceptual/high-level things that I believe would make me a better programmer.
And that I’ll re-read this every time I think of something to add here.
The master thesis has given me ample occasions to find out about these things, and will give me ample occasions to use them before it’s over. Just like with dashes ([[231205-1311 Notes from paper review#Hyphens vs dashes (em-dash, en-dash)]]), practiced enough it will stick.
(the post that started this page)
After refactoring my third program to use OOP this quarter, this be the wisdom:
(Unless threads/parallelism, then it means think harder).
Context: UPCrawler & GBIF downloader
TL;DR: downloading bits and writing to disk each is sometimes better than to keep them in a dataframe-like-ish structure that gets written to disk in bulk. And the presence of a file on disk can be signal enough about its state, making separate data structures tracking that unneeded.
When downloading something big and of many parts, my first instinct is/was to put it into pretty dataclasses-like structures, (maybe serializable through JSONWizard), collect it and write it down.
If I think I need some intermediate results, I’d do checkpoints or something similar, usually in an ugly function of the dataframe class to do file handling etc.
Often one can download the individual bit and write it to disk, maybe inside a folder. Then a check of whether it has been downloaded would be literally a check if the file exists, making them self-documenting in a small way.
(And generally - previously I had this when writing certain converters and the second worst thing I have written in my life - I’d have dataclasses with kinds of data and separate boolean fields with has_X_data
and stuff. I could have just used whether the data fields are None
to signify if they are there or not instead of …that.)
Doing it like that makes they can happily be parallelized or whatever, downloaded separately.
In the UPCrawler, I was blocked by the need to add to each article a language-independent tag, that was an URI and one to two translations. I wanted to get the entire chunk, gather all translations of tags from them, label the chunks correctly, then serialize.
This is idiotic if I can just download the articles with the info I have to disk and then run a separate script to gather all tags from them and do this. (Or I can gather the tags in parallel while this is happening but don’t let the need to complete it block my download)
Context: UPCrawler; a pattern I’ve been noticing.
First I crawled and prased pages like Архив 26 сентября 2023 года | Украинская правда to get the URI of the articles published on that day, did permutations of the URI to get the other languages if any, and got the list of URIs of articles to crawl.
Yesterday I realized that UPravda has sitemaps:
https://www.pravda.com.ua/sitemap/sitemap-2023-04.xml.gz, and that I can use something like advtools
to nicely parse them, and advtools gave me back the data as a pandas DataFrame — leading me to the insight that I can analyze parse regex etc. the uris using pandas. Including things like groupby article ID to give me immediately the 1..3 translations of that article. Instead of me needing to track it inside a (guess what) datastructure based on dataclasses.
This inspired me to look for better solutions of another problem plaguing me - tags, with their UK and RU translations.
I thought maybe I could check if the website has a nice listing of all existing tags. And of course it does: Теги | Украинская правда
Damn.
Make an effort — really, an effort - to look at the forest, and for each problem think if there’s an easier way to do that than the one I started implementing without thinking. Including whether there are already structures in place I know about but from other contexts.
I learned to look for solutions inside python stdlib, remembering about this at the right moments should be easy as well.
A lot of my code is more complex than needed, and to heavy for its own good/purpose. Connected to the above: think (draw? architect?) of a good design before I start writing the code. A sound structure from the beginning will remove many of the corner cases that end up in ugly code to maintain.
In the context of 240118-1516 RU interference masterarbeit task embeddings mapping, especially given that the models take a while to load.
StillImage
is only one of them: MediaType (GBIF Parsers 0.62-SNAPSHOT API)image/jpeg
mime type: https://data-blog.gbif.org/post/gbif-multimedia/Couldn’t find a proper list, but one can always jq
> curl https://api.gbif.org/v1/occurrence/search\?taxonKey\=4\&limit\=300 | jq -C | grep "format.*image" | sort | uniq
"format": "image/gif",
"format": "image/jpeg",
"format": "image/png",
"http://purl.org/dc/terms/format": "image/gif",
"http://purl.org/dc/terms/format": "image/jpeg",
"http://purl.org/dc/terms/format": "image/png",
class LoggingFilter(logging.Filter):
def filter(self, record):
if "Connection pool is full" in record.getMessage():
return False
logger_cpool = logging.getLogger("urllib3.connectionpool")
logger_cpool.addFilter(LoggingFilter())
False
, then the record is silenced, otherwise it gets logged normally.logrecord.message
but I didn’t have it in my case (todo), but I found getMessage()
.How to list all existing loggers using python.logging module - Stack Overflow:
import logging
loggers = [logging.getLogger(name) for name in logging.root.manager.loggerDict]
warnings — Warning control — Python 3.12.0 documentation:
import warnings
def fxn():
warnings.warn("deprecated", DeprecationWarning)
with warnings.catch_warnings():
warnings.simplefilter("ignore")
fxn()
logging — Logging facility for Python — Python 3.12.0 documentation
# capture is True for enabling, False for disabling
logging.captureWarnings(capture)
# all warnings will become logs from logger 'py.warnings' with severity WARN
Goal: retry running function X times max Scenario: networking-ish issues
Solution: I came up with the thing below. It gets an optional list of acceptable exception types, and retries N times every time it gets one of them. As soon as it gets an unacceptable exception it passes it further. As soon as the function runs successfully it returns the function’s return value.
Can repeat infinite times and can consider all exceptions acceptable if both params are given empty or None.
from urllib3.exceptions import ProtocolError
from functools import partial
from itertools import count
from typing import Optional
def _try_n_times(fn, n_times: Optional[int]=3, acceptable_exceptions: Optional[tuple] =(ProtocolError, )):
""" Try function X times before giving up.
Concept:
- retry N times if fn fails with an acceptable exception
- raise immediately any exceptions not inside acceptable_exceptions
- if n_times is falsey will retry infinite times
- if acceptable_exceptions is falsey, all exceptions are acceptable
Returns:
- after n<n_times retries the return value of the first successdful run of fn
Raises:
- first unacceptable exceptions if acceptable_exceptions is not empty
- last exception raised by fn after too many retries
Args:
fn: callable to run
n_times: how many times, 0 means infinite
acceptable_exceptions: iterable of exceptions classes after which retry
empty/None means all exceptions are OK
TODO: if this works, integrate into load image/json as well (or increase
the number of retries organically) for e.g. NameResolutionErrors
and similar networking/connection issues
"""
last_exc = None
for time in range(n_times) if n_times else count(0):
try:
# Try running the function and save output
# break if it worked
if time>0:
logger.debug(f"Running fn {time=}")
res = fn()
break
except Exception as e:
# If there's an exception, raise bad ones otherwise continue the loop
if acceptable_exceptions and e.__class__ not in acceptable_exceptions:
logger.error(f"Caught {e} not in {acceptable_exceptions=}, so raising")
raise
logger.debug(f"Caught acceptable {e} our {time}'th time, continuing")
last_exc = e
continue
else:
# If loop went through without a single break it means fn always failed
# we raise the last exception
logger.error(f"Went through {time} acceptable exceptions, all failed, last exception was {last_exc}")
raise last_exc
# Return whatever fn returned on its first successful run
return res
The main bit here was that I didn’t want to use any magic values that might conflict with whatever the function returns (if I get a None/False how can I know it wasn’t the function without ugly complex magic values?)
The main insight here is the else
clause w/ break
.
fn
is run as fn()
and partial
is a good way to generate them
EDIT: (ty CH) you can also just declare a function, lol
.
!\cite{a,b}
(-> [2,3]
) for multiple citations!Moved theory to rl/garden: Hyphens vs dashes vs en-dash em-dash minus etc - serhii.net1
(It seems I can’t do links to the garden/
portion of the website/obyde/obsidian/vault thing, so moved things below there and doing a hard link from here…)
Updated my (former mirrorboard / pchr8board / …) dvorak xkb layout (220604-0136 Latest iteration of my custom dvorak-UA-RU xkb layout / 230209-0804 Small update to my keyboard layout / pchr8/dvorak_mirrorboard: A Dvorak version of the MirrorBoard) to get an en-dash and em-dash on level5 of the physical/querty keys N and M, so for example <S-Latch-M>
gives me an em-dash/—.
I may update the picture later.
I hereby promise to use them as much as possible everywhere to remember which ones they are.
(I always hated small dashes in front of two-letter+ entities because it feels wrong, and an en-dash for such cases removes some of the pressure I surprisingly feel when I have to do that, it kinda matches my intuition that a different symbol is needed for longer compound words for clarity reasons.)
This also reminds me that I have quite a few unused Level3 keys on the right side of the keyboard, maybe I can take a second look at it all.
/garden/days/2023-12-06-231206-1501-hyphens-vs-dashes-vs-en-dash-em-dash-minus-etc/ / https://serhii.net/garden/days/2023-12-06-231206-1501-hyphens-vs-dashes-vs-en-dash-em-dash-minus-etc/ /
Importing Overleaf to Zotero saw that most citations aren’t found because citation keys are now different from before. Somehow my citation format authorName1998
when syncing with Overleaf becomes author_name_paper_1998
.
The solution seems to be pinning citation keys in Better Bibtex: Citation Keys :: Better BibTeX for Zotero
This should guarantee that the keys won’t be automatially (re) generated but stay fixed forever.
This translates to my overleaf export it seems.
Also: when importing from clipboard, the resulting citeKey is also pinned, which is more than logical.
First paper I write with ONE column, which required a change to my usual image inclusion process.
Generally I’d do:
\begin{figure}[t]
\includegraphics[width=0.4\linewidth]{images/mypic}
\caption{My caption}
\label{fig:mylabel}
\end{figure}
Looking into Overleaf documentation about Inserting Images, found out about wrapfig
. Examples from there:
\usepackage{wrapfig}
% ...
\begin{wrapfigure}{L}{0.25\textwidth}
\centering
\includegraphics[width=0.25\textwidth]{contour}
\end{wrapfigure}
The magic is:
\begin{wrapfigure}[lineheight]{position}{width}
...
\end{wrapfigure}
position
for my purposes is lL
/rR
. Uppercase version allows the figure to float, lowercase means exactly here (a la h
in figure
)
The first argument lineheight
is how many lines should the picture used. Has to be determined later, but gets rid of the large amount of whitespace that sometimes appears under it.
Also — doesn’t like tops/bottoms of pages, section titles, and enums, and creates absolutely ugly results. This really matters.
As a bonus, position options from includegraphics, stolen from Overleaf and converted to table by ChatGPT:
Parameter | Position |
---|---|
h | Place the float here, i.e., approximately at the same point in the source text |
t | Position at the top of the page |
b | Position at the bottom of the page |
p | Put on a special page for floats only |
! | Override internal parameters LaTeX uses for determining “good” float positions |
H | Places the float at precisely the location in the LATEX code |
Problem: new overleaf project using new template (so no copying the project through interface->copy). The projects have separate folders with multiple files inside, mostly images.
Previously I discovered that you can import files from another overleaf project, without having to download/upload them individually, but I’m still unsure about how linked they are and what happens if they get deleted from the original project.
Today I discovered a better way: download the overleaf project zip, unzip locally, then drag and drop the (multiple!) files to a newly created folder in the new project, all together.
TIL about the exciting world of Chrome extensions for Overleaf. Most of them seem to have GPT and copilot in the title but there are interesting ones as well.
Tried https://www.writefull.com/writefull-for-overleaf and it’s alright I guess
EDIT: very quickly hit the limit of my free account :( but it had potential
Something about the recent changes in UA, both the new 2019 orthography and feminitives [^@synchak2023feminine]
ChatGPT creating his own feminitives! https://chat.openai.com/share/b7e49b4b-9a58-4bf9-80fa-ec11f551b503 has the absolute joy “фахівецька”.
Old attempts:
I think this format works well enough: https://chat.openai.com/share/9374e47b-f63c-4f97-bfd4-528b11ea0f68
Наведи будь-ласка однозначні короткі дефініції цим професіям чи словам, так, щоб по ним було однозначно очевидно про яку саме професію йде мова.
Зміни дефініції так, щоб вони стали фразами, де мова однозначно йде про жінку. Придумай різні варіанти жінок, про яких йде мова, умовно: моя сестра, моя жінка, колишня однокласниця, імена (Марія, Марія Петрівна, Кассандра). Але придумай і свої різноманітніші приклади.
Уникай використання самого слова чи поняття у визначеннях. Уникай слів "фахівецька" чи "спеціалістка".
Наприклад:
Актор: "Моя жінка виконує ролі на сцені чи екрані"
Акушерка: "Марія Петрівна допомагає при пологах"
Автор: "Я знаю дівчину, яка пише твори та книжки".
Будь творчим. Але професія, про яку іде мова, має все рівно бути однозначно зрозумілою.
- - -
Зроби це для всіх цих слів:
абітурієнтка
абстракціоністка
автоматниця
автомобілістка
авторка
агітаторка
агрономка
адвокатка
анархіст
англієць
антрополог
асистентка
астронавт
аптекар
Можеш зробити з цього json наступного формату?
{'job': '',
'description': ''
}
I asked it to randomly change some of them to be men, so it doesn’t get additional cues. This seems to confuse it and get at least some feminitives to be wrong (“водій”)
https://chat.openai.com/share/f8a61785-2d2b-4aeb-a24c-45708e40eee3 The format to get it to answer could be:
Я дам список речень, для кожного наведи одне слово, яке це речення логічно завершує. Це має бути іменник, назва ролі або професії.
"Моя колишня однокласниця готується до вступу у виш, здібна та наполеглива. Вона - "
"Мій брат творить вражаючі образи, захоплюючи глядачів абстракцією. Він - "
"Марія Петрівна керує автоматизованими процесами, забезпечуючи ефективну роботу виробництва. Вона - "
"Кассандра вправно керує автомобілем, виявляючи високий рівень водійської майстерності. Вона - "
"Мій чоловік втілює свої ідеї у власних творах, пишучи захоплюючі оповідання та книги. Він - "
"Мій колишній однокласник ефективно підбадьорює та мобілізує громаду, виступаючи за ідеї. Він - "
"Марія вивчає та вдосконалює методи сільськогосподарського виробництва, бережливо ставлячись до рослин. Вона - "
"Мій брат захищає права та інтереси клієнтів у суді, професійно вирішуючи юридичні питання. Він - "
"Кассандра відстоює ідеї анархії, агітуючи за вільні та незалежні структури суспільства. Вона - "
"Мій чоловік є представником англійської національності, пишаючись своєю культурною спадщиною. Він - "
"Марія Петрівна вивчає різноманітні аспекти людської культури та поведінки, розкриваючи таємниці соціального взаємодії. Вона - "
"Мій колишній однокласник відомого вченого активно допомагає у проведенні досліджень та лабораторних робіт. Він - "
"Мій брат вивчає космос та вчиться до майбутнього польоту у космос як астронавт. Він - "
"Марія забезпечує нашу місцеву аптеку ліками та медичними засобами, дбаючи про здоров'я громади. Вона - "
I get:
"Моя колишня однокласниця готується до вступу у виш, здібна та наполеглива. Вона - абітурієнтка."
"Мій брат творить вражаючі образи, захоплюючи глядачів абстракцією. Він - художник."
"Марія Петрівна керує автоматизованими процесами, забезпечуючи ефективну роботу виробництва. Вона - менеджер виробництва."
"Кассандра вправно керує автомобілем, виявляючи високий рівень водійської майстерності. Вона - водій."
"Мій чоловік втілює свої ідеї у власних творах, пишучи захоплюючі оповідання та книги. Він - письменник."
"Мій колишній однокласник ефективно підбадьорює та мобілізує громаду, виступаючи за ідеї. Він - активіст."
"Марія вивчає та вдосконалює методи сільськогосподарського виробництва, бережливо ставлячись до рослин. Вона - агроном."
"Мій брат захищає права та інтереси клієнтів у суді, професійно вирішуючи юридичні питання. Він - адвокат."
"Кассандра відстоює ідеї анархії, агітуючи за вільні та незалежні структури суспільства. Вона - анархістка."
"Мій чоловік є представником англійської національності, пишаючись своєю культурною спадщиною. Він - англієць."
"Марія Петрівна вивчає різноманітні аспекти людської культури та поведінки, розкриваючи таємниці соціального взаємодії. Вона - антропологиня."
"Мій колишній однокласник відомого вченого активно допомагає у проведенні досліджень та лабораторних робіт. Він - асистент вченого."
"Мій брат вивчає космос та вчиться до майбутнього польоту у космос як астронавт. Він - астронавт."
"Марія забезпечує нашу місцеву аптеку ліками та медичними засобами, дбаючи про здоров'я громади. Вона - фармацевтка."
profession: str
descriptions_male: list[str]
descriptions_female: list[str]
valid_feminitives: list[str]
valid_masc.: list[str]
LLM: A CLI utility and Python library for interacting with Large Language Models (for later: install the GPT4All plugin for local uncensored models)
Templates: Prompt templates - LLM
llm templates edit m-fem
prompt: >
Наведи будь-ласка однозначні короткі дефініції цим професіям чи словам, так, щоб по ним було однозначно очевидно про яку саме професію йде мова.
Зміни дефініції так, щоб вони стали фразами, де мова однозначно йде про жінку. Придумай різні варіанти жінок, про яких йде мова, умовно: моя сестра, моя жінка, колишня однокласниця, імена (Марія, Марія Петрівна, Кассандра). Але придумай і свої різноманітніші приклади.
Уникай використання самого слова чи поняття у визначеннях. Уникай слів 'фахівецька' чи 'спеціалістка'.
Наприклад:
Актор: "Моя жінка виконує ролі на сцені чи екрані"
Акушерка: "Марія Петрівна допомагає при пологах"
Автор: "Я знаю дівчину, яка пише твори та книжки".
Будь творчим. Але професія, про яку іде мова, має все рівно бути однозначно зрозумілою.
Зроби це для всіх цих слів: $input
> echo "водій, програміст, вчений" | llm -t m-fem
Водій: "Моя сестра допомагає перевозити пасажирів та вантажі на автомобілі"
Програміст: "Моя однокласниця створює програми та розробляє веб-сайти"
Вчений: "Кассандра проводить дослідження і займається науковими відкриттями"
Damn!
# Why three?
> echo "водій, програміст, вчений" | llm -t m-fem -m 3.5-16k
Водій: "Моя колишня однокласниця розвозить пасажирів на таксі"
Водій: "Марія перевозить вантажі на великогабаритних автомобілях"
Водій: "Кассандра працює на міському автобусному маршруті"
Програміст: "Моя сестра створює програми та веб-сайти для клієнтів"
Програміст: "Марія Петрівна програмує роботів та штучний інтелект"
Програміст: "Кассандра розробляє мобільні додатки для смартфонів"
Вчений: "Моя жінка проводить експерименти та дослідження в лабораторії"
Вчений: "Марія займається науковим дослідженням у галузі генетики"
Вчений: "Кассандра вивчає космос та проводить астрономічні спостереження"
> echo "водій, програміст, вчений" | llm -t m-fem -m 4
Водій: "Моя сестра керує автобусом, вантажівкою або автомобілем."
Або: "Моя дружина впевнено сідає за кермо і відповідально перевозить пасажирів."
Або: "Ката наполягає, що її життєвою страстю є перевезення товарів на великі відстані."
Програміст: "Моя колишня однокласниця говорить мовою Python, Java або C++, розробляючи програмне забезпечення."
Або: "Моєму серцю неодмінно стане на шляху любов до жінок, що пишуть код і створюють додатки."
^C
I got it, larger models interpret “definitions” etc. as an instruction to create multiple options for each word! Wow!
COMPLETE_PROMPT: str = """ Наведи будь-ласка однозначні короткі дефініції цим професіям чи словам, так, щоб по ним було однозначно очевидно про яку саме професію йде мова.
Зміни дефініції так, щоб вони стали фразами, де мова однозначно йде про жінку. Придумай різні варіанти жінок, про яких йде мова, умовно: моя сестра, моя жінка, колишня однокласниця, імена (Марія, Марія Петрівна, Кассандра). Але придумай і свої різноманітніші приклади.
Уникай використання самого слова чи поняття у визначеннях. Уникай слів 'фахівецька' чи 'спеціалістка'.
Наприклад:
Актор: "Моя жінка виконує ролі на сцені чи екрані"
Акушерка: "Марія Петрівна допомагає при пологах"
Автор: "Я знаю дівчину, яка пише твори та книжки".
Будь творчим. Але професія, про яку іде мова, має все рівно бути однозначно зрозумілою.
"""
FORMAT_INSTRUCTIONS = """
Формат виводу - JSON, по обʼєкту на кожну дефініцію. Обʼєкт виглядати таким чином:
{
"profession": "",
"description": ""
}
Виводь тільки код JSON, без ніяких додаткових даних до чи після.
"""
prompt = PromptTemplate(
template="{complete_prompt}\n{format_instructions}\n Професія, яку потрібно описати: {query}\n",
input_variables=["query"],
partial_variables={
"format_instructions": FORMAT_INSTRUCTIONS,
"complete_prompt": COMPLETE_PROMPT,
},
)
json_parser = SimpleJsonOutputParser()
prompt_and_model = prompt | model | json_parser
output = prompt_and_model.invoke({"query": "архітектор,програміст"})
[{'description': ['Моя сестра працює в школі і навчає дітей',
'Дочка маминої подруги викладає у початковій '
'школі'],
'profession': 'Вчителька'},
{'description': ['Моя сестра створює картини, які відображають '
'абстрактні ідеї та почуття',
'Дівчина, яку я знаю, малює абстракціоністські '
'полотна'],
'profession': 'абстракціоністка'},
{'description': ['Моя сестра вміє водити автомобіль',
'Дівчина знає всі тонкощі водіння автомобіля'],
'profession': 'автомобілістка'},
{'description': ['Моя сестра пише книги та статті',
'Дівчина, яку я знаю, створює літературні твори',
'Марія Петрівна є відомою письменницею'],
'profession': 'авторка'},
{'description': ['Моя сестра вивчає рослинництво та допомагає '
'фермерам у вирощуванні культур',
'Дочка маминої подруги консультує селян щодо '
'вибору добрив та захисту рослин'],
'profession': 'агрономка'},
{'description': ['Моя сестра захищає клієнтів у суді',
'Дочка маминої подруги працює в юридичній фірмі'],
'profession': 'адвокатка'},
{'description': ['Моя сестра бореться за відсутність влади та '
'держави',
'Дівчина, яку я знаю, вірить у самоорганізацію '
'суспільства без уряду'],
'profession': 'анархіст'},
{'description': ['Моя колишня однокласниця живе в Англії',
'Моя сестра вивчає англійську мову'],
'profession': 'англієць'},
{'description': ['Моя сестра вивчає культури та традиції різних '
'народів',
'Дочка маминої подруги досліджує етнічні групи '
'та їхні звичаї'],
'profession': 'антрополог'},
{'description': ['Моя сестра допомагає виконувати різні завдання '
'на роботі',
'Дочка маминої подруги організовує робочий '
'графік та зустрічі'],
'profession': 'асистентка'},
{'description': ['Моя сестра досліджує космос як астронавт',
'Дочка маминої подруги летить у космос як '
'астронавт'],
'profession': 'астронавт'},
{'description': ['Моя сестра працює в аптеці та консультує '
'пацієнтів з ліками',
'Дочка маминої подруги видає ліки в аптеці'],
'profession': 'аптекар'},
{'description': ['Моя сестра працює в школі та навчає дітей',
'Дочка маминої подруги викладає у початковій '
'школі'],
'profession': 'Вчителька'}]
These generate worse prompts:
COMPLETE_PROMPT: str = """Наведи будь-ласка {N_PROFS} однозначні короткі дефініції цій професії або слову, так, щоб по ним було однозначно очевидно про яку саме професію йде мова.
Зроби два варіанта дефініцій:
1) Зміни дефініції так, щоб вони стали фразами, де мова однозначно йде про жінку. Придумай різні варіанти жінок, про яких йде мова, умовно: {WOMEN_VARIANTS}. Але придумай і свої різноманітніші приклади.
2) Те саме, але про чоловіків. Опис професії де мова йде про чоловіка.
Уникай використання самого слова чи поняття у визначеннях. Уникай слів 'фахівецька' чи 'спеціалістка'.
Наприклад:
Актор: "Моя жінка виконує ролі на сцені чи екрані", "Мій чоловік виконує ролі на сцені чи екрані"
Акушерка: "Марія Петрівна допомагає при пологах", "Валентин Петрович допомагає при пологах"
Автор: "Я знаю дівчину, яка пише твори та книжки", "Я знаю хлопця, який пише твори та книжки"
Будь творчим. Але професія, про яку іде мова, має все рівно бути однозначно зрозумілою.
"""
FORMAT_INSTRUCTIONS = """
Формат виводу - JSON. Обʼєкт виглядати таким чином:
{
"profession": "",
"description": [
[description_female, description_male],
[description_female, description_male],
]
}
В полі description список всіх згенерованих дефініцій, для кожної з якої надається пара жіночого опису і чоловічого.
Виводь тільки код JSON, без ніяких додаткових даних до чи після.
"""
[[231010-1003 Masterarbeit Tagebuch#Feminitives task 231204-1642 Masterarbeit evaluation task new UA grammar and feminitives]]