Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: internal cleanup #31

Merged
merged 1 commit into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
# Used by streamlit deployment
-e .
streamlit>=1.34.0
-e ."[streamlit]"
23 changes: 19 additions & 4 deletions sksmithy/_static/description.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,27 @@
# Description

Writing scikit-learn compatible estimators might be harder than expected.

While everyone knows about the `fit` and `predict`, there are other behaviours, methods and attributes that scikit-learn might be expecting from your estimator depending on:
While everyone knows about the `fit` and `predict`, there are other behaviours, methods and attributes that
scikit-learn might be expecting from your estimator depending on:

- The type of estimator you're writing.
- The signature of the estimator.
- The signature of the `.fit(...)` method.

Scikit-learn Smithy to the rescue: this tool aims to help you crafting your own estimator by asking a few questions about it, and then generating the boilerplate code.
Scikit-learn Smithy to the rescue: this tool aims to help you crafting your own estimator by asking a few
questions about it, and then generating the boilerplate code.

In this way you will be able to fully focus on the core implementation logic, and not on nitty-gritty details
of the scikit-learn API.

## Sanity check

Once the core logic is implemented, the estimator should be ready to test against the _somewhat official_
[`parametrize_with_checks`](https://scikit-learn.org/dev/modules/generated/sklearn.utils.estimator_checks.parametrize_with_checks.html#sklearn.utils.estimator_checks.parametrize_with_checks)
pytest compatible decorator.

## Official guide

In this way you will be able to fully focus on the core implementation logic, and not on nitty-gritty details of the
scikit-learn API.
Scikit-learn documentation on how to
[develop estimators](https://scikit-learn.org/dev/developers/develop.html#developing-scikit-learn-estimators).
4 changes: 0 additions & 4 deletions sksmithy/_static/tui.tcss
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,3 @@ OptionGroup {
height: 1fr;
border-right: vkey $background;
}

Message {
margin: 0 1;
}
33 changes: 4 additions & 29 deletions sksmithy/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re
import time
from importlib import resources
from importlib.metadata import version

from result import Err, Ok
Expand Down Expand Up @@ -32,6 +33,8 @@
else: # pragma: no cover
import streamlit as st

SIDEBAR_MSG: str = (resources.files("sksmithy") / "_static" / "description.md").read_text()

st.set_page_config(
page_title="Smithy",
page_icon="⚒️",
Expand All @@ -52,35 +55,7 @@
st.markdown("## Forge your own scikit-learn compatible estimator")

with st.sidebar:
st.markdown("""
# Description

Writing scikit-learn compatible estimators might be harder than expected.

While everyone knows about the `fit` and `predict`, there are other behaviours, methods and attributes that
scikit-learn might be expecting from your estimator depending on:

- The type of estimator you're writing.
- The signature of the estimator.
- The signature of the `.fit(...)` method.

Scikit-learn Smithy to the rescue: this tool aims to help you crafting your own estimator by asking a few
questions about it, and then generating the boilerplate code.

In this way you will be able to fully focus on the core implementation logic, and not on nitty-gritty details
of the scikit-learn API.

## Sanity check

Once the core logic is implemented, the estimator should be ready to test against the _somewhat official_
[`parametrize_with_checks`](https://scikit-learn.org/dev/modules/generated/sklearn.utils.estimator_checks.parametrize_with_checks.html#sklearn.utils.estimator_checks.parametrize_with_checks)
pytest compatible decorator.

## Official guide

Scikit-learn documentation on how to
[develop estimators](https://scikit-learn.org/dev/developers/develop.html#developing-scikit-learn-estimators).
""")
st.markdown(SIDEBAR_MSG)

sample_weights = False
linear = False
Expand Down
27 changes: 8 additions & 19 deletions sksmithy/tui/_components.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import sys
from importlib import metadata, resources
import webbrowser
from importlib import resources
from pathlib import Path

from result import Err, Ok
from rich.console import RenderableType
from textual import on
from textual.app import ComposeResult
from textual.containers import Container, Grid, Horizontal, ScrollableContainer
from textual.widgets import Button, Collapsible, Input, Select, Static, Switch, TextArea
from textual.widgets import Button, Collapsible, Input, Markdown, Select, Static, Switch, TextArea

from sksmithy._models import EstimatorType
from sksmithy._parsers import check_duplicates, name_parser, params_parser
Expand Down Expand Up @@ -336,25 +336,14 @@ class ForgeRow(Grid):
"""Row grid for forge."""


class Title(Static):
pass


class OptionGroup(ScrollableContainer):
pass


class Message(Static):
pass


class Version(Static):
def render(self: Self) -> RenderableType:
return f"Version: [b]{metadata.version('sklearn-smithy')}"


class Sidebar(Container):
def compose(self: Self) -> ComposeResult:
yield Title("Description")
yield OptionGroup(Message(SIDEBAR_MSG), Version())
yield Version()
yield OptionGroup(Markdown(SIDEBAR_MSG))

def on_markdown_link_clicked(self: Self, event: Markdown.LinkClicked) -> None:
# Relevant discussion: https://github.com/Textualize/textual/discussions/3668
webbrowser.open_new_tab(event.href)
10 changes: 2 additions & 8 deletions sksmithy/tui/_tui.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from importlib import resources
from importlib import metadata, resources
from typing import ClassVar

from textual.app import App, ComposeResult
Expand Down Expand Up @@ -29,12 +29,6 @@
from typing_extensions import Self


TEXT = """\
import pandas as pd
import numpy as np
"""


class ForgeTUI(App):
"""Textual app to forge scikit-learn compatible estimators."""

Expand All @@ -61,7 +55,7 @@ def on_mount(self: Self) -> None:
def compose(self: Self) -> ComposeResult:
"""Create child widgets for the app."""
yield Container(
Header(),
Header(icon=f"v{metadata.version('sklearn-smithy')}"),
ScrollableContainer(
Horizontal(Name(), Estimator()),
Horizontal(Required(), Optional()),
Expand Down