Add filter creation in configuration creation command.

This commit is contained in:
gabriel becker 2022-12-09 15:42:00 +11:00
parent eaa82edc81
commit d46f59abc0
6 changed files with 116 additions and 24 deletions

5
.gitignore vendored
View File

@ -157,4 +157,7 @@ cython_debug/
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
.idea/
# Project Specific
scripts/

View File

@ -1,4 +1,5 @@
click
genanki
pandas
pyyaml
pyyaml
bullet

View File

@ -27,6 +27,7 @@ setup(
"genanki",
"pandas",
"pyyaml",
"bullet"
],
long_description_content_type='text/markdown',
)

View File

@ -14,12 +14,15 @@ class AnkimakerConfig(yaml.YAMLObject):
separators = ','
filters: List[List[FilterConfig]] = list()
def __init__(self, header=None, answer_column=None, question_column=None, filters=tuple()):
AnkimakerConfig.answer_column = answer_column
AnkimakerConfig.question_column = question_column
AnkimakerConfig.header = header
AnkimakerConfig.AnkimakerConfig = AnkimakerConfig
AnkimakerConfig.filters = list(map(lambda x: FilterConfig, filters))
def __init__(
self, separators=',', header=None, answer_column=None, question_column=None,
filters=tuple(), *args, **karhs
):
self.answer_column = answer_column
self.question_column = question_column
self.header = header
self.separators = separators
self.filters = _conditionally_create_new_filters(filters)
@staticmethod
def loader(configuration_content):
@ -31,8 +34,19 @@ class AnkimakerConfig(yaml.YAMLObject):
AnkimakerConfig.question_column = content.question_column
AnkimakerConfig.answer_column = content.answer_column
AnkimakerConfig.separators = content.separators
AnkimakerConfig.filters = [
[FilterConfig(**x) for x in or_filter]
for or_filter in content.filters
]
AnkimakerConfig.filters = _conditionally_create_new_filters(content.filters)
def _conditionally_create_new_filters(filters):
conf_has_filters = len(filters) > 0
if conf_has_filters:
should_cast_filter = not isinstance(filters[0][0], FilterConfig)
if should_cast_filter:
new_filters = [
[FilterConfig(**x) for x in or_filter]
for or_filter in filters
]
else:
new_filters = filters
return new_filters
return list()

View File

@ -1,7 +1,10 @@
import yaml
from typing import List, Union
class FilterConfig:
class FilterConfig(yaml.YAMLObject):
yaml_tag = '!fitlerconfig'
column: Union[str, int]
values: Union[List[Union[int, str]], Union[int, str]]
@ -10,7 +13,7 @@ class FilterConfig:
self.values = values
def __str__(self):
return f'<ankimaker.config.filters.FilterConfig {self.column}: {self.values} >'
return f'<F({self.column}:{self.values})>'
def __repr__(self):
return self.__str__()

View File

@ -1,10 +1,12 @@
import os
import yaml
import click
import pandas as pd
from typing import Type
from typing import Type, List
from bullet import Bullet, Input, YesNo
from ankimaker.config import Config
from ankimaker.config import Config, FilterConfig
__CONFIRMATION_QUESTION = """
@ -25,25 +27,93 @@ __COMMAND_SAMPLE = """ankimaker csv \
"""
__ADD_FILTER_QUESTION = """Do you want do add a filter to the configuration?"""
def create_config(input_file, output_path):
new_config = Config()
new_config.separators = handle_read_option(
input_file, read_option='sep', sep=new_config.separators
separators = handle_read_option(
input_file, read_option='sep', sep=','
)
new_config.header = handle_read_option(
input_file, read_option='header', header=new_config.header,
sep=new_config.separators, option_type=int
header = handle_read_option(
input_file, read_option='header', header=None,
sep=separators, option_type=int
)
new_config.question_column = get_column('question')
new_config.answer_column = get_column('answer')
question_column = get_column('question')
answer_column = get_column('answer')
filters = process_filters(input_file, header, separators)
new_config = Config(
separators=separators,
header=header,
question_column=question_column,
answer_column=answer_column,
filters=filters
)
save_file(new_config, output_path)
finish_message = __SUCCESS_MESSAGE.format(command=make_sample_command(input_file, output_path))
click.clear()
click.echo(finish_message)
def process_filters(input_file, header, separators):
df = pd.read_csv(input_file, header=header, sep=separators)
filters = add_filters_to_config(df)
return filters
def __inline_yes_or_no_question(question):
answer = YesNo(prompt=question, default='n').launch()
return answer
def add_filters_to_config(df: pd.DataFrame) -> List[List[FilterConfig]]:
config = Config()
should_add_filter = __inline_yes_or_no_question(__ADD_FILTER_QUESTION)
while should_add_filter:
config = add_filter_to_or_create_filter_group(df, config)
should_add_filter = __inline_yes_or_no_question(__ADD_FILTER_QUESTION)
return config.filters
def add_filter_to_or_create_filter_group(df: pd.DataFrame, config: Config) -> Config:
config_has_filters = len(config.filters) > 0
chosen_group = -1
if config_has_filters:
filter_options = [f'({"|".join(map(str, group)):.45s})' for group in config.filters]
filter_options = [f'Group{i+1}{s}' for i, s in enumerate(filter_options)]
cli = Bullet(
prompt="Select group: ",
choices=["Create new", *filter_options],
return_index=True,
)
chosen_group = cli.launch()[1] - 1
new_filter = create_filter_config(df)
if chosen_group < 0:
config.filters.append([new_filter])
else:
config.filters[chosen_group].append(new_filter)
return config
def create_filter_config(df: pd.DataFrame) -> FilterConfig:
options = list(df.columns)
cli = Bullet(
prompt="Select a columns to filter: ",
choices=list(map(str, options)),
return_index=True
)
chosen = cli.launch()[1]
filter_column = options[chosen]
columns_values = df[filter_column].unique()
values = Input(f'Which values fo filter out? values[{columns_values}]: ').launch()
new_filter = FilterConfig(column=filter_column, values=values)
return new_filter
def get_column(name: str) -> str:
answer = click.prompt(f'Which is your {name} column?', type=str, confirmation_prompt=True)
return answer