Add filter creation in configuration creation command.
This commit is contained in:
parent
eaa82edc81
commit
d46f59abc0
5
.gitignore
vendored
5
.gitignore
vendored
@ -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/
|
@ -1,4 +1,5 @@
|
||||
click
|
||||
genanki
|
||||
pandas
|
||||
pyyaml
|
||||
pyyaml
|
||||
bullet
|
1
setup.py
1
setup.py
@ -27,6 +27,7 @@ setup(
|
||||
"genanki",
|
||||
"pandas",
|
||||
"pyyaml",
|
||||
"bullet"
|
||||
],
|
||||
long_description_content_type='text/markdown',
|
||||
)
|
||||
|
@ -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()
|
||||
|
@ -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__()
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user