Open xiekun opened 3 years ago
For existing python users, rather than x_columns,y_columns,series, use name x,y,hue/color, people with matplotlib/seaborn/plotly will pick it up easier
I agree with this comment, will implement
I think there is some inconsistency in class name that will hinder user when building a mental model
I agree, let's Option 1 classes that represent actions and Option 2 class that represent objects. To your point at the moment I have a mix of 2. I'll walk through my thinking using the SheetsFrame
parent class as an example. I do agree that I could move to an object based approach but want to talk through it.
Action Approach
I originally defined the classes as actions because the initialization of a GetFrame
class and CreateFrame
class needed to be different. For GetFrame
the user needs to provide cells that would bound the rows/columns to retrieve, for CreateFrame
a pandas dataframe is required.
Object approach
If I were to refactor to take an object based approach perhaps I would do the following:
- class: Frame
- method: __init__ --> initializes empty object
- method: create --> runs CreateFrame(args).execute()
- method: get --> runs GetFrame(args.execute())
- property: data --> only returns `data` if either `create` or `get` has been executed
I think this structure could be feasible for a number of different objects
- class: Chart
- method: __init__ --> initializes empty object
- method: create --> runs existing class Chart(args).execute()
- method: get --> runs a method to get an existing chart in sheets
- property: chart_id --> only returns `chart_id` if either `create` or `get` has been executed
- class: Presentation
- method: __init__ --> initializes empty object
- method: create --> runs CreatePresentation(args).execute()
- method: get --> runs a method to get an existing presentation and get all the slides contained in the presentation
- method: add_slide --> runs CreateSlide(args).execute()
- method: rm_slide --> runs a method to remove a slide
- method: update_slide --> runs a method to update data on a slide (would need to think about this more)
- property: presentation_id --> only returns a `presentation_id` if either `create` or `get` has been executed
- property: sld_id --> returns a list of `sld_id` if either `create` or `get` has been executed
- class: SpreadSheet
- method: __init__ --> initializes empty object
- method: create --> runs CreateSpreadsheet(args).execute()
- method: get --> runs a method to get an existing spreadsheet and get all the sheets contained in the presentation
- method: add_sheet --> runs CreateSlide(args).execute()
- method: rm_sheet --> runs a method to remove a slide
- property: spreadsheet_id --> only returns a `spreadsheet_id` if either `create` or `get` has been executed
- property: sheet_id --> returns a list of `sheet_id` if either `create` or `get` has been executed
new_presentation = Presentation(Slides = [slide1,slide2]) #Create at initilization
I'm thinking of not creating a Slide
object for simplicity. Like sheets I think slides have to belong to their parent object (presentations) and can't be initialized on their own
new_series = Scatter(argument that describe the series, except the type)
This was something I spent a lot of time thinking about. Based on the type of series only certain parameters can be set (e.g. a column chart can't have a line_width). I enforced this through creating separate classes with unique initializations.
Perhaps is an alternative is like so:
- class: Series
- method: __init__ --> initializes empty series object
- method: scatter --> initializes scatterplot
- method: line --> initialized line
.
.
.
Before I test anything and since there is a refractoring on the horizon, if you are considering to do
- class: Frame
- method: __init__ --> initializes empty object
- method: create --> runs CreateFrame(args).execute()
- method: get --> runs GetFrame(args.execute())
- property: data --> only returns `data` if either `create` or `get` has been executed
It might be good to create a super class with init/create/get
and for all sub classes to inherit to be more DRY.
Before I test anything and since there is a refractoring on the horizon, if you are considering to do
- class: Frame - method: __init__ --> initializes empty object - method: create --> runs CreateFrame(args).execute() - method: get --> runs GetFrame(args.execute()) - property: data --> only returns `data` if either `create` or `get` has been executed
It might be good to create a super class with
init/create/get
and for all sub classes to inherit to be more DRY.
Do you prefer the action based or object based classes? I haven't completed decided yet to do the refactoring
object :)
@xiekun @jfyu just pushed the refactor to main branch 😄 . Plus I added table functionality. For some of the other feedback like logging I need to create issues and resolve later
Description
Play around with the package and offer opinions
What I Did
usage.ipynb
, troubleshoot any errorsslides.py
andaddchart.py
Issues Noted:
usage.ipynb
, I was able to directly runcreds = flow.run_local_server()
without specifying a portiris = datasets.load_iris(as_frame = True)['data']
missing dependency on sklearn, maybe embed a flat file directly in repo?Feedback:
I think there is some inconsistency in class name that will hinder user when building a mental model, Currently it is:
It can be consistent this way:
Expectation: When user see
CreatePresentation
, they intuitively will expectCreateChart
and vice versa.The method of initialize is also not consistent, currently it is:
I think rest of approach should be consistent to this, i.e
and adjusting each object via add/remove method with consistent pattern i.e.
Specifically on charts, a nice feature in popular packages is FacetGrid , and this is not doable in Excel/Sheets manually. This will become an attractive feature but requires a bit of planning in class structure:
A styler object that can be applied on presentation/slide/chart level, this is already covered in your feature planning
You can make argument name more mainstream, it will reduce cognitive overhead for new users:
These are all opinion, I didn't quite get how Gsuite api works or if any of these is possible.