├── .github └── ISSUE_TEMPLATE.md ├── .gitignore ├── README.md ├── assets └── img │ └── activation_screen.png └── plugins ├── README.md └── examples ├── loaders ├── load_dummy_data.ipynb └── load_dummy_data.py ├── projects ├── blog_post_demo_bluerock_analytics │ ├── br_analytics │ │ ├── __init__.py │ │ ├── calculations.py │ │ ├── figure_plugins.py │ │ ├── loader_plugins.py │ │ ├── transformation_plugins.py │ │ └── view_plugins.py │ ├── data │ │ ├── AAPL.csv │ │ └── GOOG.csv │ ├── monday_no_plugins_result.py │ └── wednesday_with_plugins_result.py └── sales_plugin_demo │ ├── README.md │ ├── abc_analytics │ ├── __init__.py │ ├── calculations.py │ ├── figure_plugins.py │ ├── loader_plugins.py │ └── transformation_plugins.py │ ├── bam - plugin demo.ipynb │ └── bam - plugin demo.py ├── transformations ├── calculate_diff_within_groups.ipynb ├── calculate_diff_within_groups.py ├── calculate_revenue_shares_by_group.ipynb ├── calculate_revenue_shares_by_group.py ├── drop_columns_with_missing_values.ipynb ├── drop_columns_with_missing_values.py ├── groupby_custom_function.ipynb ├── groupby_custom_function.py ├── timedelta_extract_attributes.ipynb └── timedelta_extract_attributes.py └── views ├── display_mean_of_column.ipynb └── display_mean_of_column.py /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Environment 2 | 3 | * Operating System: 4 | * Python Version: `$ python --version` 5 | * How did you install bamboolib: (`pip`, `conda`, or `other (please explain)`) 6 | * Python packages: `$ pip list` or `$ conda list` (please include bamboolib) 7 | * If bamboolib is used with JupyterLab: JupyterLab extensions: `jupyter labextension list` 8 | * If bamboolib is used with Jupyter Notebook: Notebook extension: `jupyter nbextension list` 9 | 10 | ### Description of Issue 11 | 12 | * What did you expect to happen? 13 | * What happened instead? 14 | 15 | ### Reproduction Steps 16 | 17 | 1. 18 | 2. 19 | 3. 20 | ... 21 | 22 | ### What steps have you taken to resolve this already? 23 | 24 | ... 25 | 26 | ### Anything else? 27 | 28 | ... -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | .pytest_cache/ 49 | 50 | # Translations 51 | *.mo 52 | *.pot 53 | 54 | # Django stuff: 55 | *.log 56 | local_settings.py 57 | db.sqlite3 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # Environments 85 | .env 86 | .venv 87 | env/ 88 | venv/ 89 | ENV/ 90 | env.bak/ 91 | venv.bak/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | .DS_Store 106 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Community repository of bamboolib 2 | 3 | > bamboolib is joining forces with Databricks. For more information, please read our [announcement](https://docs.bamboolib.8080labs.com/databricks). 4 | 5 | > Please note that this repository does not contain the source code of bamboolib. The repo contains e.g. [explanations and code samples for plugins](https://github.com/tkrabel/bamboolib/tree/master/plugins) and it serves as a place to answer public questions via [issues](https://github.com/tkrabel/bamboolib/issues). 6 | 7 | # Data Analysis in Python 🐍 - without becoming a programmer or googling syntax 8 | 9 | This is the community repository of [bamboolib](https://bamboolib.8080labs.com/). You can use bamboolib for free if you use bamboolib on your local computer or on Open Data via [Binder](https://github.com/8080labs/bamboolib_binder_template). 10 | 11 | - If you have any issues or feature requests, please [open an issue](https://github.com/tkrabel/bamboolib/issues/new/choose). 12 | 13 | bamboolib is a GUI for pandas DataFrames that enables anyone to work with Python in Jupyter Notebook or JupyterLab. 14 | 15 | ## Features 16 | 17 | - Intuitive GUI that exports Python code 18 | - Supports all common transformations and visualizations 19 | - Provides best-practice analyses for data exploration 20 | - Can be arbitrarily customized via simple Python plugins 21 | - Integrate any internal or external Python library 22 | 23 | ## Main benefits of bamboolib 24 | 25 | - Enables anyone to **analyse data in Python without having to write code** 26 | - Even people who can code use bamboolib because it is **faster and easier** than writing the code themselves 27 | - Reduces employee on-boarding time and training costs 28 | - Enables team members of all skill levels to collaborate within Jupyter and to share the working results as reproducible code 29 | - No lock-in. You own the code you created with bamboolib 30 | - All your data remains private and secure 31 | 32 | __[🔍Try bamboolib live on Binder](https://bamboolib.com/demo)__ 33 | 34 | ## Installation 35 | 36 | Install bamboolib for Jupyter Notebook or Jupyter Lab by running the code below in your terminal (or Anaconda Prompt for Windows): 37 | 38 | ```bash 39 | pip install bamboolib 40 | 41 | # Jupyter Notebook extensions 42 | python -m bamboolib install_nbextensions 43 | 44 | # JupyterLab extensions 45 | python -m bamboolib install_labextensions 46 | ``` 47 | 48 | After you have installed bamboolib, you can [go here to test bamboolib](https://docs.bamboolib.8080labs.com/documentation/how-tos/installation-and-setup/install-bamboolib/test-bamboolib). 49 | 50 | ## Documentation 51 | 52 | You find out how to get started along with tutorials and an API reference on our [docs](https://docs.bamboolib.8080labs.com/). 53 | 54 | ## Further links 55 | 56 | - 🌐 [Official Website](https://bamboolib.8080labs.com/) 57 | - 📘 [Get started using bamboolib](https://docs.bamboolib.8080labs.com/documentation/getting-started) 58 | - 🚀 [Use bamboolib with your keyboard for maximum speed up](https://docs.bamboolib.8080labs.com/documentation/tutorials/keyboard) 59 | - 💪 [How to extend bamboolib with plugins](./plugins) 60 | - [bamboolib tutorial on Medium](https://towardsdatascience.com/bamboolib-learn-and-use-pandas-without-coding-23a7d3a94e1b) 61 | -------------------------------------------------------------------------------- /assets/img/activation_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tkrabel/bamboolib/d088f51c7e4c28c10d75fccb2c392f69c4776660/assets/img/activation_screen.png -------------------------------------------------------------------------------- /plugins/README.md: -------------------------------------------------------------------------------- 1 | # Plugins - add your own transformations, loaders or views 2 | 3 | ## Scenario: 4 | - Are you __missing a special transformation__ in bamboolib? 5 | - Do you want to provide __custom transformations for your team__? 6 | - Do you want to __load data from a custom source__? 7 | - Do you want to add __custom visualizations or data explorations__? 8 | 9 | bamboolib enables you to quickly add plugins or even write your own plugins based on your specific needs. 10 | 11 | 12 | ## Get started 13 | 14 | 1) make sure that you are running bamboolib 1.18.0 or higher. You can check this via running: `bam.__version__` If you need to upgrade, please [follow this guide](https://docs.bamboolib.8080labs.com/how-tos/update-to-a-new-version-of-bamboolib) 15 | 16 | 2) write your own plugin or [copy an example](https://github.com/tkrabel/bamboolib/tree/master/plugins/examples) 17 | 18 | 3) execute the plugin code 19 | 20 | 4) use the plugin from within the bamboolib user interface 21 | 22 | If you have questions, please reach out via bamboolib-feedback@databricks.com 23 | 24 | ## How to permanently add my plugin to bamboolib? 25 | 26 | 3 things you should know about how plugins work: 27 | - __Plugins are added to bamboolib after you execute the plugin code.__ 28 | - If you add a plugin, it will be available as long as the Python kernel is running. 29 | - If you restart your Python kernel, the plugin will no longer be available. 30 | 31 | Given those constraints there are __multiple alternatives__. Our __preferred option is number 2__: 32 | 1. Put the plugin code into an internal Python package and import the package at the top of your Jupyter Notebook. For example, you can quickly create a new Python package with [pyscaffold](https://github.com/pyscaffold/pyscaffold). You might also want to upload your own plugin package to a private or public GitHub repository and collaborate with others to make sure that you will always have all the best plugins available for your use case. 33 | 2. __[Preferred]__ Create an internal library like described in step 1. Then, use [Jupyter templates](https://towardsdatascience.com/stop-copy-pasting-notebooks-embrace-jupyter-templates-6bd7b6c00b94) in order to always automatically import bamboolib and your internal library at the top of the notebook when creating a new notebook file. 34 | 3. [Discouraged] Put the raw plugin code or the import of your internal library into a Python file in the IPython auto startup folder which is located in your home directory at `~/.ipython/profile_default/startup` This code is run by IPython every time you start a new Jupyter Python kernel. The only reason why we list this approach is because we want to let you know why we kindly discourage it. This approach hides the state and dependencies of your notebook. Thus, your notebook might not work out of the box when run on the computer of a colleague who might not have the same startup script like you do. 35 | 36 | Do you __prefer another way?__ If so, please let us know via the issues. Your approach might be helpful to others as well :) 37 | 38 | 39 | ## Plugin architecture 40 | 41 | If you want to build the plugins of your dreams, you basically need 2 ingredients: 42 | 1. the bamboolib internals that `bamboolib.plugins` provides to you 43 | 2. any of the user interface elements of [ipywidgets](https://github.com/jupyter-widgets/ipywidgets) 44 | 45 | 46 | ## Reference 47 | 48 | Below, you find the description of some of the core plugin components like `LoaderPlugin`, `TransformationPlugin`, `DF_OLD`, and `DF_NEW`. 49 | 50 | In addition, the following components can be imported from `bamboolib.plugins`: 51 | - `BamboolibError` - helpful for raising beautiful errors 52 | - `Singleselect` 53 | - `Multiselect` 54 | - `Button` 55 | - `Text` 56 | 57 | If you want more information about their usage, please check the Docstring e.g. using `Text?` or `help(Text)` 58 | 59 | For more infos about their usage in the real life, please check the examples. 60 | 61 | ### bamboolib.plugins.LoaderPlugin 62 | 63 | __Methods that you can OVERRIDE:__ 64 | - __get_code()__: this is the __bare minimum__ that is required. You need to return a string that contains Python code. 65 | - __render()__: for adding custom user interface elements 66 | 67 | __Helpers that you might want to USE:__ 68 | 69 | __Methods:__ 70 | - set_title() 71 | - set_content() 72 | - execute(): starts the code execution 73 | 74 | __Attributes:__ 75 | - new_df_name_group: input for giving the new dataframe a name that is referenced as DF_NEW in the code 76 | - execute_button: button that calls execute() when called 77 | 78 | 79 | ### bamboolib.plugins.TransformationPlugin 80 | 81 | __Methods that you can OVERRIDE:__ 82 | - __get_code()__: this is the __bare minimum__ that is required. You need to return a string that contains Python code. 83 | - __render()__: for adding custom user interface elements 84 | - __is_valid_transformation()__: return True or False or even raise exceptions 85 | - __get_description()__: return a description of the transformation that is shown in the history 86 | 87 | 88 | __Helpers that you might want to USE:__ 89 | 90 | __Methods:__ 91 | - set_title() 92 | - set_content() 93 | - get_df() 94 | - get_name_of_df() 95 | - ADVANCED 96 | - update_code_preview() 97 | - get_final_code() 98 | - execute() 99 | 100 | __Attributes:__ 101 | - rename_df_group 102 | - code_preview_group 103 | - spacer 104 | - new_df_name_input 105 | 106 | ### bamboolib.plugins.DF_OLD 107 | 108 | - Placeholder that you __NEED to use__ within `get_code()` 109 | 110 | - At runtime, bamboolib will replace the placeholder with the name of the current dataframe. 111 | 112 | ### bamboolib.plugins.DF_NEW 113 | 114 | - Placeholder that you __CAN use__ within `get_code()` 115 | 116 | - At runtime, bamboolib will replace the placeholder with the new name of the current dataframe. 117 | The new name can be specified by the user inside the `rename_df_group` input element. 118 | 119 | > Attention: for TransformationPlugin the renaming will only work if you add `self.rename_df_group` to `self.set_content()` 120 | 121 | > Attention: for LoaderPlugin the renaming will only work if you add `self.new_df_name_group` to `self.set_content()` 122 | -------------------------------------------------------------------------------- /plugins/examples/loaders/load_dummy_data.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Demo for loading dummy data\n", 8 | "- This is the actual code that is also used inside bamboolib. You find the UI when you type \"bam\" in a cell and execute the cell\n", 9 | "- You can use this template to write your own data loader from your custom sources" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import bamboolib as bam" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "execution_count": null, 24 | "metadata": {}, 25 | "outputs": [], 26 | "source": [ 27 | "bam" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "If you adjust the code of the DummyData class below, you will also adjust the default behavior of bamboolib because the LoaderPlugin overrides the previous plugin with the same name" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "import ipywidgets as widgets\n", 44 | "from bamboolib.plugins import LoaderPlugin, DF_NEW, Singleselect\n", 45 | "\n", 46 | "class DummyData(LoaderPlugin):\n", 47 | "\n", 48 | " name = \"Load dummy data\"\n", 49 | " new_df_name_placeholder = \"df\"\n", 50 | "\n", 51 | " def __init__(self, **kwargs):\n", 52 | " super().__init__(**kwargs)\n", 53 | " data_options = [\n", 54 | " {\n", 55 | " \"label\": \"Titanic dataset\",\n", 56 | " \"value\": \"pd.read_csv(bam.titanic_csv)\",\n", 57 | " \"description\": \"Each row is a passenger on the Titanic - often used for classifications\",\n", 58 | " },\n", 59 | " {\n", 60 | " \"label\": \"Sales dataset\",\n", 61 | " \"value\": \"pd.read_csv(bam.sales_csv)\",\n", 62 | " \"description\": \"Timeseries dataset - each row is a monthly sales figure for various products\",\n", 63 | " },\n", 64 | " ]\n", 65 | " self.dataset = Singleselect(\n", 66 | " options=data_options, value=data_options[0][\"value\"], width=\"xl\"\n", 67 | " )\n", 68 | "\n", 69 | " def render(self):\n", 70 | " self.set_title(\"Load dummy data\")\n", 71 | " self.set_content(\n", 72 | " widgets.HTML(\"Load a dummy data set for testing bamboolib\"),\n", 73 | " self.dataset,\n", 74 | " self.new_df_name_group,\n", 75 | " self.execute_button,\n", 76 | " )\n", 77 | "\n", 78 | " def get_code(self):\n", 79 | " return f\"\"\"\n", 80 | " import pandas as pd\n", 81 | " {DF_NEW} = {self.dataset.value}\n", 82 | " \"\"\"" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": {}, 88 | "source": [ 89 | "When you adjusted the class, you can also debug and view the plugin UI via executing `DummyData()`. This saves you the time of navigating to the plugin in the UI in order to view your changes." 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "DummyData()" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": {}, 105 | "outputs": [], 106 | "source": [] 107 | } 108 | ], 109 | "metadata": { 110 | "jupytext": { 111 | "cell_metadata_filter": "-all", 112 | "notebook_metadata_filter": "-all", 113 | "text_representation": { 114 | "extension": ".py", 115 | "format_name": "light" 116 | } 117 | }, 118 | "kernelspec": { 119 | "display_name": "Python 3.7.7 64-bit", 120 | "language": "python", 121 | "name": "python37764bitbbca2793e9b54c6393603e4e81e7f13c" 122 | }, 123 | "language_info": { 124 | "codemirror_mode": { 125 | "name": "ipython", 126 | "version": 3 127 | }, 128 | "file_extension": ".py", 129 | "mimetype": "text/x-python", 130 | "name": "python", 131 | "nbconvert_exporter": "python", 132 | "pygments_lexer": "ipython3", 133 | "version": "3.7.7" 134 | } 135 | }, 136 | "nbformat": 4, 137 | "nbformat_minor": 2 138 | } 139 | -------------------------------------------------------------------------------- /plugins/examples/loaders/load_dummy_data.py: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # # Demo for loading dummy data 3 | # - This is the actual code that is also used inside bamboolib. You find the UI when you type "bam" in a cell and execute the cell 4 | # - You can use this template to write your own data loader from your custom sources 5 | 6 | # %% 7 | import bamboolib as bam 8 | 9 | # %% 10 | bam 11 | 12 | # %% [markdown] 13 | # If you adjust the code of the DummyData class below, you will also adjust the default behavior of bamboolib because the LoaderPlugin overrides the previous plugin with the same name 14 | 15 | # %% 16 | import ipywidgets as widgets 17 | from bamboolib.plugins import LoaderPlugin, DF_NEW, Singleselect 18 | 19 | class DummyData(LoaderPlugin): 20 | 21 | name = "Load dummy data" 22 | new_df_name_placeholder = "df" 23 | 24 | def __init__(self, **kwargs): 25 | super().__init__(**kwargs) 26 | data_options = [ 27 | { 28 | "label": "Titanic dataset", 29 | "value": "pd.read_csv(bam.titanic_csv)", 30 | "description": "Each row is a passenger on the Titanic - often used for classifications", 31 | }, 32 | { 33 | "label": "Sales dataset", 34 | "value": "pd.read_csv(bam.sales_csv)", 35 | "description": "Timeseries dataset - each row is a monthly sales figure for various products", 36 | }, 37 | ] 38 | self.dataset = Singleselect( 39 | options=data_options, value=data_options[0]["value"], width="xl" 40 | ) 41 | 42 | def render(self): 43 | self.set_title("Load dummy data") 44 | self.set_content( 45 | widgets.HTML("Load a dummy data set for testing bamboolib"), 46 | self.dataset, 47 | self.new_df_name_group, 48 | self.execute_button, 49 | ) 50 | 51 | def get_code(self): 52 | return f""" 53 | import pandas as pd 54 | {DF_NEW} = {self.dataset.value} 55 | """ 56 | 57 | 58 | # %% [markdown] 59 | # When you adjusted the class, you can also debug and view the plugin UI via executing `DummyData()`. This saves you the time of navigating to the plugin in the UI in order to view your changes. 60 | 61 | # %% 62 | DummyData() 63 | 64 | # %% 65 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/br_analytics/__init__.py: -------------------------------------------------------------------------------- 1 | from br_analytics.calculations import load_ticker, add_index_return 2 | 3 | import br_analytics.figure_plugins 4 | import br_analytics.loader_plugins 5 | import br_analytics.transformation_plugins 6 | import br_analytics.view_plugins 7 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/br_analytics/calculations.py: -------------------------------------------------------------------------------- 1 | # %% 2 | import pandas as pd 3 | # The spark setup is expected to fail outside of Databricks 4 | from pyspark.sql import SparkSession 5 | spark = SparkSession.getActiveSession() 6 | 7 | # %% 8 | def load_ticker(ticker_list): 9 | df_list = [] 10 | for ticker_name in ticker_list: 11 | ticker_df = spark.table(ticker_name).toPandas() 12 | df_list.append(ticker_df) 13 | df = pd.concat(df_list, axis=0, ignore_index=True) 14 | df = df.sort_values(by=['date'], ascending=[True]) 15 | return df 16 | 17 | 18 | # %% 19 | def add_index_return(df, value_column, groupby_columns): 20 | df["price_return"] = df.groupby(groupby_columns)[value_column].transform( 21 | "pct_change" 22 | ) 23 | df["index_return"] = df["price_return"].add(1) 24 | df["index_return"] = df.groupby(groupby_columns)["index_return"].cumprod().fillna(1) 25 | return df 26 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/br_analytics/figure_plugins.py: -------------------------------------------------------------------------------- 1 | # %% 2 | import bamboolib.views.plot_creator as pc 3 | 4 | 5 | # %% 6 | class XAxisForStocks(pc.XAxisWithMaybeSortColumn): 7 | default_value = "date" 8 | 9 | 10 | # %% 11 | class YAxisForStocks(pc.YAxisWithMultipleColumns): 12 | default_value = ["index_return"] 13 | 14 | 15 | # %% 16 | class ColorForStocks(pc.Color): 17 | default_value = "label" 18 | 19 | 20 | # %% 21 | class BRLinePlotForStocks(pc.LinePlot): 22 | name = "BR: Line plot for stocks" 23 | recommended_configs = [ 24 | XAxisForStocks, 25 | YAxisForStocks, 26 | ColorForStocks, 27 | pc.XAxisRangeSlider, 28 | pc.XAxisDefaultDateRangeSelectors, 29 | ] 30 | #optional_configs = [] 31 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/br_analytics/loader_plugins.py: -------------------------------------------------------------------------------- 1 | from bamboolib.plugins import LoaderPlugin, DF_NEW, Multiselect 2 | 3 | import ipywidgets as widgets 4 | 5 | 6 | class LoadTickerData(LoaderPlugin): 7 | 8 | name = "BR: Load ticker data" 9 | new_df_name_placeholder = "df" 10 | 11 | def __init__(self, **kwargs): 12 | super().__init__(**kwargs) 13 | 14 | ticker_options = [ 15 | {"label": "Google/Alphabet (GOOG)", "value":"goog_ticker_clean"}, 16 | {"label": "Apple (AAPL)", "value":"aapl_ticker_clean"}, 17 | {"label": "Microsoft (MSF)", "value":"msf_ticker_clean"}, 18 | {"label": "Amazon (AMZ)", "value":"amz_ticker_clean"}, 19 | ] 20 | self.tickers_input = Multiselect(options=ticker_options, value="", width="xl") 21 | 22 | def render(self): 23 | self.set_title("Load ticker data") 24 | self.set_content( 25 | widgets.HTML("Load data for ticker(s)"), 26 | self.tickers_input, 27 | self.new_df_name_group, 28 | self.execute_button, 29 | ) 30 | 31 | def get_code(self): 32 | return f"""{DF_NEW} = br.load_ticker({self.tickers_input.value})""" 33 | 34 | 35 | class LoadGoogleSpreadsheetData(LoaderPlugin): 36 | name = "BR: Google Spreadsheet - load data" 37 | # TODO: to be implemented with your credentials etc 38 | 39 | class LoadBigQueryData(LoaderPlugin): 40 | name = "BR: BigQuery - load data" 41 | # TODO: to be implemented with your credentials etc 42 | 43 | class LoadSnowflakeData(LoaderPlugin): 44 | name = "BR: Snowflake - load data" 45 | # TODO: to be implemented with your credentials etc 46 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/br_analytics/transformation_plugins.py: -------------------------------------------------------------------------------- 1 | # %% 2 | import ipywidgets as widgets 3 | 4 | # %% 5 | from bamboolib.plugins import TransformationPlugin, DF_OLD, Singleselect, Multiselect 6 | 7 | 8 | # %% 9 | class CalculateIndexReturn(TransformationPlugin): 10 | 11 | name = "Calculate index return" 12 | description = "BR function: calculate the index return of a column." 13 | 14 | def __init__(self, *args, **kwargs): 15 | super().__init__(*args, **kwargs) 16 | 17 | numeric_columns = list(self.get_df().select_dtypes(include=["number"]).columns) 18 | 19 | self.value_column_input = Singleselect( 20 | options=numeric_columns, placeholder="Choose column", focus_after_init=True 21 | ) 22 | self.groupby_columns_input = Multiselect( 23 | options=list(self.get_df().columns), 24 | placeholder="Choose column(s) (optional)", 25 | ) 26 | 27 | def render(self): 28 | self.set_title("Calculate Index Return") 29 | self.set_content( 30 | widgets.HTML("Calculate the index return of"), 31 | self.value_column_input, 32 | widgets.HTML("For each group in (optional)"), 33 | self.groupby_columns_input, 34 | ) 35 | 36 | def get_code(self): 37 | return f"""{DF_OLD} = br.add_index_return({DF_OLD}, '{self.value_column_input.value}', {self.groupby_columns_input.value})""" 38 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/br_analytics/view_plugins.py: -------------------------------------------------------------------------------- 1 | from bamboolib.plugins import ViewPlugin 2 | from bamboolib.helper import notification 3 | 4 | 5 | class TrainXGBoostModel(ViewPlugin): 6 | 7 | name = "Train XGBoost model" 8 | description = "Machine learning (ML): train and score an XGBoost model." 9 | 10 | def render(self): 11 | self.set_title("Train XGBoost model") 12 | self.set_content(notification("Coming soon 🚀")) 13 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/data/AAPL.csv: -------------------------------------------------------------------------------- 1 | label,date,open,high,low,close 2 | AAPL,2018-01-02,42.540001,43.075001,42.314999,43.064999 3 | AAPL,2018-01-03,43.1325,43.637501,42.990002,43.057499 4 | AAPL,2018-01-04,43.134998,43.3675,43.02,43.2575 5 | AAPL,2018-01-05,43.360001,43.842499,43.262501,43.75 6 | AAPL,2018-01-08,43.587502,43.9025,43.482498,43.587502 7 | AAPL,2018-01-09,43.637501,43.764999,43.352501,43.5825 8 | AAPL,2018-01-10,43.290001,43.575001,43.25,43.572498 9 | AAPL,2018-01-11,43.647499,43.872501,43.622501,43.82 10 | AAPL,2018-01-12,44.044998,44.34,43.912498,44.272499 11 | AAPL,2018-01-16,44.474998,44.8475,44.035,44.047501 12 | AAPL,2018-01-17,44.037498,44.8125,43.767502,44.775002 13 | AAPL,2018-01-18,44.842499,45.025002,44.5625,44.814999 14 | AAPL,2018-01-19,44.6525,44.895,44.352501,44.615002 15 | AAPL,2018-01-22,44.325001,44.445,44.150002,44.25 16 | AAPL,2018-01-23,44.325001,44.860001,44.205002,44.259998 17 | AAPL,2018-01-24,44.3125,44.325001,43.299999,43.555 18 | AAPL,2018-01-25,43.627499,43.737499,42.6325,42.7775 19 | AAPL,2018-01-26,43,43,42.514999,42.877499 20 | AAPL,2018-01-29,42.540001,42.540001,41.767502,41.990002 21 | AAPL,2018-01-30,41.3825,41.842499,41.174999,41.7425 22 | AAPL,2018-01-31,41.717499,42.110001,41.625,41.857498 23 | AAPL,2018-02-01,41.7925,42.154999,41.689999,41.945 24 | AAPL,2018-02-02,41.5,41.700001,40.025002,40.125 25 | AAPL,2018-02-05,39.775002,40.970001,39,39.122501 26 | AAPL,2018-02-06,38.7075,40.93,38.5,40.7575 27 | AAPL,2018-02-07,40.772499,40.849998,39.767502,39.884998 28 | AAPL,2018-02-08,40.072498,40.25,38.7575,38.787498 29 | AAPL,2018-02-09,39.267502,39.4725,37.560001,39.102501 30 | AAPL,2018-02-12,39.625,40.9725,39.377499,40.677502 31 | AAPL,2018-02-13,40.487499,41.1875,40.412498,41.084999 32 | AAPL,2018-02-14,40.759998,41.884998,40.720001,41.842499 33 | AAPL,2018-02-15,42.447498,43.272499,42.25,43.247501 34 | AAPL,2018-02-16,43.09,43.705002,42.942501,43.107498 35 | AAPL,2018-02-20,43.012501,43.564999,42.855,42.962502 36 | AAPL,2018-02-21,43.2075,43.529999,42.752499,42.767502 37 | AAPL,2018-02-22,42.950001,43.487499,42.927502,43.125 38 | AAPL,2018-02-23,43.4175,43.912498,43.384998,43.875 39 | AAPL,2018-02-26,44.087502,44.8475,44.052502,44.7425 40 | AAPL,2018-02-27,44.775002,45.119999,44.540001,44.5975 41 | AAPL,2018-02-28,44.814999,45.154999,44.512501,44.529999 42 | AAPL,2018-03-01,44.634998,44.945,43.165001,43.75 43 | AAPL,2018-03-02,43.200001,44.075001,43.112499,44.052502 44 | AAPL,2018-03-05,43.802502,44.435001,43.630001,44.205002 45 | AAPL,2018-03-06,44.477501,44.5625,44.032501,44.1675 46 | AAPL,2018-03-07,43.735001,43.962502,43.567501,43.7575 47 | AAPL,2018-03-08,43.869999,44.279999,43.767502,44.235001 48 | AAPL,2018-03-09,44.490002,45,44.3475,44.994999 49 | AAPL,2018-03-12,45.072498,45.5975,45.052502,45.43 50 | AAPL,2018-03-13,45.647499,45.875,44.810001,44.9925 51 | AAPL,2018-03-14,45.080002,45.130001,44.452499,44.610001 52 | AAPL,2018-03-15,44.625,45.060001,44.517502,44.662498 53 | AAPL,2018-03-16,44.662498,44.779999,44.404999,44.505001 54 | AAPL,2018-03-19,44.330002,44.3675,43.415001,43.825001 55 | AAPL,2018-03-20,43.810001,44.200001,43.735001,43.810001 56 | AAPL,2018-03-21,43.759998,43.772499,42.814999,42.817501 57 | AAPL,2018-03-22,42.5,43.169998,42.150002,42.212502 58 | AAPL,2018-03-23,42.0975,42.48,41.235001,41.235001 59 | AAPL,2018-03-26,42.017502,43.275002,41.610001,43.192501 60 | AAPL,2018-03-27,43.419998,43.787498,41.73,42.084999 61 | AAPL,2018-03-28,41.8125,42.505001,41.297501,41.619999 62 | AAPL,2018-03-29,41.952499,42.9375,41.724998,41.945 63 | AAPL,2018-04-02,41.66,42.235001,41.1175,41.669998 64 | AAPL,2018-04-03,41.91,42.1875,41.220001,42.0975 65 | AAPL,2018-04-04,41.220001,43.002499,41.192501,42.9025 66 | AAPL,2018-04-05,43.145,43.557499,43.02,43.200001 67 | AAPL,2018-04-06,42.7425,43.119999,42.049999,42.095001 68 | AAPL,2018-04-09,42.470001,43.272499,42.462502,42.512501 69 | AAPL,2018-04-10,43.25,43.5,42.8825,43.3125 70 | AAPL,2018-04-11,43.057499,43.48,42.924999,43.110001 71 | AAPL,2018-04-12,43.352501,43.75,43.259998,43.535 72 | AAPL,2018-04-13,43.695,43.959999,43.462502,43.682499 73 | AAPL,2018-04-16,43.7575,44.047501,43.7075,43.955002 74 | AAPL,2018-04-17,44.122501,44.735001,44.102501,44.560001 75 | AAPL,2018-04-18,44.452499,44.705002,44.220001,44.459999 76 | AAPL,2018-04-19,43.439999,43.8475,43.165001,43.200001 77 | AAPL,2018-04-20,42.650002,42.805,41.357498,41.43 78 | AAPL,2018-04-23,41.7075,41.73,41.022499,41.310001 79 | AAPL,2018-04-24,41.4175,41.5825,40.305,40.735001 80 | AAPL,2018-04-25,40.654999,41.355,40.602501,40.912498 81 | AAPL,2018-04-26,41.029999,41.432499,40.842499,41.055 82 | AAPL,2018-04-27,41,41.0825,40.157501,40.580002 83 | AAPL,2018-04-30,40.532501,41.814999,40.459999,41.314999 84 | AAPL,2018-05-01,41.602501,42.299999,41.317501,42.275002 85 | AAPL,2018-05-02,43.807499,44.4375,43.450001,44.142502 86 | AAPL,2018-05-03,43.970001,44.375,43.610001,44.2225 87 | AAPL,2018-05-04,44.5625,46.0625,44.5425,45.9575 88 | AAPL,2018-05-07,46.294998,46.9175,46.1875,46.290001 89 | AAPL,2018-05-08,46.247501,46.555,45.9175,46.512501 90 | AAPL,2018-05-09,46.637501,46.849998,46.305,46.84 91 | AAPL,2018-05-10,46.935001,47.592499,46.912498,47.509998 92 | AAPL,2018-05-11,47.372501,47.514999,46.862499,47.147499 93 | AAPL,2018-05-14,47.252499,47.3825,46.965,47.037498 94 | AAPL,2018-05-15,46.695,46.767502,46.275002,46.610001 95 | AAPL,2018-05-16,46.517502,47.115002,46.5,47.044998 96 | AAPL,2018-05-17,47,47.227501,46.59,46.747501 97 | AAPL,2018-05-18,46.797501,46.952499,46.532501,46.577499 98 | AAPL,2018-05-21,47,47.317501,46.727501,46.907501 99 | AAPL,2018-05-22,47.095001,47.220001,46.695,46.790001 100 | AAPL,2018-05-23,46.587502,47.125,46.439999,47.09 101 | AAPL,2018-05-24,47.192501,47.209999,46.552502,47.037498 102 | AAPL,2018-05-25,47.057499,47.412498,46.912498,47.145 103 | AAPL,2018-05-29,46.900002,47.1875,46.717499,46.974998 104 | AAPL,2018-05-30,46.93,47,46.695,46.875 105 | AAPL,2018-05-31,46.805,47.057499,46.535,46.717499 106 | AAPL,2018-06-01,46.997501,47.564999,46.9375,47.560001 107 | AAPL,2018-06-04,47.91,48.355,47.837502,47.9575 108 | AAPL,2018-06-05,48.267502,48.485001,48.09,48.327499 109 | AAPL,2018-06-06,48.407501,48.52,47.98,48.494999 110 | AAPL,2018-06-07,48.535,48.549999,48.084999,48.365002 111 | AAPL,2018-06-08,47.7925,48,47.442501,47.924999 112 | AAPL,2018-06-11,47.837502,47.9925,47.552502,47.807499 113 | AAPL,2018-06-12,47.8475,48.1525,47.787498,48.07 114 | AAPL,2018-06-13,48.105,48.220001,47.610001,47.674999 115 | AAPL,2018-06-14,47.887501,47.892502,47.555,47.700001 116 | AAPL,2018-06-15,47.5075,47.540001,47.064999,47.209999 117 | AAPL,2018-06-18,46.970001,47.305,46.799999,47.185001 118 | AAPL,2018-06-19,46.285,46.5825,45.862499,46.422501 119 | AAPL,2018-06-20,46.587502,46.799999,46.432499,46.625 120 | AAPL,2018-06-21,46.8125,47.087502,46.235001,46.365002 121 | AAPL,2018-06-22,46.529999,46.537498,46.174999,46.23 122 | AAPL,2018-06-25,45.849998,46.23,45.182499,45.5425 123 | AAPL,2018-06-26,45.747501,46.6325,45.634998,46.107498 124 | AAPL,2018-06-27,46.307499,46.82,46.0075,46.040001 125 | AAPL,2018-06-28,46.025002,46.552502,45.950001,46.375 126 | AAPL,2018-06-29,46.572498,46.797501,45.727501,46.2775 127 | AAPL,2018-07-02,45.955002,46.825001,45.855,46.794998 128 | AAPL,2018-07-03,46.947498,46.987499,45.884998,45.98 129 | AAPL,2018-07-05,46.314999,46.602501,46.07,46.349998 130 | AAPL,2018-07-06,46.355,47.107498,46.299999,46.9925 131 | AAPL,2018-07-09,47.375,47.669998,47.325001,47.645 132 | AAPL,2018-07-10,47.677502,47.82,47.544998,47.587502 133 | AAPL,2018-07-11,47.125,47.445,46.9025,46.970001 134 | AAPL,2018-07-12,47.3825,47.852501,47.327499,47.7575 135 | AAPL,2018-07-13,47.77,47.959999,47.724998,47.8325 136 | AAPL,2018-07-16,47.880001,48.162498,47.605,47.727501 137 | AAPL,2018-07-17,47.4375,47.967499,47.299999,47.862499 138 | AAPL,2018-07-18,47.945,47.950001,47.482498,47.599998 139 | AAPL,2018-07-19,47.422501,48.137501,47.422501,47.970001 140 | AAPL,2018-07-20,47.945,48.107498,47.5425,47.860001 141 | AAPL,2018-07-23,47.669998,47.990002,47.389999,47.9025 142 | AAPL,2018-07-24,48.112499,48.415001,48.012501,48.25 143 | AAPL,2018-07-25,48.264999,48.712502,48.107498,48.705002 144 | AAPL,2018-07-26,48.6525,48.990002,48.4025,48.552502 145 | AAPL,2018-07-27,48.747501,48.797501,47.525002,47.744999 146 | AAPL,2018-07-30,47.974998,48.049999,47.267502,47.477501 147 | AAPL,2018-07-31,47.575001,48.035,47.334999,47.572498 148 | AAPL,2018-08-01,49.782501,50.439999,49.327499,50.375 149 | AAPL,2018-08-02,50.145,52.095001,50.087502,51.8475 150 | AAPL,2018-08-03,51.7575,52.185001,51.369999,51.997501 151 | AAPL,2018-08-06,52,52.3125,51.767502,52.267502 152 | AAPL,2018-08-07,52.330002,52.375,51.689999,51.7775 153 | AAPL,2018-08-08,51.512501,51.952499,51.130001,51.8125 154 | AAPL,2018-08-09,52.3825,52.445,51.799999,52.220001 155 | AAPL,2018-08-10,51.84,52.275002,51.6675,51.8825 156 | AAPL,2018-08-13,52.327499,52.737499,51.924999,52.217499 157 | AAPL,2018-08-14,52.540001,52.639999,52.064999,52.4375 158 | AAPL,2018-08-15,52.305,52.685001,52.0825,52.560001 159 | AAPL,2018-08-16,52.9375,53.452499,52.8675,53.330002 160 | AAPL,2018-08-17,53.360001,54.487499,53.290001,54.395 161 | AAPL,2018-08-20,54.525002,54.794998,53.7775,53.865002 162 | AAPL,2018-08-21,54.200001,54.297501,53.5075,53.759998 163 | AAPL,2018-08-22,53.525002,54.09,53.459999,53.762501 164 | AAPL,2018-08-23,53.662498,54.262501,53.650002,53.872501 165 | AAPL,2018-08-24,54.150002,54.224998,53.7775,54.040001 166 | AAPL,2018-08-27,54.287498,54.685001,54.0825,54.485001 167 | AAPL,2018-08-28,54.752499,55.134998,54.73,54.924999 168 | AAPL,2018-08-29,55.037498,55.872501,54.852501,55.744999 169 | AAPL,2018-08-30,55.8125,57.064999,55.599998,56.2575 170 | AAPL,2018-08-31,56.627499,57.217499,56.5,56.907501 171 | AAPL,2018-09-04,57.102501,57.294998,56.657501,57.09 172 | AAPL,2018-09-05,57.247501,57.4175,56.275002,56.717499 173 | AAPL,2018-09-06,56.557499,56.837502,55.325001,55.775002 174 | AAPL,2018-09-07,55.462502,56.342499,55.177502,55.325001 175 | AAPL,2018-09-10,55.237499,55.462502,54.1175,54.5825 176 | AAPL,2018-09-11,54.502499,56.075001,54.139999,55.962502 177 | AAPL,2018-09-12,56.235001,56.25,54.959999,55.267502 178 | AAPL,2018-09-13,55.880001,57.087502,55.642502,56.602501 179 | AAPL,2018-09-14,56.4375,56.709999,55.630001,55.959999 180 | AAPL,2018-09-17,55.537498,55.737499,54.317501,54.470001 181 | AAPL,2018-09-18,54.447498,55.462502,54.279999,54.560001 182 | AAPL,2018-09-19,54.625,54.904999,53.825001,54.592499 183 | AAPL,2018-09-20,55.060001,55.57,54.787498,55.0075 184 | AAPL,2018-09-21,55.195,55.34,54.322498,54.415001 185 | AAPL,2018-09-24,54.205002,55.314999,54.157501,55.197498 186 | AAPL,2018-09-25,54.9375,55.705002,54.924999,55.547501 187 | AAPL,2018-09-26,55.25,55.9375,54.939999,55.105 188 | AAPL,2018-09-27,55.955002,56.610001,55.884998,56.237499 189 | AAPL,2018-09-28,56.197498,56.459999,56.005001,56.435001 190 | AAPL,2018-10-01,56.987499,57.355,56.587502,56.814999 191 | AAPL,2018-10-02,56.8125,57.5,56.657501,57.32 192 | AAPL,2018-10-03,57.512501,58.3675,57.445,58.017502 193 | AAPL,2018-10-04,57.695,58.087502,56.682499,56.997501 194 | AAPL,2018-10-05,56.990002,57.102501,55.145,56.072498 195 | AAPL,2018-10-08,55.552502,56.200001,55.049999,55.942501 196 | AAPL,2018-10-09,55.91,56.817501,55.5625,56.717499 197 | AAPL,2018-10-10,56.365002,56.587502,54.012501,54.09 198 | AAPL,2018-10-11,53.630001,54.875,53.080002,53.612499 199 | AAPL,2018-10-12,55.105,55.720001,54.209999,55.5275 200 | AAPL,2018-10-15,55.290001,55.4575,54.317501,54.34 201 | AAPL,2018-10-16,54.732498,55.747501,54.189999,55.537498 202 | AAPL,2018-10-17,55.575001,55.66,54.834999,55.297501 203 | AAPL,2018-10-18,54.465,54.935001,53.25,54.005001 204 | AAPL,2018-10-19,54.514999,55.314999,54.357498,54.827499 205 | AAPL,2018-10-22,54.947498,55.84,54.735001,55.162498 206 | AAPL,2018-10-23,53.9575,55.8125,53.674999,55.682499 207 | AAPL,2018-10-24,55.650002,56.057499,53.634998,53.772499 208 | AAPL,2018-10-25,54.427502,55.345001,54.1875,54.950001 209 | AAPL,2018-10-26,53.974998,55.047501,53.1675,54.075001 210 | AAPL,2018-10-29,54.797501,54.922501,51.522499,53.060001 211 | AAPL,2018-10-30,52.787498,53.794998,52.317501,53.325001 212 | AAPL,2018-10-31,54.220001,55.112499,54.154999,54.715 213 | AAPL,2018-11-01,54.762501,55.59,54.202499,55.555 214 | AAPL,2018-11-02,52.387501,53.412498,51.357498,51.869999 215 | AAPL,2018-11-05,51.075001,51.0975,49.5425,50.397499 216 | AAPL,2018-11-06,50.48,51.18,50.422501,50.942501 217 | AAPL,2018-11-07,51.4925,52.514999,51.032501,52.487499 218 | AAPL,2018-11-08,52.494999,52.529999,51.6875,52.122501 219 | AAPL,2018-11-09,51.387501,51.502499,50.5625,51.1175 220 | AAPL,2018-11-12,49.75,49.962502,48.447498,48.5425 221 | AAPL,2018-11-13,47.907501,49.294998,47.862499,48.057499 222 | AAPL,2018-11-14,48.474998,48.619999,46.482498,46.700001 223 | AAPL,2018-11-15,47.0975,47.9925,46.724998,47.852501 224 | AAPL,2018-11-16,47.625,48.7425,47.365002,48.3825 225 | AAPL,2018-11-19,47.5,47.674999,46.247501,46.465 226 | AAPL,2018-11-20,44.592499,45.3675,43.877499,44.244999 227 | AAPL,2018-11-21,44.932499,45.067501,44.137501,44.195 228 | AAPL,2018-11-23,43.735001,44.150002,43.025002,43.072498 229 | AAPL,2018-11-26,43.560001,43.737499,42.564999,43.654999 230 | AAPL,2018-11-27,42.877499,43.692501,42.720001,43.560001 231 | AAPL,2018-11-28,44.182499,45.322498,43.732498,45.235001 232 | AAPL,2018-11-29,45.665001,45.700001,44.424999,44.887501 233 | AAPL,2018-11-30,45.072498,45.0825,44.2575,44.645 234 | AAPL,2018-12-03,46.115002,46.235001,45.302502,46.205002 235 | AAPL,2018-12-04,45.237499,45.5975,44.067501,44.172501 236 | AAPL,2018-12-06,42.939999,43.695,42.605,43.68 237 | AAPL,2018-12-07,43.372501,43.622501,42.075001,42.122501 238 | AAPL,2018-12-10,41.25,42.522499,40.8325,42.400002 239 | AAPL,2018-12-11,42.915001,42.947498,41.75,42.157501 240 | AAPL,2018-12-12,42.599998,42.98,42.255001,42.275002 241 | AAPL,2018-12-13,42.622501,43.142502,42.387501,42.737499 242 | AAPL,2018-12-14,42.25,42.27,41.32,41.369999 243 | AAPL,2018-12-17,41.362499,42.087502,40.682499,40.985001 244 | AAPL,2018-12-18,41.345001,41.8825,41.0975,41.517502 245 | AAPL,2018-12-19,41.5,41.862499,39.772499,40.2225 246 | AAPL,2018-12-20,40.099998,40.5275,38.825001,39.2075 247 | AAPL,2018-12-21,39.215,39.540001,37.407501,37.682499 248 | AAPL,2018-12-24,37.037498,37.887501,36.647499,36.7075 249 | AAPL,2018-12-26,37.075001,39.307499,36.68,39.2925 250 | AAPL,2018-12-27,38.959999,39.192501,37.517502,39.037498 251 | AAPL,2018-12-28,39.375,39.630001,38.637501,39.057499 252 | AAPL,2018-12-31,39.6325,39.84,39.119999,39.435001 253 | AAPL,2019-01-02,38.7225,39.712502,38.557499,39.48 254 | AAPL,2019-01-03,35.994999,36.43,35.5,35.547501 255 | AAPL,2019-01-04,36.1325,37.137501,35.950001,37.064999 256 | AAPL,2019-01-07,37.174999,37.2075,36.474998,36.982498 257 | AAPL,2019-01-08,37.389999,37.955002,37.130001,37.6875 258 | AAPL,2019-01-09,37.822498,38.6325,37.407501,38.327499 259 | AAPL,2019-01-10,38.125,38.4925,37.715,38.450001 260 | AAPL,2019-01-11,38.220001,38.424999,37.877499,38.072498 261 | AAPL,2019-01-14,37.712502,37.817501,37.305,37.5 262 | AAPL,2019-01-15,37.567501,38.3475,37.512501,38.267502 263 | AAPL,2019-01-16,38.27,38.970001,38.25,38.735001 264 | AAPL,2019-01-17,38.549999,39.415001,38.314999,38.965 265 | AAPL,2019-01-18,39.375,39.470001,38.994999,39.205002 266 | AAPL,2019-01-22,39.102501,39.182499,38.154999,38.325001 267 | AAPL,2019-01-23,38.537498,38.785,37.924999,38.48 268 | AAPL,2019-01-24,38.5275,38.619999,37.935001,38.174999 269 | AAPL,2019-01-25,38.869999,39.532501,38.580002,39.439999 270 | AAPL,2019-01-28,38.947498,39.0825,38.415001,39.075001 271 | AAPL,2019-01-29,39.0625,39.532501,38.5275,38.669998 272 | AAPL,2019-01-30,40.8125,41.537498,40.057499,41.3125 273 | AAPL,2019-01-31,41.5275,42.25,41.139999,41.610001 274 | AAPL,2019-02-01,41.740002,42.244999,41.482498,41.630001 275 | AAPL,2019-02-04,41.852501,42.915001,41.82,42.8125 276 | AAPL,2019-02-05,43.215,43.77,43.087502,43.544998 277 | AAPL,2019-02-06,43.662498,43.892502,43.212502,43.560001 278 | AAPL,2019-02-07,43.099998,43.485001,42.584999,42.735001 279 | AAPL,2019-02-08,42.247501,42.665001,42.105,42.602501 280 | AAPL,2019-02-11,42.762501,42.802502,42.3125,42.357498 281 | AAPL,2019-02-12,42.525002,42.75,42.424999,42.7225 282 | AAPL,2019-02-13,42.8475,43.119999,42.48,42.544998 283 | AAPL,2019-02-14,42.427502,42.814999,42.345001,42.700001 284 | AAPL,2019-02-15,42.8125,42.924999,42.4375,42.605 285 | AAPL,2019-02-19,42.427502,42.860001,42.372501,42.732498 286 | AAPL,2019-02-20,42.797501,43.330002,42.747501,43.0075 287 | AAPL,2019-02-21,42.950001,43.092499,42.575001,42.764999 288 | AAPL,2019-02-22,42.895,43.25,42.845001,43.2425 289 | AAPL,2019-02-25,43.540001,43.967499,43.487499,43.557499 290 | AAPL,2019-02-26,43.427502,43.825001,43.2925,43.5825 291 | AAPL,2019-02-27,43.302502,43.75,43.182499,43.717499 292 | AAPL,2019-02-28,43.580002,43.727501,43.23,43.287498 293 | AAPL,2019-03-01,43.57,43.787498,43.2225,43.7425 294 | AAPL,2019-03-04,43.922501,44.4375,43.4925,43.962502 295 | AAPL,2019-03-05,43.985001,44,43.634998,43.8825 296 | AAPL,2019-03-06,43.6675,43.872501,43.485001,43.630001 297 | AAPL,2019-03-07,43.467499,43.610001,43.005001,43.125 298 | AAPL,2019-03-08,42.580002,43.267502,42.375,43.227501 299 | AAPL,2019-03-11,43.872501,44.779999,43.837502,44.724998 300 | AAPL,2019-03-12,45,45.6675,44.842499,45.227501 301 | AAPL,2019-03-13,45.5625,45.825001,45.23,45.427502 302 | AAPL,2019-03-14,45.974998,46.025002,45.639999,45.932499 303 | AAPL,2019-03-15,46.212502,46.8325,45.935001,46.529999 304 | AAPL,2019-03-18,46.450001,47.0975,46.447498,47.005001 305 | AAPL,2019-03-19,47.087502,47.247501,46.48,46.6325 306 | AAPL,2019-03-20,46.557499,47.372501,46.182499,47.040001 307 | AAPL,2019-03-21,47.505001,49.0825,47.452499,48.772499 308 | AAPL,2019-03-22,48.834999,49.422501,47.695,47.762501 309 | AAPL,2019-03-25,47.877499,47.994999,46.650002,47.185001 310 | AAPL,2019-03-26,47.915001,48.220001,46.145,46.697498 311 | AAPL,2019-03-27,47.1875,47.439999,46.637501,47.1175 312 | AAPL,2019-03-28,47.237499,47.389999,46.8825,47.18 313 | AAPL,2019-03-29,47.4575,47.52,47.134998,47.487499 314 | AAPL,2019-04-01,47.91,47.919998,47.095001,47.810001 315 | AAPL,2019-04-02,47.772499,48.615002,47.762501,48.505001 316 | AAPL,2019-04-03,48.3125,49.125,48.287498,48.837502 317 | AAPL,2019-04-04,48.697498,49.092499,48.285,48.922501 318 | AAPL,2019-04-05,49.112499,49.275002,48.982498,49.25 319 | AAPL,2019-04-08,49.105,50.057499,49.084999,50.025002 320 | AAPL,2019-04-09,50.080002,50.712502,49.807499,49.875 321 | AAPL,2019-04-10,49.669998,50.185001,49.544998,50.154999 322 | AAPL,2019-04-11,50.212502,50.25,49.610001,49.737499 323 | AAPL,2019-04-12,49.799999,50.035,49.052502,49.717499 324 | AAPL,2019-04-15,49.645,49.962502,49.502499,49.807499 325 | AAPL,2019-04-16,49.865002,50.342499,49.639999,49.8125 326 | AAPL,2019-04-17,49.884998,50.845001,49.6525,50.782501 327 | AAPL,2019-04-18,50.779999,51.037498,50.630001,50.965 328 | AAPL,2019-04-22,50.7075,51.235001,50.584999,51.1325 329 | AAPL,2019-04-23,51.107498,51.9375,50.974998,51.869999 330 | AAPL,2019-04-24,51.84,52.119999,51.762501,51.790001 331 | AAPL,2019-04-25,51.7075,51.939999,51.279999,51.32 332 | AAPL,2019-04-26,51.224998,51.25,50.529999,51.075001 333 | AAPL,2019-04-29,51.099998,51.4925,50.965,51.1525 334 | AAPL,2019-04-30,50.764999,50.849998,49.7775,50.1675 335 | AAPL,2019-05-01,52.470001,53.827499,52.307499,52.630001 336 | AAPL,2019-05-02,52.459999,53.162498,52.032501,52.287498 337 | AAPL,2019-05-03,52.7225,52.959999,52.557499,52.9375 338 | AAPL,2019-05-06,51.072498,52.209999,50.875,52.119999 339 | AAPL,2019-05-07,51.470001,51.855,50.2075,50.715 340 | AAPL,2019-05-08,50.474998,51.334999,50.4375,50.724998 341 | AAPL,2019-05-09,50.099998,50.419998,49.165001,50.18 342 | AAPL,2019-05-10,49.355,49.712502,48.192501,49.294998 343 | AAPL,2019-05-13,46.927502,47.369999,45.712502,46.43 344 | AAPL,2019-05-14,46.602501,47.424999,46.352501,47.165001 345 | AAPL,2019-05-15,46.567501,47.9375,46.505001,47.73 346 | AAPL,2019-05-16,47.477501,48.1175,47.209999,47.52 347 | AAPL,2019-05-17,46.732498,47.724998,46.689999,47.25 348 | AAPL,2019-05-20,45.880001,46.087502,45.07,45.772499 349 | AAPL,2019-05-21,46.305,47,46.174999,46.650002 350 | AAPL,2019-05-22,46.165001,46.427502,45.637501,45.695 351 | AAPL,2019-05-23,44.950001,45.134998,44.452499,44.915001 352 | AAPL,2019-05-24,45.049999,45.535,44.654999,44.7425 353 | AAPL,2019-05-28,44.73,45.147499,44.477501,44.557499 354 | AAPL,2019-05-29,44.105,44.837502,44,44.345001 355 | AAPL,2019-05-30,44.487499,44.807499,44.1675,44.575001 356 | AAPL,2019-05-31,44.057499,44.497501,43.747501,43.767502 357 | AAPL,2019-06-03,43.900002,44.48,42.567501,43.325001 358 | AAPL,2019-06-04,43.860001,44.9575,43.630001,44.91 359 | AAPL,2019-06-05,46.07,46.247501,45.285,45.634998 360 | AAPL,2019-06-06,45.77,46.3675,45.537498,46.305 361 | AAPL,2019-06-07,46.627499,47.98,46.442501,47.537498 362 | AAPL,2019-06-10,47.952499,48.842499,47.904999,48.145 363 | AAPL,2019-06-11,48.715,49,48.400002,48.702499 364 | AAPL,2019-06-12,48.487499,48.9925,48.3475,48.547501 365 | AAPL,2019-06-13,48.674999,49.197498,48.400002,48.537498 366 | AAPL,2019-06-14,47.887501,48.397499,47.575001,48.185001 367 | AAPL,2019-06-17,48.224998,48.740002,48.0425,48.4725 368 | AAPL,2019-06-18,49.012501,50.072498,48.802502,49.612499 369 | AAPL,2019-06-19,49.919998,49.970001,49.327499,49.467499 370 | AAPL,2019-06-20,50.092499,50.1525,49.5075,49.865002 371 | AAPL,2019-06-21,49.700001,50.212502,49.537498,49.695 372 | AAPL,2019-06-24,49.634998,50.040001,49.5425,49.645 373 | AAPL,2019-06-25,49.607498,49.814999,48.822498,48.892502 374 | AAPL,2019-06-26,49.442501,50.247501,49.337502,49.950001 375 | AAPL,2019-06-27,50.072498,50.392502,49.892502,49.935001 376 | AAPL,2019-06-28,49.669998,49.875,49.262501,49.48 377 | AAPL,2019-07-01,50.7925,51.122501,50.162498,50.387501 378 | AAPL,2019-07-02,50.352501,50.782501,50.34,50.682499 379 | AAPL,2019-07-03,50.82,51.110001,50.672501,51.102501 380 | AAPL,2019-07-05,50.837502,51.27,50.724998,51.057499 381 | AAPL,2019-07-08,50.202499,50.349998,49.602501,50.005001 382 | AAPL,2019-07-09,49.799999,50.377499,49.702499,50.310001 383 | AAPL,2019-07-10,50.462502,50.932499,50.389999,50.807499 384 | AAPL,2019-07-11,50.827499,51.0975,50.427502,50.4375 385 | AAPL,2019-07-12,50.612499,51,50.549999,50.825001 386 | AAPL,2019-07-15,51.022499,51.467499,51,51.302502 387 | AAPL,2019-07-16,51.147499,51.5275,50.875,51.125 388 | AAPL,2019-07-17,51.012501,51.272499,50.817501,50.837502 389 | AAPL,2019-07-18,51,51.470001,50.924999,51.415001 390 | AAPL,2019-07-19,51.447498,51.625,50.59,50.647499 391 | AAPL,2019-07-22,50.912498,51.807499,50.9025,51.805 392 | AAPL,2019-07-23,52.115002,52.227501,51.822498,52.209999 393 | AAPL,2019-07-24,51.9175,52.287498,51.7925,52.1675 394 | AAPL,2019-07-25,52.2225,52.310001,51.682499,51.755001 395 | AAPL,2019-07-26,51.869999,52.432499,51.785,51.935001 396 | AAPL,2019-07-29,52.115002,52.66,52.110001,52.419998 397 | AAPL,2019-07-30,52.189999,52.540001,51.827499,52.195 398 | AAPL,2019-07-31,54.105,55.342499,52.825001,53.259998 399 | AAPL,2019-08-01,53.474998,54.5075,51.685001,52.107498 400 | AAPL,2019-08-02,51.3825,51.607498,50.407501,51.005001 401 | AAPL,2019-08-05,49.497501,49.662498,48.145,48.334999 402 | AAPL,2019-08-06,49.077499,49.517502,48.509998,49.25 403 | AAPL,2019-08-07,48.852501,49.889999,48.455002,49.759998 404 | AAPL,2019-08-08,50.049999,50.8825,49.8475,50.857498 405 | AAPL,2019-08-09,50.325001,50.689999,49.822498,50.247501 406 | AAPL,2019-08-12,49.904999,50.512501,49.787498,50.119999 407 | AAPL,2019-08-13,50.255001,53.035,50.119999,52.2425 408 | AAPL,2019-08-14,50.790001,51.610001,50.647499,50.6875 409 | AAPL,2019-08-15,50.865002,51.285,49.9175,50.435001 410 | AAPL,2019-08-16,51.07,51.790001,50.959999,51.625 411 | AAPL,2019-08-19,52.654999,53.182499,52.5075,52.587502 412 | AAPL,2019-08-20,52.720001,53.337502,52.580002,52.59 413 | AAPL,2019-08-21,53.247501,53.412498,52.900002,53.16 414 | AAPL,2019-08-22,53.297501,53.610001,52.6875,53.115002 415 | AAPL,2019-08-23,52.357498,53.012501,50.25,50.66 416 | AAPL,2019-08-26,51.465,51.797501,51.264999,51.622501 417 | AAPL,2019-08-27,51.965,52.137501,50.8825,51.040001 418 | AAPL,2019-08-28,51.025002,51.43,50.830002,51.3825 419 | AAPL,2019-08-29,52.125,52.330002,51.665001,52.252499 420 | AAPL,2019-08-30,52.540001,52.612499,51.799999,52.185001 421 | AAPL,2019-09-03,51.607498,51.744999,51.055,51.424999 422 | AAPL,2019-09-04,52.0975,52.369999,51.830002,52.297501 423 | AAPL,2019-09-05,53,53.4925,52.877499,53.32 424 | AAPL,2019-09-06,53.512501,53.605,53.127499,53.314999 425 | AAPL,2019-09-09,53.709999,54.110001,52.767502,53.5425 426 | AAPL,2019-09-10,53.465,54.195,52.927502,54.174999 427 | AAPL,2019-09-11,54.517502,55.927502,54.432499,55.897499 428 | AAPL,2019-09-12,56.200001,56.605,55.715,55.772499 429 | AAPL,2019-09-13,55,55.197498,54.255001,54.6875 430 | AAPL,2019-09-16,54.432499,55.032501,54.389999,54.974998 431 | AAPL,2019-09-17,54.990002,55.205002,54.779999,55.174999 432 | AAPL,2019-09-18,55.264999,55.712502,54.860001,55.692501 433 | AAPL,2019-09-19,55.502499,55.939999,55.092499,55.240002 434 | AAPL,2019-09-20,55.345001,55.639999,54.3675,54.432499 435 | AAPL,2019-09-23,54.737499,54.959999,54.412498,54.68 436 | AAPL,2019-09-24,55.2575,55.622501,54.297501,54.419998 437 | AAPL,2019-09-25,54.637501,55.375,54.285,55.2575 438 | AAPL,2019-09-26,55,55.235001,54.7075,54.9725 439 | AAPL,2019-09-27,55.134998,55.240002,54.32,54.705002 440 | AAPL,2019-09-30,55.224998,56.145,55.197498,55.9925 441 | AAPL,2019-10-01,56.267502,57.055,56.049999,56.147499 442 | AAPL,2019-10-02,55.764999,55.895,54.482498,54.740002 443 | AAPL,2019-10-03,54.607498,55.240002,53.782501,55.205002 444 | AAPL,2019-10-04,56.41,56.872501,55.9725,56.752499 445 | AAPL,2019-10-07,56.567501,57.482498,56.459999,56.764999 446 | AAPL,2019-10-08,56.455002,57.014999,56.0825,56.099998 447 | AAPL,2019-10-09,56.7575,56.947498,56.41,56.7575 448 | AAPL,2019-10-10,56.982498,57.610001,56.825001,57.522499 449 | AAPL,2019-10-11,58.237499,59.41,58.077499,59.052502 450 | AAPL,2019-10-14,58.724998,59.532501,58.6675,58.967499 451 | AAPL,2019-10-15,59.0975,59.412498,58.720001,58.830002 452 | AAPL,2019-10-16,58.342499,58.810001,58.299999,58.592499 453 | AAPL,2019-10-17,58.772499,59.037498,58.380001,58.82 454 | AAPL,2019-10-18,58.647499,59.395,58.572498,59.102501 455 | AAPL,2019-10-21,59.380001,60.247501,59.330002,60.127499 456 | AAPL,2019-10-22,60.290001,60.549999,59.904999,59.990002 457 | AAPL,2019-10-23,60.525002,60.810001,60.305,60.794998 458 | AAPL,2019-10-24,61.127499,61.200001,60.452499,60.895 459 | AAPL,2019-10-25,60.790001,61.682499,60.720001,61.645 460 | AAPL,2019-10-28,61.855,62.3125,61.68,62.262501 461 | AAPL,2019-10-29,62.2425,62.4375,60.642502,60.822498 462 | AAPL,2019-10-30,61.189999,61.325001,60.302502,60.814999 463 | AAPL,2019-10-31,61.810001,62.2925,59.314999,62.189999 464 | AAPL,2019-11-01,62.384998,63.982498,62.290001,63.955002 465 | AAPL,2019-11-04,64.332497,64.462502,63.845001,64.375 466 | AAPL,2019-11-05,64.262497,64.547501,64.080002,64.282501 467 | AAPL,2019-11-06,64.192497,64.372498,63.842499,64.309998 468 | AAPL,2019-11-07,64.684998,65.087502,64.527496,64.857498 469 | AAPL,2019-11-08,64.672501,65.110001,64.212502,65.035004 470 | AAPL,2019-11-11,64.574997,65.6175,64.57,65.550003 471 | AAPL,2019-11-12,65.387497,65.697502,65.230003,65.489998 472 | AAPL,2019-11-13,65.282501,66.195,65.267502,66.1175 473 | AAPL,2019-11-14,65.9375,66.220001,65.525002,65.660004 474 | AAPL,2019-11-15,65.919998,66.445,65.752502,66.440002 475 | AAPL,2019-11-18,66.449997,66.857498,66.057503,66.775002 476 | AAPL,2019-11-19,66.974998,67,66.347504,66.572502 477 | AAPL,2019-11-20,66.385002,66.519997,65.099998,65.797501 478 | AAPL,2019-11-21,65.922501,66.002502,65.294998,65.502502 479 | AAPL,2019-11-22,65.647499,65.794998,65.209999,65.445 480 | AAPL,2019-11-25,65.677498,66.610001,65.629997,66.592499 481 | AAPL,2019-11-26,66.735001,66.790001,65.625,66.072502 482 | AAPL,2019-11-27,66.394997,66.995003,66.327499,66.959999 483 | AAPL,2019-11-29,66.650002,67,66.474998,66.8125 484 | AAPL,2019-12-02,66.817497,67.0625,65.862503,66.040001 485 | AAPL,2019-12-03,64.577499,64.8825,64.072502,64.862503 486 | AAPL,2019-12-04,65.267502,65.827499,65.169998,65.434998 487 | AAPL,2019-12-05,65.947502,66.472504,65.682503,66.394997 488 | AAPL,2019-12-06,66.870003,67.75,66.824997,67.677498 489 | AAPL,2019-12-09,67.5,67.699997,66.227501,66.730003 490 | AAPL,2019-12-10,67.150002,67.517502,66.464996,67.120003 491 | AAPL,2019-12-11,67.202499,67.775002,67.125,67.692497 492 | AAPL,2019-12-12,66.945,68.139999,66.830002,67.864998 493 | AAPL,2019-12-13,67.864998,68.824997,67.732498,68.787498 494 | AAPL,2019-12-16,69.25,70.197502,69.245003,69.964996 495 | AAPL,2019-12-17,69.892502,70.442497,69.699997,70.102501 496 | AAPL,2019-12-18,69.949997,70.474998,69.779999,69.934998 497 | AAPL,2019-12-19,69.875,70.294998,69.737503,70.004997 498 | AAPL,2019-12-20,70.557503,70.662498,69.639999,69.860001 499 | AAPL,2019-12-23,70.1325,71.0625,70.092499,71 500 | AAPL,2019-12-24,71.172501,71.222504,70.730003,71.067497 501 | AAPL,2019-12-26,71.205002,72.495003,71.175003,72.477501 502 | AAPL,2019-12-27,72.779999,73.4925,72.029999,72.449997 503 | AAPL,2019-12-30,72.364998,73.172501,71.305,72.879997 504 | AAPL,2019-12-31,72.482498,73.419998,72.379997,73.412498 505 | AAPL,2020-01-02,74.059998,75.150002,73.797501,75.087502 506 | AAPL,2020-01-03,74.287498,75.144997,74.125,74.357498 507 | AAPL,2020-01-06,73.447502,74.989998,73.1875,74.949997 508 | AAPL,2020-01-07,74.959999,75.224998,74.370003,74.597504 509 | AAPL,2020-01-08,74.290001,76.110001,74.290001,75.797501 510 | AAPL,2020-01-09,76.809998,77.607498,76.550003,77.407501 511 | AAPL,2020-01-10,77.650002,78.167503,77.0625,77.582497 512 | AAPL,2020-01-13,77.910004,79.267502,77.787498,79.239998 513 | AAPL,2020-01-14,79.175003,79.392502,78.042503,78.169998 514 | AAPL,2020-01-15,77.962502,78.875,77.387497,77.834999 515 | AAPL,2020-01-16,78.397499,78.925003,78.022499,78.809998 516 | AAPL,2020-01-17,79.067497,79.684998,78.75,79.682503 517 | AAPL,2020-01-21,79.297501,79.754997,79,79.142502 518 | AAPL,2020-01-22,79.644997,79.997498,79.327499,79.425003 519 | AAPL,2020-01-23,79.480003,79.889999,78.912498,79.807503 520 | AAPL,2020-01-24,80.0625,80.832497,79.379997,79.577499 521 | AAPL,2020-01-27,77.514999,77.942497,76.220001,77.237503 522 | AAPL,2020-01-28,78.150002,79.599998,78.047501,79.422501 523 | AAPL,2020-01-29,81.112503,81.962502,80.345001,81.084999 524 | AAPL,2020-01-30,80.135002,81.022499,79.6875,80.967499 525 | AAPL,2020-01-31,80.232498,80.669998,77.072502,77.377502 526 | AAPL,2020-02-03,76.074997,78.372498,75.555,77.165001 527 | AAPL,2020-02-04,78.827499,79.910004,78.407501,79.712502 528 | AAPL,2020-02-05,80.879997,81.190002,79.737503,80.362503 529 | AAPL,2020-02-06,80.642502,81.305,80.065002,81.302498 530 | AAPL,2020-02-07,80.592499,80.849998,79.5,80.0075 531 | AAPL,2020-02-10,78.544998,80.387497,78.462502,80.387497 532 | AAPL,2020-02-11,80.900002,80.974998,79.677498,79.902496 533 | AAPL,2020-02-12,80.3675,81.805,80.3675,81.800003 534 | AAPL,2020-02-13,81.047501,81.555,80.837502,81.217499 535 | AAPL,2020-02-14,81.184998,81.495003,80.712502,81.237503 536 | AAPL,2020-02-18,78.839996,79.9375,78.652496,79.75 537 | AAPL,2020-02-19,80,81.142502,80,80.904999 538 | AAPL,2020-02-20,80.657501,81.162498,79.552498,80.074997 539 | AAPL,2020-02-21,79.654999,80.112503,77.625,78.262497 540 | AAPL,2020-02-24,74.315002,76.044998,72.307503,74.544998 541 | AAPL,2020-02-25,75.237503,75.6325,71.532501,72.019997 542 | AAPL,2020-02-26,71.6325,74.470001,71.625,73.162498 543 | AAPL,2020-02-27,70.275002,71.5,68.239998,68.379997 544 | AAPL,2020-02-28,64.315002,69.602501,64.092499,68.339996 545 | AAPL,2020-03-02,70.57,75.360001,69.43,74.702499 546 | AAPL,2020-03-03,75.917503,76,71.449997,72.330002 547 | AAPL,2020-03-04,74.110001,75.849998,73.282501,75.684998 548 | AAPL,2020-03-05,73.879997,74.887497,72.852501,73.230003 549 | AAPL,2020-03-06,70.5,72.705002,70.307503,72.2575 550 | AAPL,2020-03-09,65.9375,69.522499,65.75,66.542503 551 | AAPL,2020-03-10,69.285004,71.610001,67.342499,71.334999 552 | AAPL,2020-03-11,69.347504,70.305,67.964996,68.857498 553 | AAPL,2020-03-12,63.985001,67.5,62,62.057499 554 | AAPL,2020-03-13,66.222504,69.980003,63.237499,69.4925 555 | AAPL,2020-03-16,60.487499,64.769997,60,60.552502 556 | AAPL,2020-03-17,61.877499,64.402496,59.599998,63.215 557 | AAPL,2020-03-18,59.942501,62.5,59.279999,61.6675 558 | AAPL,2020-03-19,61.8475,63.209999,60.6525,61.195 559 | AAPL,2020-03-20,61.794998,62.9575,57,57.310001 560 | AAPL,2020-03-23,57.02,57.125,53.1525,56.092499 561 | AAPL,2020-03-24,59.09,61.922501,58.575001,61.720001 562 | AAPL,2020-03-25,62.6875,64.5625,61.075001,61.380001 563 | AAPL,2020-03-26,61.630001,64.669998,61.59,64.610001 564 | AAPL,2020-03-27,63.1875,63.967499,61.762501,61.935001 565 | AAPL,2020-03-30,62.685001,63.880001,62.349998,63.702499 566 | AAPL,2020-03-31,63.900002,65.622498,63,63.572498 567 | AAPL,2020-04-01,61.625,62.18,59.782501,60.227501 568 | AAPL,2020-04-02,60.084999,61.287498,59.224998,61.232498 569 | AAPL,2020-04-03,60.700001,61.424999,59.7425,60.352501 570 | AAPL,2020-04-06,62.724998,65.777496,62.345001,65.6175 571 | AAPL,2020-04-07,67.699997,67.925003,64.75,64.857498 572 | AAPL,2020-04-08,65.684998,66.842499,65.307503,66.517502 573 | AAPL,2020-04-09,67.175003,67.517502,66.175003,66.997498 574 | AAPL,2020-04-13,67.077499,68.425003,66.457497,68.3125 575 | AAPL,2020-04-14,70,72.0625,69.512497,71.762497 576 | AAPL,2020-04-15,70.599998,71.582497,70.157501,71.107498 577 | AAPL,2020-04-16,71.845001,72.050003,70.587502,71.672501 578 | AAPL,2020-04-17,71.172501,71.737503,69.214996,70.699997 579 | AAPL,2020-04-20,69.487503,70.419998,69.212502,69.232498 580 | AAPL,2020-04-21,69.07,69.3125,66.357498,67.092499 581 | AAPL,2020-04-22,68.402496,69.474998,68.050003,69.025002 582 | AAPL,2020-04-23,68.967499,70.4375,68.717499,68.7575 583 | AAPL,2020-04-24,69.300003,70.752502,69.25,70.7425 584 | AAPL,2020-04-27,70.449997,71.135002,69.987503,70.792503 585 | AAPL,2020-04-28,71.269997,71.457497,69.550003,69.644997 586 | AAPL,2020-04-29,71.182503,72.417503,70.972504,71.932503 587 | AAPL,2020-04-30,72.489998,73.6325,72.087502,73.449997 588 | AAPL,2020-05-01,71.5625,74.75,71.462502,72.267502 589 | AAPL,2020-05-04,72.292503,73.422501,71.580002,73.290001 590 | AAPL,2020-05-05,73.764999,75.25,73.614998,74.389999 591 | AAPL,2020-05-06,75.114998,75.809998,74.717499,75.157501 592 | AAPL,2020-05-07,75.805,76.292503,75.4925,75.934998 593 | AAPL,2020-05-08,76.410004,77.587502,76.072502,77.532501 594 | AAPL,2020-05-11,77.025002,79.262497,76.809998,78.752502 595 | AAPL,2020-05-12,79.457497,79.922501,77.727501,77.852501 596 | AAPL,2020-05-13,78.037498,78.987503,75.802498,76.912498 597 | AAPL,2020-05-14,76.127502,77.447502,75.3825,77.385002 598 | AAPL,2020-05-15,75.087502,76.974998,75.052498,76.927498 599 | AAPL,2020-05-18,78.292503,79.125,77.580002,78.739998 600 | AAPL,2020-05-19,78.7575,79.629997,78.252502,78.285004 601 | AAPL,2020-05-20,79.169998,79.879997,79.129997,79.807503 602 | AAPL,2020-05-21,79.665001,80.222504,78.967499,79.212502 603 | AAPL,2020-05-22,78.942497,79.807503,78.837502,79.722504 604 | AAPL,2020-05-26,80.875,81.059998,79.125,79.182503 605 | AAPL,2020-05-27,79.035004,79.677498,78.272499,79.527496 606 | AAPL,2020-05-28,79.192497,80.860001,78.907501,79.5625 607 | AAPL,2020-05-29,79.8125,80.287498,79.1175,79.485001 608 | AAPL,2020-06-01,79.4375,80.587502,79.302498,80.462502 609 | AAPL,2020-06-02,80.1875,80.860001,79.732498,80.834999 610 | AAPL,2020-06-03,81.165001,81.550003,80.574997,81.279999 611 | AAPL,2020-06-04,81.097504,81.404999,80.195,80.580002 612 | AAPL,2020-06-05,80.837502,82.9375,80.807503,82.875 613 | AAPL,2020-06-08,82.5625,83.400002,81.830002,83.364998 614 | AAPL,2020-06-09,83.035004,86.402496,83.002502,85.997498 615 | AAPL,2020-06-10,86.974998,88.692497,86.522499,88.209999 616 | AAPL,2020-06-11,87.327499,87.764999,83.870003,83.974998 617 | AAPL,2020-06-12,86.18,86.949997,83.555,84.699997 618 | AAPL,2020-06-15,83.3125,86.419998,83.144997,85.747498 619 | AAPL,2020-06-16,87.864998,88.300003,86.18,88.019997 620 | AAPL,2020-06-17,88.787498,88.849998,87.772499,87.897499 621 | AAPL,2020-06-18,87.852501,88.362503,87.305,87.932503 622 | AAPL,2020-06-19,88.660004,89.139999,86.287498,87.43 623 | AAPL,2020-06-22,87.834999,89.864998,87.787498,89.717499 624 | AAPL,2020-06-23,91,93.095001,90.567497,91.6325 625 | AAPL,2020-06-24,91.25,92.197502,89.629997,90.014999 626 | AAPL,2020-06-25,90.175003,91.25,89.392502,91.209999 627 | AAPL,2020-06-26,91.102501,91.330002,88.254997,88.407501 628 | AAPL,2020-06-29,88.3125,90.542503,87.82,90.445 629 | AAPL,2020-06-30,90.019997,91.495003,90,91.199997 630 | AAPL,2020-07-01,91.279999,91.839996,90.977501,91.027496 631 | AAPL,2020-07-02,91.962502,92.6175,90.910004,91.027496 632 | AAPL,2020-07-06,92.5,93.945,92.467499,93.462502 633 | AAPL,2020-07-07,93.852501,94.654999,93.057503,93.172501 634 | AAPL,2020-07-08,94.18,95.375,94.089996,95.342499 635 | AAPL,2020-07-09,96.262497,96.317497,94.672501,95.752502 636 | AAPL,2020-07-10,95.334999,95.980003,94.705002,95.919998 637 | AAPL,2020-07-13,97.264999,99.955002,95.2575,95.477501 638 | AAPL,2020-07-14,94.839996,97.254997,93.877502,97.057503 639 | AAPL,2020-07-15,98.989998,99.247498,96.489998,97.724998 640 | AAPL,2020-07-16,96.5625,97.404999,95.904999,96.522499 641 | AAPL,2020-07-17,96.987503,97.147499,95.839996,96.327499 642 | AAPL,2020-07-20,96.417503,98.5,96.0625,98.357498 643 | AAPL,2020-07-21,99.172501,99.25,96.7425,97 644 | AAPL,2020-07-22,96.692497,97.974998,96.602501,97.272499 645 | AAPL,2020-07-23,96.997498,97.077499,92.010002,92.845001 646 | AAPL,2020-07-24,90.987503,92.970001,89.144997,92.614998 647 | AAPL,2020-07-27,93.709999,94.904999,93.480003,94.809998 648 | AAPL,2020-07-28,94.3675,94.550003,93.247498,93.252502 649 | AAPL,2020-07-29,93.75,95.230003,93.712502,95.040001 650 | AAPL,2020-07-30,94.1875,96.297501,93.767502,96.190002 651 | AAPL,2020-07-31,102.885002,106.415001,100.824997,106.260002 652 | AAPL,2020-08-03,108.199997,111.637497,107.892502,108.9375 653 | AAPL,2020-08-04,109.1325,110.790001,108.387497,109.665001 654 | AAPL,2020-08-05,109.377502,110.392502,108.897499,110.0625 655 | AAPL,2020-08-06,110.404999,114.412498,109.797501,113.902496 656 | AAPL,2020-08-07,113.205002,113.675003,110.292503,111.112503 657 | AAPL,2020-08-10,112.599998,113.775002,110,112.727501 658 | AAPL,2020-08-11,111.970001,112.482498,109.107498,109.375 659 | AAPL,2020-08-12,110.497498,113.275002,110.297501,113.010002 660 | AAPL,2020-08-13,114.43,116.042503,113.927498,115.010002 661 | AAPL,2020-08-14,114.830002,115,113.044998,114.907501 662 | AAPL,2020-08-17,116.0625,116.087502,113.962502,114.607498 663 | AAPL,2020-08-18,114.352501,116,114.0075,115.5625 664 | AAPL,2020-08-19,115.982498,117.162498,115.610001,115.707497 665 | AAPL,2020-08-20,115.75,118.392502,115.732498,118.275002 666 | AAPL,2020-08-21,119.262497,124.8675,119.25,124.370003 667 | AAPL,2020-08-24,128.697495,128.785004,123.9375,125.857498 668 | AAPL,2020-08-25,124.697502,125.18,123.052498,124.824997 669 | AAPL,2020-08-26,126.18,126.9925,125.082497,126.522499 670 | AAPL,2020-08-27,127.142502,127.485001,123.832497,125.010002 671 | AAPL,2020-08-28,126.012497,126.442497,124.577499,124.807503 672 | AAPL,2020-08-31,127.580002,131,126,129.039993 673 | AAPL,2020-09-01,132.759995,134.800003,130.529999,134.179993 674 | AAPL,2020-09-02,137.589996,137.979996,127,131.399994 675 | AAPL,2020-09-03,126.910004,128.839996,120.5,120.879997 676 | AAPL,2020-09-04,120.07,123.699997,110.889999,120.959999 677 | AAPL,2020-09-08,113.949997,118.989998,112.68,112.82 678 | AAPL,2020-09-09,117.260002,119.139999,115.260002,117.32 679 | AAPL,2020-09-10,120.360001,120.5,112.5,113.489998 680 | AAPL,2020-09-11,114.57,115.230003,110,112 681 | AAPL,2020-09-14,114.720001,115.93,112.800003,115.360001 682 | AAPL,2020-09-15,118.330002,118.830002,113.610001,115.540001 683 | AAPL,2020-09-16,115.230003,116,112.040001,112.129997 684 | AAPL,2020-09-17,109.720001,112.199997,108.709999,110.339996 685 | AAPL,2020-09-18,110.400002,110.879997,106.089996,106.839996 686 | AAPL,2020-09-21,104.540001,110.190002,103.099998,110.080002 687 | AAPL,2020-09-22,112.68,112.860001,109.160004,111.809998 688 | AAPL,2020-09-23,111.620003,112.110001,106.769997,107.120003 689 | AAPL,2020-09-24,105.169998,110.25,105,108.220001 690 | AAPL,2020-09-25,108.43,112.440002,107.669998,112.279999 691 | AAPL,2020-09-28,115.010002,115.32,112.779999,114.959999 692 | AAPL,2020-09-29,114.550003,115.309998,113.57,114.089996 693 | AAPL,2020-09-30,113.790001,117.260002,113.620003,115.809998 694 | AAPL,2020-10-01,117.639999,117.720001,115.830002,116.790001 695 | AAPL,2020-10-02,112.889999,115.370003,112.220001,113.019997 696 | AAPL,2020-10-05,113.910004,116.650002,113.550003,116.5 697 | AAPL,2020-10-06,115.699997,116.120003,112.25,113.160004 698 | AAPL,2020-10-07,114.620003,115.550003,114.129997,115.080002 699 | AAPL,2020-10-08,116.25,116.400002,114.589996,114.970001 700 | AAPL,2020-10-09,115.279999,117,114.919998,116.970001 701 | AAPL,2020-10-12,120.059998,125.18,119.279999,124.400002 702 | AAPL,2020-10-13,125.269997,125.389999,119.650002,121.099998 703 | AAPL,2020-10-14,121,123.029999,119.620003,121.190002 704 | AAPL,2020-10-15,118.720001,121.199997,118.150002,120.709999 705 | AAPL,2020-10-16,121.279999,121.550003,118.809998,119.019997 706 | AAPL,2020-10-19,119.959999,120.419998,115.660004,115.980003 707 | AAPL,2020-10-20,116.199997,118.980003,115.629997,117.510002 708 | AAPL,2020-10-21,116.669998,118.709999,116.449997,116.870003 709 | AAPL,2020-10-22,117.449997,118.040001,114.589996,115.75 710 | AAPL,2020-10-23,116.389999,116.550003,114.279999,115.040001 711 | AAPL,2020-10-26,114.010002,116.550003,112.879997,115.050003 712 | AAPL,2020-10-27,115.489998,117.279999,114.540001,116.599998 713 | AAPL,2020-10-28,115.050003,115.43,111.099998,111.199997 714 | AAPL,2020-10-29,112.370003,116.93,112.199997,115.32 715 | AAPL,2020-10-30,111.059998,111.989998,107.720001,108.860001 716 | AAPL,2020-11-02,109.110001,110.68,107.32,108.769997 717 | AAPL,2020-11-03,109.660004,111.489998,108.730003,110.440002 718 | AAPL,2020-11-04,114.139999,115.589996,112.349998,114.949997 719 | AAPL,2020-11-05,117.949997,119.620003,116.870003,119.029999 720 | AAPL,2020-11-06,118.32,119.199997,116.129997,118.690002 721 | AAPL,2020-11-09,120.5,121.989998,116.050003,116.32 722 | AAPL,2020-11-10,115.550003,117.589996,114.129997,115.970001 723 | AAPL,2020-11-11,117.190002,119.629997,116.440002,119.489998 724 | AAPL,2020-11-12,119.620003,120.529999,118.57,119.209999 725 | AAPL,2020-11-13,119.440002,119.669998,117.870003,119.260002 726 | AAPL,2020-11-16,118.919998,120.989998,118.150002,120.300003 727 | AAPL,2020-11-17,119.550003,120.669998,118.959999,119.389999 728 | AAPL,2020-11-18,118.610001,119.82,118,118.029999 729 | AAPL,2020-11-19,117.589996,119.059998,116.809998,118.639999 730 | AAPL,2020-11-20,118.639999,118.769997,117.290001,117.339996 731 | AAPL,2020-11-23,117.18,117.620003,113.75,113.849998 732 | AAPL,2020-11-24,113.910004,115.849998,112.589996,115.169998 733 | AAPL,2020-11-25,115.550003,116.75,115.169998,116.029999 734 | AAPL,2020-11-27,116.57,117.489998,116.220001,116.589996 735 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/data/GOOG.csv: -------------------------------------------------------------------------------- 1 | label,date,open,high,low,close 2 | GOOG,2017-06-30,926.049988,926.049988,908.309998,908.72998 3 | GOOG,2017-07-03,912.179993,913.940002,894.789978,898.700012 4 | GOOG,2017-07-05,901.76001,914.51001,898.5,911.710022 5 | GOOG,2017-07-06,904.119995,914.94397,899.700012,906.690002 6 | GOOG,2017-07-07,908.849976,921.539978,908.849976,918.590027 7 | GOOG,2017-07-10,921.77002,930.380005,919.590027,928.799988 8 | GOOG,2017-07-11,929.539978,931.429993,922,930.090027 9 | GOOG,2017-07-12,938.679993,946.299988,934.469971,943.830017 10 | GOOG,2017-07-13,946.289978,954.450012,943.01001,947.159973 11 | GOOG,2017-07-14,952,956.909973,948.005005,955.98999 12 | GOOG,2017-07-17,957,960.73999,949.241028,953.419983 13 | GOOG,2017-07-18,953,968.039978,950.599976,965.400024 14 | GOOG,2017-07-19,967.840027,973.039978,964.030029,970.890015 15 | GOOG,2017-07-20,975,975.900024,961.51001,968.150024 16 | GOOG,2017-07-21,962.25,973.22998,960.150024,972.919983 17 | GOOG,2017-07-24,972.219971,986.200012,970.77002,980.340027 18 | GOOG,2017-07-25,953.809998,959.700012,945.400024,950.700012 19 | GOOG,2017-07-26,954.679993,955,942.278992,947.799988 20 | GOOG,2017-07-27,951.780029,951.780029,920,934.090027 21 | GOOG,2017-07-28,929.400024,943.830017,927.5,941.530029 22 | GOOG,2017-07-31,941.890015,943.590027,926.039978,930.5 23 | GOOG,2017-08-01,932.380005,937.447021,929.26001,930.830017 24 | GOOG,2017-08-02,928.609985,932.599976,916.679993,930.390015 25 | GOOG,2017-08-03,930.340027,932.23999,922.23999,923.650024 26 | GOOG,2017-08-04,926.75,930.307007,923.030029,927.960022 27 | GOOG,2017-08-07,929.059998,931.700012,926.5,929.359985 28 | GOOG,2017-08-08,927.090027,935.814026,925.609985,926.789978 29 | GOOG,2017-08-09,920.609985,925.97998,917.25,922.900024 30 | GOOG,2017-08-10,917.549988,919.26001,906.130005,907.23999 31 | GOOG,2017-08-11,907.969971,917.780029,905.580017,914.390015 32 | GOOG,2017-08-14,922.530029,924.66803,918.190002,922.669983 33 | GOOG,2017-08-15,924.22998,926.549988,919.820007,922.219971 34 | GOOG,2017-08-16,925.289978,932.700012,923.445007,926.960022 35 | GOOG,2017-08-17,925.780029,926.859985,910.97998,910.97998 36 | GOOG,2017-08-18,910.309998,915.275024,907.153992,910.669983 37 | GOOG,2017-08-21,910,913,903.400024,906.659973 38 | GOOG,2017-08-22,912.719971,925.859985,911.474976,924.690002 39 | GOOG,2017-08-23,921.929993,929.929993,919.359985,927 40 | GOOG,2017-08-24,928.659973,930.840027,915.5,921.280029 41 | GOOG,2017-08-25,923.48999,925.554993,915.5,915.890015 42 | GOOG,2017-08-28,916,919.244995,911.869995,913.809998 43 | GOOG,2017-08-29,905.099976,923.330017,905,921.289978 44 | GOOG,2017-08-30,920.049988,930.81897,919.650024,929.570007 45 | GOOG,2017-08-31,931.76001,941.97998,931.76001,939.330017 46 | GOOG,2017-09-01,941.130005,942.47998,935.150024,937.340027 47 | GOOG,2017-09-05,933.080017,937,921.960022,928.450012 48 | GOOG,2017-09-06,930.150024,930.914978,919.27002,927.809998 49 | GOOG,2017-09-07,931.72998,936.409973,923.619995,935.950012 50 | GOOG,2017-09-08,936.48999,936.98999,924.880005,926.5 51 | GOOG,2017-09-11,934.25,938.380005,926.919983,929.080017 52 | GOOG,2017-09-12,932.590027,933.47998,923.861023,932.070007 53 | GOOG,2017-09-13,930.659973,937.25,929.859985,935.090027 54 | GOOG,2017-09-14,931.25,932.77002,924,925.109985 55 | GOOG,2017-09-15,924.659973,926.48999,916.359985,920.289978 56 | GOOG,2017-09-18,920.01001,922.080017,910.599976,915 57 | GOOG,2017-09-19,917.419983,922.419983,912.549988,921.809998 58 | GOOG,2017-09-20,922.97998,933.880005,922,931.580017 59 | GOOG,2017-09-21,933,936.530029,923.830017,932.450012 60 | GOOG,2017-09-22,927.75,934.72998,926.47998,928.530029 61 | GOOG,2017-09-25,925.450012,926.400024,909.700012,920.969971 62 | GOOG,2017-09-26,923.719971,930.820007,921.140015,924.859985 63 | GOOG,2017-09-27,927.73999,949.900024,927.73999,944.48999 64 | GOOG,2017-09-28,941.359985,950.690002,940.549988,949.5 65 | GOOG,2017-09-29,952,959.786011,951.51001,959.109985 66 | GOOG,2017-10-02,959.97998,962.539978,947.840027,953.27002 67 | GOOG,2017-10-03,954,958,949.140015,957.789978 68 | GOOG,2017-10-04,957,960.390015,950.690002,951.679993 69 | GOOG,2017-10-05,955.48999,970.909973,955.179993,969.960022 70 | GOOG,2017-10-06,966.700012,979.460022,963.359985,978.890015 71 | GOOG,2017-10-09,980,985.424988,976.109985,977 72 | GOOG,2017-10-10,980,981.570007,966.080017,972.599976 73 | GOOG,2017-10-11,973.719971,990.710022,972.25,989.25 74 | GOOG,2017-10-12,987.450012,994.119995,985,987.830017 75 | GOOG,2017-10-13,992,997.210022,989,989.679993 76 | GOOG,2017-10-16,992.099976,993.906982,984,992 77 | GOOG,2017-10-17,990.289978,996.440002,988.590027,992.179993 78 | GOOG,2017-10-18,991.77002,996.719971,986.974976,992.809998 79 | GOOG,2017-10-19,986,988.880005,978.390015,984.450012 80 | GOOG,2017-10-20,989.440002,991,984.580017,988.200012 81 | GOOG,2017-10-23,989.52002,989.52002,966.119995,968.450012 82 | GOOG,2017-10-24,970,972.22998,961,970.539978 83 | GOOG,2017-10-25,968.369995,976.090027,960.52002,973.330017 84 | GOOG,2017-10-26,980,987.599976,972.200012,972.559998 85 | GOOG,2017-10-27,1009.190002,1048.390015,1008.200012,1019.27002 86 | GOOG,2017-10-30,1014,1024.969971,1007.5,1017.109985 87 | GOOG,2017-10-31,1015.219971,1024,1010.419983,1016.640015 88 | GOOG,2017-11-01,1017.210022,1029.670044,1016.950012,1025.5 89 | GOOG,2017-11-02,1021.76001,1028.089966,1013.01001,1025.579956 90 | GOOG,2017-11-03,1022.109985,1032.650024,1020.309998,1032.47998 91 | GOOG,2017-11-06,1028.98999,1034.869995,1025,1025.900024 92 | GOOG,2017-11-07,1027.27002,1033.969971,1025.130005,1033.329956 93 | GOOG,2017-11-08,1030.52002,1043.521973,1028.449951,1039.849976 94 | GOOG,2017-11-09,1033.98999,1033.98999,1019.666016,1031.26001 95 | GOOG,2017-11-10,1026.459961,1030.76001,1025.280029,1028.069946 96 | GOOG,2017-11-13,1023.419983,1031.579956,1022.570007,1025.75 97 | GOOG,2017-11-14,1022.590027,1026.810059,1014.150024,1026 98 | GOOG,2017-11-15,1019.210022,1024.089966,1015.419983,1020.909973 99 | GOOG,2017-11-16,1022.52002,1035.920044,1022.52002,1032.5 100 | GOOG,2017-11-17,1034.01001,1034.420044,1017.75,1019.090027 101 | GOOG,2017-11-20,1020.26001,1022.609985,1017.5,1018.380005 102 | GOOG,2017-11-21,1023.309998,1035.109985,1022.655029,1034.48999 103 | GOOG,2017-11-22,1035,1039.706055,1031.430054,1035.959961 104 | GOOG,2017-11-24,1035.869995,1043.177979,1035,1040.609985 105 | GOOG,2017-11-27,1040,1055.459961,1038.439941,1054.209961 106 | GOOG,2017-11-28,1055.089966,1062.375,1040,1047.410034 107 | GOOG,2017-11-29,1042.680054,1044.079956,1015.650024,1021.659973 108 | GOOG,2017-11-30,1022.369995,1028.48999,1015,1021.409973 109 | GOOG,2017-12-01,1015.799988,1022.48999,1002.02002,1010.169983 110 | GOOG,2017-12-04,1012.659973,1016.099976,995.570007,998.679993 111 | GOOG,2017-12-05,995.940002,1020.609985,988.280029,1005.150024 112 | GOOG,2017-12-06,1001.5,1024.969971,1001.140015,1018.380005 113 | GOOG,2017-12-07,1020.429993,1034.23999,1018.070984,1030.930054 114 | GOOG,2017-12-08,1037.48999,1042.050049,1032.521973,1037.050049 115 | GOOG,2017-12-11,1035.5,1043.800049,1032.050049,1041.099976 116 | GOOG,2017-12-12,1039.630005,1050.310059,1033.689941,1040.47998 117 | GOOG,2017-12-13,1046.119995,1046.665039,1038.380005,1040.609985 118 | GOOG,2017-12-14,1045,1058.5,1043.109985,1049.150024 119 | GOOG,2017-12-15,1054.609985,1067.619995,1049.5,1064.189941 120 | GOOG,2017-12-18,1066.079956,1078.48999,1062,1077.140015 121 | GOOG,2017-12-19,1075.199951,1076.839966,1063.550049,1070.680054 122 | GOOG,2017-12-20,1071.780029,1073.380005,1061.52002,1064.949951 123 | GOOG,2017-12-21,1064.949951,1069.329956,1061.793945,1063.630005 124 | GOOG,2017-12-22,1061.109985,1064.199951,1059.439941,1060.119995 125 | GOOG,2017-12-26,1058.069946,1060.119995,1050.199951,1056.73999 126 | GOOG,2017-12-27,1057.390015,1058.369995,1048.050049,1049.369995 127 | GOOG,2017-12-28,1051.599976,1054.75,1044.77002,1048.140015 128 | GOOG,2017-12-29,1046.719971,1049.699951,1044.900024,1046.400024 129 | GOOG,2018-01-02,1048.339966,1066.939941,1045.22998,1065 130 | GOOG,2018-01-03,1064.310059,1086.290039,1063.209961,1082.47998 131 | GOOG,2018-01-04,1088,1093.569946,1084.001953,1086.400024 132 | GOOG,2018-01-05,1094,1104.25,1092,1102.22998 133 | GOOG,2018-01-08,1102.22998,1111.27002,1101.619995,1106.939941 134 | GOOG,2018-01-09,1109.400024,1110.569946,1101.230957,1106.26001 135 | GOOG,2018-01-10,1097.099976,1104.599976,1096.109985,1102.609985 136 | GOOG,2018-01-11,1106.300049,1106.525024,1099.589966,1105.52002 137 | GOOG,2018-01-12,1102.410034,1124.290039,1101.150024,1122.26001 138 | GOOG,2018-01-16,1132.51001,1139.910034,1117.832031,1121.76001 139 | GOOG,2018-01-17,1126.219971,1132.599976,1117.01001,1131.97998 140 | GOOG,2018-01-18,1131.410034,1132.51001,1117.5,1129.790039 141 | GOOG,2018-01-19,1131.829956,1137.859985,1128.300049,1137.51001 142 | GOOG,2018-01-22,1137.48999,1159.880005,1135.109985,1155.810059 143 | GOOG,2018-01-23,1159.849976,1171.626953,1158.75,1169.969971 144 | GOOG,2018-01-24,1177.329956,1179.859985,1161.050049,1164.23999 145 | GOOG,2018-01-25,1172.530029,1175.939941,1162.76001,1170.369995 146 | GOOG,2018-01-26,1175.079956,1175.839966,1158.109985,1175.839966 147 | GOOG,2018-01-29,1176.47998,1186.890015,1171.97998,1175.579956 148 | GOOG,2018-01-30,1167.829956,1176.52002,1163.52002,1163.689941 149 | GOOG,2018-01-31,1170.569946,1173,1159.130005,1169.939941 150 | GOOG,2018-02-01,1162.609985,1174,1157.52002,1167.699951 151 | GOOG,2018-02-02,1122,1123.069946,1107.277954,1111.900024 152 | GOOG,2018-02-05,1090.599976,1110,1052.030029,1055.800049 153 | GOOG,2018-02-06,1027.180054,1081.709961,1023.137024,1080.599976 154 | GOOG,2018-02-07,1081.540039,1081.780029,1048.26001,1048.579956 155 | GOOG,2018-02-08,1055.410034,1058.619995,1000.659973,1001.52002 156 | GOOG,2018-02-09,1017.25,1043.969971,992.559998,1037.780029 157 | GOOG,2018-02-12,1048,1061.5,1040.927979,1051.939941 158 | GOOG,2018-02-13,1045,1058.369995,1044.087036,1052.099976 159 | GOOG,2018-02-14,1048.949951,1071.719971,1046.75,1069.699951 160 | GOOG,2018-02-15,1079.069946,1091.479004,1064.339966,1089.52002 161 | GOOG,2018-02-16,1088.410034,1104.670044,1088.312988,1094.800049 162 | GOOG,2018-02-20,1090.569946,1113.949951,1088.52002,1102.459961 163 | GOOG,2018-02-21,1106.469971,1133.969971,1106.329956,1111.339966 164 | GOOG,2018-02-22,1116.189941,1122.819946,1102.589966,1106.630005 165 | GOOG,2018-02-23,1112.640015,1127.280029,1104.713989,1126.790039 166 | GOOG,2018-02-26,1127.800049,1143.959961,1126.694946,1143.75 167 | GOOG,2018-02-27,1141.23999,1144.040039,1118,1118.290039 168 | GOOG,2018-02-28,1123.030029,1127.530029,1103.23999,1104.72998 169 | GOOG,2018-03-01,1107.869995,1110.119995,1067.000977,1069.52002 170 | GOOG,2018-03-02,1053.079956,1081.999023,1048.11499,1078.920044 171 | GOOG,2018-03-05,1075.140015,1097.099976,1069,1090.930054 172 | GOOG,2018-03-06,1099.219971,1101.849976,1089.775024,1095.060059 173 | GOOG,2018-03-07,1089.189941,1112.219971,1085.482056,1109.640015 174 | GOOG,2018-03-08,1115.319946,1127.599976,1112.800049,1126 175 | GOOG,2018-03-09,1136,1160.800049,1132.46106,1160.040039 176 | GOOG,2018-03-12,1163.849976,1177.050049,1157.420044,1164.5 177 | GOOG,2018-03-13,1170,1176.76001,1133.329956,1138.170044 178 | GOOG,2018-03-14,1145.209961,1158.589966,1141.439941,1149.48999 179 | GOOG,2018-03-15,1149.959961,1161.079956,1134.540039,1149.579956 180 | GOOG,2018-03-16,1154.140015,1155.880005,1131.959961,1135.72998 181 | GOOG,2018-03-19,1120.01001,1121.98999,1089.01001,1099.819946 182 | GOOG,2018-03-20,1099,1105.199951,1083.459961,1097.709961 183 | GOOG,2018-03-21,1092.73999,1106.300049,1085.150024,1090.880005 184 | GOOG,2018-03-22,1081.880005,1082.900024,1045.910034,1049.079956 185 | GOOG,2018-03-23,1047.030029,1063.359985,1021.219971,1021.570007 186 | GOOG,2018-03-26,1046,1055.630005,1008.400024,1053.209961 187 | GOOG,2018-03-27,1063,1064.838989,996.919983,1005.099976 188 | GOOG,2018-03-28,998,1024.22998,980.640015,1004.559998 189 | GOOG,2018-03-29,1011.630005,1043,1002.900024,1031.790039 190 | GOOG,2018-04-02,1022.820007,1034.800049,990.369995,1006.469971 191 | GOOG,2018-04-03,1013.909973,1020.98999,994.070007,1013.409973 192 | GOOG,2018-04-04,993.409973,1028.718018,993,1025.140015 193 | GOOG,2018-04-05,1041.329956,1042.790039,1020.130981,1027.810059 194 | GOOG,2018-04-06,1020,1031.420044,1003.030029,1007.039978 195 | GOOG,2018-04-09,1016.799988,1039.599976,1014.080017,1015.450012 196 | GOOG,2018-04-10,1026.439941,1036.280029,1011.340027,1031.640015 197 | GOOG,2018-04-11,1027.98999,1031.364014,1015.869995,1019.969971 198 | GOOG,2018-04-12,1025.040039,1040.689941,1021.434998,1032.51001 199 | GOOG,2018-04-13,1040.880005,1046.420044,1022.97998,1029.27002 200 | GOOG,2018-04-16,1037,1043.23999,1026.73999,1037.97998 201 | GOOG,2018-04-17,1051.369995,1077.880005,1048.26001,1074.160034 202 | GOOG,2018-04-18,1077.430054,1077.430054,1066.224976,1072.079956 203 | GOOG,2018-04-19,1069.400024,1094.165039,1068.180054,1087.699951 204 | GOOG,2018-04-20,1082,1092.349976,1069.569946,1072.959961 205 | GOOG,2018-04-23,1077.859985,1082.719971,1060.699951,1067.449951 206 | GOOG,2018-04-24,1052,1057,1010.590027,1019.97998 207 | GOOG,2018-04-25,1025.52002,1032.48999,1015.309998,1021.179993 208 | GOOG,2018-04-26,1029.51001,1047.97998,1018.190002,1040.040039 209 | GOOG,2018-04-27,1046,1049.5,1025.589966,1030.050049 210 | GOOG,2018-04-30,1030.01001,1037,1016.849976,1017.330017 211 | GOOG,2018-05-01,1013.659973,1038.469971,1008.210022,1037.310059 212 | GOOG,2018-05-02,1028.099976,1040.389038,1022.869995,1024.380005 213 | GOOG,2018-05-03,1019,1029.675049,1006.289978,1023.719971 214 | GOOG,2018-05-04,1016.900024,1048.51001,1016.900024,1048.209961 215 | GOOG,2018-05-07,1049.22998,1061.680054,1047.099976,1054.790039 216 | GOOG,2018-05-08,1058.540039,1060.550049,1047.14502,1053.910034 217 | GOOG,2018-05-09,1058.099976,1085.439941,1056.36499,1082.76001 218 | GOOG,2018-05-10,1086.030029,1100.439941,1085.640015,1097.569946 219 | GOOG,2018-05-11,1093.599976,1101.329956,1090.910034,1098.26001 220 | GOOG,2018-05-14,1100,1110.75,1099.109985,1100.199951 221 | GOOG,2018-05-15,1090,1090.050049,1073.469971,1079.22998 222 | GOOG,2018-05-16,1077.310059,1089.27002,1076.26001,1081.77002 223 | GOOG,2018-05-17,1079.890015,1086.869995,1073.5,1078.589966 224 | GOOG,2018-05-18,1061.859985,1069.939941,1060.680054,1066.359985 225 | GOOG,2018-05-21,1074.060059,1088,1073.650024,1079.579956 226 | GOOG,2018-05-22,1083.560059,1086.589966,1066.689941,1069.72998 227 | GOOG,2018-05-23,1065.130005,1080.780029,1061.709961,1079.689941 228 | GOOG,2018-05-24,1079,1080.469971,1066.150024,1079.23999 229 | GOOG,2018-05-25,1079.02002,1082.560059,1073.775024,1075.660034 230 | GOOG,2018-05-29,1064.890015,1073.369995,1055.219971,1060.319946 231 | GOOG,2018-05-30,1063.030029,1069.209961,1056.829956,1067.800049 232 | GOOG,2018-05-31,1067.560059,1097.189941,1067.560059,1084.98999 233 | GOOG,2018-06-01,1099.349976,1120,1098.5,1119.5 234 | GOOG,2018-06-04,1122.329956,1141.890015,1122.005005,1139.290039 235 | GOOG,2018-06-05,1140.98999,1145.738037,1133.189941,1139.660034 236 | GOOG,2018-06-06,1142.170044,1143,1125.743042,1136.880005 237 | GOOG,2018-06-07,1131.319946,1135.819946,1116.52002,1123.859985 238 | GOOG,2018-06-08,1118.180054,1126.670044,1112.150024,1120.869995 239 | GOOG,2018-06-11,1118.599976,1137.26001,1118.599976,1129.98999 240 | GOOG,2018-06-12,1131.069946,1139.790039,1130.734985,1139.319946 241 | GOOG,2018-06-13,1141.119995,1146.5,1133.380005,1134.790039 242 | GOOG,2018-06-14,1143.849976,1155.469971,1140.640015,1152.119995 243 | GOOG,2018-06-15,1148.859985,1153.420044,1143.484985,1152.26001 244 | GOOG,2018-06-18,1143.650024,1174.310059,1143.589966,1173.459961 245 | GOOG,2018-06-19,1158.5,1171.27002,1154.01001,1168.060059 246 | GOOG,2018-06-20,1175.310059,1186.286011,1169.160034,1169.839966 247 | GOOG,2018-06-21,1174.849976,1177.295044,1152.232056,1157.660034 248 | GOOG,2018-06-22,1159.140015,1162.496948,1147.26001,1155.47998 249 | GOOG,2018-06-25,1143.599976,1143.910034,1112.780029,1124.810059 250 | GOOG,2018-06-26,1128,1133.209961,1116.659058,1118.459961 251 | GOOG,2018-06-27,1121.339966,1131.83606,1103.619995,1103.97998 252 | GOOG,2018-06-28,1102.089966,1122.310059,1096.01001,1114.219971 253 | GOOG,2018-06-29,1120,1128.227051,1115,1115.650024 254 | GOOG,2018-07-02,1099,1128,1093.800049,1127.459961 255 | GOOG,2018-07-03,1135.819946,1135.819946,1100.02002,1102.890015 256 | GOOG,2018-07-05,1110.530029,1127.5,1108.47998,1124.27002 257 | GOOG,2018-07-06,1123.579956,1140.930054,1120.737061,1140.170044 258 | GOOG,2018-07-09,1148.47998,1154.670044,1143.420044,1154.050049 259 | GOOG,2018-07-10,1156.97998,1159.589966,1149.589966,1152.839966 260 | GOOG,2018-07-11,1144.589966,1164.290039,1141,1153.900024 261 | GOOG,2018-07-12,1159.890015,1184.410034,1155.935059,1183.47998 262 | GOOG,2018-07-13,1185,1195.416992,1180,1188.819946 263 | GOOG,2018-07-16,1189.390015,1191,1179.280029,1183.859985 264 | GOOG,2018-07-17,1172.219971,1203.040039,1170.599976,1198.800049 265 | GOOG,2018-07-18,1196.560059,1204.5,1190.339966,1195.880005 266 | GOOG,2018-07-19,1191,1200,1183.319946,1186.959961 267 | GOOG,2018-07-20,1186.959961,1196.859985,1184.219971,1184.910034 268 | GOOG,2018-07-23,1181.01001,1206.48999,1181,1205.5 269 | GOOG,2018-07-24,1262.589966,1266,1235.560059,1248.079956 270 | GOOG,2018-07-25,1239.130005,1265.859985,1239.130005,1263.699951 271 | GOOG,2018-07-26,1251,1269.770996,1249.02002,1268.329956 272 | GOOG,2018-07-27,1271,1273.890015,1231,1238.5 273 | GOOG,2018-07-30,1228.01001,1234.916016,1211.469971,1219.73999 274 | GOOG,2018-07-31,1220.01001,1227.588013,1205.599976,1217.26001 275 | GOOG,2018-08-01,1228,1233.469971,1210.209961,1220.01001 276 | GOOG,2018-08-02,1205.900024,1229.880005,1204.790039,1226.150024 277 | GOOG,2018-08-03,1229.619995,1230,1215.060059,1223.709961 278 | GOOG,2018-08-06,1225,1226.088013,1215.796997,1224.77002 279 | GOOG,2018-08-07,1237,1251.170044,1236.170044,1242.219971 280 | GOOG,2018-08-08,1240.469971,1256.5,1238.008057,1245.609985 281 | GOOG,2018-08-09,1249.900024,1255.541992,1246.01001,1249.099976 282 | GOOG,2018-08-10,1243,1245.694946,1232,1237.609985 283 | GOOG,2018-08-13,1236.97998,1249.272949,1233.640991,1235.01001 284 | GOOG,2018-08-14,1235.189941,1245.869995,1225.109985,1242.099976 285 | GOOG,2018-08-15,1229.26001,1235.23999,1209.51001,1214.380005 286 | GOOG,2018-08-16,1224.72998,1226,1202.550049,1206.48999 287 | GOOG,2018-08-17,1202.030029,1209.02002,1188.23999,1200.959961 288 | GOOG,2018-08-20,1205.02002,1211,1194.625977,1207.77002 289 | GOOG,2018-08-21,1208,1217.26001,1200.354004,1201.619995 290 | GOOG,2018-08-22,1200,1211.839966,1199,1207.329956 291 | GOOG,2018-08-23,1207.140015,1221.280029,1204.23999,1205.380005 292 | GOOG,2018-08-24,1208.819946,1221.650024,1206.359009,1220.650024 293 | GOOG,2018-08-27,1227.599976,1243.089966,1225.715942,1241.819946 294 | GOOG,2018-08-28,1241.290039,1242.545044,1228.689941,1231.150024 295 | GOOG,2018-08-29,1237.449951,1250.660034,1236.359009,1249.300049 296 | GOOG,2018-08-30,1244.22998,1253.63501,1232.589966,1239.119995 297 | GOOG,2018-08-31,1234.97998,1238.660034,1211.285034,1218.189941 298 | GOOG,2018-09-04,1204.27002,1212.98999,1192.5,1197 299 | GOOG,2018-09-05,1193.800049,1199.01001,1162,1186.47998 300 | GOOG,2018-09-06,1186.300049,1186.300049,1152,1171.439941 301 | GOOG,2018-09-07,1158.670044,1175.26001,1157.214966,1164.829956 302 | GOOG,2018-09-10,1172.189941,1174.540039,1160.109985,1164.640015 303 | GOOG,2018-09-11,1161.630005,1178.680054,1156.23999,1177.359985 304 | GOOG,2018-09-12,1172.719971,1178.609985,1158.359985,1162.819946 305 | GOOG,2018-09-13,1170.73999,1178.609985,1162.849976,1175.329956 306 | GOOG,2018-09-14,1179.099976,1180.425049,1168.329956,1172.530029 307 | GOOG,2018-09-17,1170.140015,1177.23999,1154.030029,1156.050049 308 | GOOG,2018-09-18,1157.089966,1176.079956,1157.089966,1161.219971 309 | GOOG,2018-09-19,1164.97998,1173.209961,1154.579956,1171.089966 310 | GOOG,2018-09-20,1179.98999,1189.890015,1173.359985,1186.869995 311 | GOOG,2018-09-21,1192,1192.209961,1166.040039,1166.089966 312 | GOOG,2018-09-24,1157.170044,1178,1146.910034,1173.369995 313 | GOOG,2018-09-25,1176.150024,1186.880005,1168,1184.650024 314 | GOOG,2018-09-26,1185.150024,1194.22998,1174.765015,1180.48999 315 | GOOG,2018-09-27,1186.72998,1202.099976,1183.630005,1194.640015 316 | GOOG,2018-09-28,1191.869995,1195.410034,1184.5,1193.469971 317 | GOOG,2018-10-01,1199.890015,1209.900024,1190.300049,1195.310059 318 | GOOG,2018-10-02,1190.959961,1209.959961,1186.630005,1200.109985 319 | GOOG,2018-10-03,1205,1206.410034,1193.829956,1202.949951 320 | GOOG,2018-10-04,1195.329956,1197.51001,1155.57605,1168.189941 321 | GOOG,2018-10-05,1167.5,1173.5,1145.119995,1157.349976 322 | GOOG,2018-10-08,1150.109985,1168,1127.364014,1148.969971 323 | GOOG,2018-10-09,1146.150024,1154.349976,1137.572021,1138.819946 324 | GOOG,2018-10-10,1131.079956,1132.170044,1081.130005,1081.219971 325 | GOOG,2018-10-11,1072.939941,1106.400024,1068.27002,1079.319946 326 | GOOG,2018-10-12,1108,1115,1086.401978,1110.079956 327 | GOOG,2018-10-15,1108.910034,1113.446045,1089,1092.25 328 | GOOG,2018-10-16,1104.589966,1124.219971,1102.5,1121.280029 329 | GOOG,2018-10-17,1126.459961,1128.98999,1102.189941,1115.689941 330 | GOOG,2018-10-18,1121.839966,1121.839966,1077.089966,1087.969971 331 | GOOG,2018-10-19,1093.369995,1110.359985,1087.75,1096.459961 332 | GOOG,2018-10-22,1103.060059,1112.22998,1091,1101.160034 333 | GOOG,2018-10-23,1080.890015,1107.890015,1070,1103.689941 334 | GOOG,2018-10-24,1104.25,1106.119995,1048.73999,1050.709961 335 | GOOG,2018-10-25,1071.790039,1110.97998,1069.550049,1095.569946 336 | GOOG,2018-10-26,1037.030029,1106.530029,1034.089966,1071.469971 337 | GOOG,2018-10-29,1082.469971,1097.040039,995.830017,1020.080017 338 | GOOG,2018-10-30,1008.460022,1037.48999,1000.75,1036.209961 339 | GOOG,2018-10-31,1059.810059,1091.939941,1057,1076.77002 340 | GOOG,2018-11-01,1075.800049,1083.974976,1062.459961,1070 341 | GOOG,2018-11-02,1073.72998,1082.974976,1054.609985,1057.790039 342 | GOOG,2018-11-05,1055,1058.469971,1021.23999,1040.089966 343 | GOOG,2018-11-06,1039.47998,1064.344971,1038.069946,1055.810059 344 | GOOG,2018-11-07,1069,1095.459961,1065.900024,1093.390015 345 | GOOG,2018-11-08,1091.380005,1093.27002,1072.204956,1082.400024 346 | GOOG,2018-11-09,1073.98999,1075.560059,1053.109985,1066.150024 347 | GOOG,2018-11-12,1061.390015,1062.119995,1031,1038.630005 348 | GOOG,2018-11-13,1043.290039,1056.60498,1031.150024,1036.050049 349 | GOOG,2018-11-14,1050,1054.563965,1031,1043.660034 350 | GOOG,2018-11-15,1044.709961,1071.849976,1031.780029,1064.709961 351 | GOOG,2018-11-16,1059.410034,1067,1048.97998,1061.48999 352 | GOOG,2018-11-19,1057.199951,1060.790039,1016.26001,1020 353 | GOOG,2018-11-20,1000,1031.73999,996.02002,1025.76001 354 | GOOG,2018-11-21,1036.76001,1048.560059,1033.469971,1037.609985 355 | GOOG,2018-11-23,1030,1037.589966,1022.398987,1023.880005 356 | GOOG,2018-11-26,1038.349976,1049.310059,1033.910034,1048.619995 357 | GOOG,2018-11-27,1041,1057.579956,1038.48999,1044.410034 358 | GOOG,2018-11-28,1048.76001,1086.839966,1035.76001,1086.22998 359 | GOOG,2018-11-29,1076.079956,1094.244995,1076,1088.300049 360 | GOOG,2018-11-30,1089.069946,1095.569946,1077.880005,1094.430054 361 | GOOG,2018-12-03,1123.140015,1124.650024,1103.665039,1106.430054 362 | GOOG,2018-12-04,1103.119995,1104.420044,1049.97998,1050.819946 363 | GOOG,2018-12-06,1034.26001,1071.199951,1030.77002,1068.72998 364 | GOOG,2018-12-07,1060.01001,1075.26001,1028.5,1036.579956 365 | GOOG,2018-12-10,1035.050049,1048.449951,1023.289978,1039.550049 366 | GOOG,2018-12-11,1056.48999,1060.599976,1039.839966,1051.75 367 | GOOG,2018-12-12,1068,1081.650024,1062.790039,1063.680054 368 | GOOG,2018-12-13,1068.069946,1079.76001,1053.930054,1061.900024 369 | GOOG,2018-12-14,1049.97998,1062.599976,1040.790039,1042.099976 370 | GOOG,2018-12-17,1037.51001,1053.150024,1007.900024,1016.530029 371 | GOOG,2018-12-18,1026.089966,1049.47998,1021.440002,1028.709961 372 | GOOG,2018-12-19,1033.98999,1062,1008.049988,1023.01001 373 | GOOG,2018-12-20,1018.130005,1034.219971,996.359985,1009.409973 374 | GOOG,2018-12-21,1015.299988,1024.02002,973.690002,979.539978 375 | GOOG,2018-12-24,973.900024,1003.539978,970.109985,976.219971 376 | GOOG,2018-12-26,989.01001,1040,983,1039.459961 377 | GOOG,2018-12-27,1017.150024,1043.890015,997,1043.880005 378 | GOOG,2018-12-28,1049.619995,1055.560059,1033.099976,1037.079956 379 | GOOG,2018-12-31,1050.959961,1052.699951,1023.590027,1035.609985 380 | GOOG,2019-01-02,1016.570007,1052.319946,1015.710022,1045.849976 381 | GOOG,2019-01-03,1041,1056.97998,1014.070007,1016.059998 382 | GOOG,2019-01-04,1032.589966,1070.839966,1027.417969,1070.709961 383 | GOOG,2019-01-07,1071.5,1074,1054.76001,1068.390015 384 | GOOG,2019-01-08,1076.109985,1084.560059,1060.530029,1076.280029 385 | GOOG,2019-01-09,1081.650024,1082.630005,1066.400024,1074.660034 386 | GOOG,2019-01-10,1067.660034,1071.150024,1057.709961,1070.329956 387 | GOOG,2019-01-11,1063.180054,1063.775024,1048.47998,1057.189941 388 | GOOG,2019-01-14,1046.920044,1051.530029,1041.255005,1044.689941 389 | GOOG,2019-01-15,1050.170044,1080.050049,1047.339966,1077.150024 390 | GOOG,2019-01-16,1080,1092.375,1079.339966,1080.969971 391 | GOOG,2019-01-17,1079.469971,1091.800049,1073.5,1089.900024 392 | GOOG,2019-01-18,1100,1108.352051,1090.900024,1098.26001 393 | GOOG,2019-01-22,1088,1091.51001,1063.469971,1070.52002 394 | GOOG,2019-01-23,1077.349976,1084.930054,1059.75,1075.569946 395 | GOOG,2019-01-24,1076.47998,1079.474976,1060.699951,1073.900024 396 | GOOG,2019-01-25,1085,1094,1081.819946,1090.98999 397 | GOOG,2019-01-28,1080.109985,1083,1063.800049,1070.079956 398 | GOOG,2019-01-29,1072.680054,1075.150024,1055.86499,1060.619995 399 | GOOG,2019-01-30,1068.430054,1091,1066.849976,1089.060059 400 | GOOG,2019-01-31,1103,1117.329956,1095.410034,1116.369995 401 | GOOG,2019-02-01,1112.400024,1125,1104.890015,1110.75 402 | GOOG,2019-02-04,1112.660034,1132.800049,1109.02002,1132.800049 403 | GOOG,2019-02-05,1124.839966,1146.849976,1117.248047,1145.98999 404 | GOOG,2019-02-06,1139.569946,1147,1112.77002,1115.22998 405 | GOOG,2019-02-07,1104.160034,1104.839966,1086,1098.709961 406 | GOOG,2019-02-08,1087,1098.910034,1086.550049,1095.060059 407 | GOOG,2019-02-11,1096.949951,1105.944946,1092.859985,1095.01001 408 | GOOG,2019-02-12,1106.800049,1125.295044,1105.849976,1121.369995 409 | GOOG,2019-02-13,1124.98999,1134.72998,1118.5,1120.160034 410 | GOOG,2019-02-14,1118.050049,1128.22998,1110.444946,1121.670044 411 | GOOG,2019-02-15,1130.079956,1131.670044,1110.650024,1113.650024 412 | GOOG,2019-02-19,1110,1121.890015,1110,1118.560059 413 | GOOG,2019-02-20,1119.98999,1123.410034,1105.280029,1113.800049 414 | GOOG,2019-02-21,1110.839966,1111.939941,1092.52002,1096.969971 415 | GOOG,2019-02-22,1100.900024,1111.23999,1095.599976,1110.369995 416 | GOOG,2019-02-25,1116,1118.540039,1107.27002,1109.400024 417 | GOOG,2019-02-26,1105.75,1119.51001,1099.920044,1115.130005 418 | GOOG,2019-02-27,1106.949951,1117.97998,1101,1116.050049 419 | GOOG,2019-02-28,1111.300049,1127.650024,1111.01001,1119.920044 420 | GOOG,2019-03-01,1124.900024,1142.969971,1124.75,1140.98999 421 | GOOG,2019-03-04,1146.98999,1158.280029,1130.689941,1147.800049 422 | GOOG,2019-03-05,1150.060059,1169.609985,1146.194946,1162.030029 423 | GOOG,2019-03-06,1162.48999,1167.56604,1155.48999,1157.859985 424 | GOOG,2019-03-07,1155.719971,1156.755005,1134.910034,1143.300049 425 | GOOG,2019-03-08,1126.72998,1147.079956,1123.300049,1142.319946 426 | GOOG,2019-03-11,1144.449951,1176.189941,1144.449951,1175.76001 427 | GOOG,2019-03-12,1178.26001,1200,1178.26001,1193.199951 428 | GOOG,2019-03-13,1200.64502,1200.930054,1191.939941,1193.319946 429 | GOOG,2019-03-14,1194.51001,1197.880005,1184.47998,1185.550049 430 | GOOG,2019-03-15,1193.380005,1196.569946,1182.609985,1184.459961 431 | GOOG,2019-03-18,1183.300049,1190,1177.421021,1184.26001 432 | GOOG,2019-03-19,1188.810059,1200,1185.869995,1198.849976 433 | GOOG,2019-03-20,1197.349976,1227.140015,1196.170044,1223.969971 434 | GOOG,2019-03-21,1216,1231.790039,1213.150024,1231.540039 435 | GOOG,2019-03-22,1226.319946,1230,1202.824951,1205.5 436 | GOOG,2019-03-25,1196.930054,1206.397949,1187.040039,1193 437 | GOOG,2019-03-26,1198.530029,1202.829956,1176.719971,1184.619995 438 | GOOG,2019-03-27,1185.5,1187.55896,1159.369995,1173.02002 439 | GOOG,2019-03-28,1171.540039,1171.564941,1159.43103,1168.48999 440 | GOOG,2019-03-29,1174.900024,1178.98999,1162.880005,1173.310059 441 | GOOG,2019-04-01,1184.099976,1196.660034,1182,1194.430054 442 | GOOG,2019-04-02,1195.319946,1201.349976,1185.709961,1200.48999 443 | GOOG,2019-04-03,1207.47998,1216.300049,1200.5,1205.920044 444 | GOOG,2019-04-04,1205.939941,1215.670044,1204.130005,1215 445 | GOOG,2019-04-05,1214.98999,1216.219971,1205.030029,1207.150024 446 | GOOG,2019-04-08,1207.890015,1208.689941,1199.859985,1203.839966 447 | GOOG,2019-04-09,1196,1202.290039,1193.079956,1197.25 448 | GOOG,2019-04-10,1200.680054,1203.785034,1196.435059,1202.160034 449 | GOOG,2019-04-11,1203.959961,1207.959961,1200.130005,1204.619995 450 | GOOG,2019-04-12,1210,1218.349976,1208.109985,1217.869995 451 | GOOG,2019-04-15,1218,1224.199951,1209.109985,1221.099976 452 | GOOG,2019-04-16,1225,1230.819946,1220.119995,1227.130005 453 | GOOG,2019-04-17,1233,1240.560059,1227.819946,1236.339966 454 | GOOG,2019-04-18,1239.180054,1242,1234.609985,1236.369995 455 | GOOG,2019-04-22,1235.98999,1249.089966,1228.310059,1248.839966 456 | GOOG,2019-04-23,1250.689941,1269,1246.380005,1264.550049 457 | GOOG,2019-04-24,1264.119995,1268.01001,1255,1256 458 | GOOG,2019-04-25,1264.77002,1267.407959,1252.030029,1263.449951 459 | GOOG,2019-04-26,1269,1273.069946,1260.319946,1272.180054 460 | GOOG,2019-04-29,1274,1289.27002,1266.295044,1287.579956 461 | GOOG,2019-04-30,1185,1192.810059,1175,1188.47998 462 | GOOG,2019-05-01,1188.050049,1188.050049,1167.180054,1168.079956 463 | GOOG,2019-05-02,1167.76001,1174.189941,1155.001953,1162.609985 464 | GOOG,2019-05-03,1173.650024,1186.800049,1169,1185.400024 465 | GOOG,2019-05-06,1166.26001,1190.849976,1166.26001,1189.390015 466 | GOOG,2019-05-07,1180.469971,1190.439941,1161.040039,1174.099976 467 | GOOG,2019-05-08,1172.01001,1180.42395,1165.73999,1166.27002 468 | GOOG,2019-05-09,1159.030029,1169.660034,1150.849976,1162.380005 469 | GOOG,2019-05-10,1163.589966,1172.599976,1142.5,1164.27002 470 | GOOG,2019-05-13,1141.959961,1147.939941,1122.109985,1132.030029 471 | GOOG,2019-05-14,1137.209961,1140.420044,1119.550049,1120.439941 472 | GOOG,2019-05-15,1117.869995,1171.329956,1116.666016,1164.209961 473 | GOOG,2019-05-16,1164.51001,1188.160034,1162.839966,1178.97998 474 | GOOG,2019-05-17,1168.469971,1180.150024,1160.01001,1162.300049 475 | GOOG,2019-05-20,1144.5,1146.796997,1131.442993,1138.849976 476 | GOOG,2019-05-21,1148.48999,1152.708008,1137.939941,1149.630005 477 | GOOG,2019-05-22,1146.75,1158.52002,1145.890015,1151.420044 478 | GOOG,2019-05-23,1140.5,1145.973022,1129.223999,1140.77002 479 | GOOG,2019-05-24,1147.359985,1149.765015,1131.660034,1133.469971 480 | GOOG,2019-05-28,1134,1151.587036,1133.119995,1134.150024 481 | GOOG,2019-05-29,1127.52002,1129.099976,1108.219971,1116.459961 482 | GOOG,2019-05-30,1115.540039,1123.130005,1112.119995,1117.949951 483 | GOOG,2019-05-31,1101.290039,1109.599976,1100.180054,1103.630005 484 | GOOG,2019-06-03,1065.5,1065.5,1025,1036.22998 485 | GOOG,2019-06-04,1042.900024,1056.050049,1033.689941,1053.050049 486 | GOOG,2019-06-05,1051.540039,1053.550049,1030.48999,1042.219971 487 | GOOG,2019-06-06,1044.98999,1047.48999,1033.699951,1044.339966 488 | GOOG,2019-06-07,1050.630005,1070.920044,1048.400024,1066.040039 489 | GOOG,2019-06-10,1072.97998,1092.660034,1072.322021,1080.380005 490 | GOOG,2019-06-11,1093.97998,1101.98999,1077.603027,1078.719971 491 | GOOG,2019-06-12,1078,1080.930054,1067.540039,1077.030029 492 | GOOG,2019-06-13,1083.640015,1094.170044,1080.150024,1088.77002 493 | GOOG,2019-06-14,1086.420044,1092.689941,1080.171997,1085.349976 494 | GOOG,2019-06-17,1086.280029,1099.180054,1086.280029,1092.5 495 | GOOG,2019-06-18,1109.689941,1116.390015,1098.98999,1103.599976 496 | GOOG,2019-06-19,1105.599976,1107,1093.47998,1102.329956 497 | GOOG,2019-06-20,1119.98999,1120.119995,1104.73999,1111.420044 498 | GOOG,2019-06-21,1109.23999,1124.109985,1108.079956,1121.880005 499 | GOOG,2019-06-24,1119.609985,1122,1111.01001,1115.52002 500 | GOOG,2019-06-25,1112.660034,1114.349976,1083.800049,1086.349976 501 | GOOG,2019-06-26,1086.5,1092.969971,1072.23999,1079.800049 502 | GOOG,2019-06-27,1084,1087.099976,1075.290039,1076.01001 503 | GOOG,2019-06-28,1076.390015,1081,1073.369995,1080.910034 504 | GOOG,2019-07-01,1098,1107.579956,1093.703003,1097.949951 505 | GOOG,2019-07-02,1102.23999,1111.77002,1098.170044,1111.25 506 | GOOG,2019-07-03,1117.410034,1126.76001,1113.859985,1121.579956 507 | GOOG,2019-07-05,1117.800049,1132.880005,1116.140015,1131.589966 508 | GOOG,2019-07-08,1125.170044,1125.97998,1111.209961,1116.349976 509 | GOOG,2019-07-09,1111.800049,1128.025024,1107.170044,1124.829956 510 | GOOG,2019-07-10,1131.219971,1142.050049,1130.969971,1140.47998 511 | GOOG,2019-07-11,1143.25,1153.069946,1139.579956,1144.209961 512 | GOOG,2019-07-12,1143.98999,1147.339966,1138.780029,1144.900024 513 | GOOG,2019-07-15,1146.859985,1150.819946,1139.400024,1150.339966 514 | GOOG,2019-07-16,1146,1158.579956,1145,1153.579956 515 | GOOG,2019-07-17,1150.969971,1158.359985,1145.77002,1146.349976 516 | GOOG,2019-07-18,1141.73999,1147.60498,1132.72998,1146.329956 517 | GOOG,2019-07-19,1148.189941,1151.140015,1129.619995,1130.099976 518 | GOOG,2019-07-22,1133.449951,1139.25,1124.23999,1138.069946 519 | GOOG,2019-07-23,1144,1146.900024,1131.800049,1146.209961 520 | GOOG,2019-07-24,1131.900024,1144,1126.98999,1137.810059 521 | GOOG,2019-07-25,1137.819946,1141.699951,1120.920044,1132.119995 522 | GOOG,2019-07-26,1224.040039,1265.550049,1224,1250.410034 523 | GOOG,2019-07-29,1241.050049,1247.369995,1228.22998,1239.410034 524 | GOOG,2019-07-30,1225.410034,1234.869995,1223.300049,1225.140015 525 | GOOG,2019-07-31,1223,1234,1207.764038,1216.680054 526 | GOOG,2019-08-01,1214.030029,1234.109985,1205.719971,1209.01001 527 | GOOG,2019-08-02,1200.73999,1206.900024,1188.939941,1193.98999 528 | GOOG,2019-08-05,1170.040039,1175.23999,1140.140015,1152.319946 529 | GOOG,2019-08-06,1163.310059,1179.959961,1160,1169.949951 530 | GOOG,2019-08-07,1156,1178.444946,1149.624023,1173.98999 531 | GOOG,2019-08-08,1182.829956,1205.01001,1173.02002,1204.800049 532 | GOOG,2019-08-09,1197.98999,1203.880005,1183.603027,1188.01001 533 | GOOG,2019-08-12,1179.209961,1184.959961,1167.671997,1174.709961 534 | GOOG,2019-08-13,1171.459961,1204.780029,1171.459961,1197.27002 535 | GOOG,2019-08-14,1176.310059,1182.300049,1160.540039,1164.290039 536 | GOOG,2019-08-15,1163.5,1175.839966,1162.109985,1167.26001 537 | GOOG,2019-08-16,1179.550049,1182.719971,1171.810059,1177.599976 538 | GOOG,2019-08-19,1190.089966,1206.98999,1190.089966,1198.449951 539 | GOOG,2019-08-20,1195.25,1196.060059,1182.109985,1182.689941 540 | GOOG,2019-08-21,1193.150024,1199,1187.430054,1191.25 541 | GOOG,2019-08-22,1194.069946,1198.011963,1178.579956,1189.530029 542 | GOOG,2019-08-23,1181.98999,1194.079956,1147.75,1151.290039 543 | GOOG,2019-08-26,1157.26001,1169.469971,1152.959961,1168.890015 544 | GOOG,2019-08-27,1180.530029,1182.400024,1161.449951,1167.839966 545 | GOOG,2019-08-28,1161.709961,1176.420044,1157.300049,1171.02002 546 | GOOG,2019-08-29,1181.119995,1196.060059,1181.119995,1192.849976 547 | GOOG,2019-08-30,1198.5,1198.5,1183.802979,1188.099976 548 | GOOG,2019-09-03,1177.030029,1186.890015,1163.199951,1168.390015 549 | GOOG,2019-09-04,1176.709961,1183.47998,1171,1181.410034 550 | GOOG,2019-09-05,1191.530029,1213.040039,1191.530029,1211.380005 551 | GOOG,2019-09-06,1208.130005,1212.015015,1202.521973,1204.930054 552 | GOOG,2019-09-09,1204,1220,1192.619995,1204.410034 553 | GOOG,2019-09-10,1195.150024,1210,1194.579956,1206 554 | GOOG,2019-09-11,1203.410034,1222.599976,1202.199951,1220.170044 555 | GOOG,2019-09-12,1224.300049,1241.859985,1223.02002,1234.25 556 | GOOG,2019-09-13,1231.349976,1240.880005,1227.01001,1239.560059 557 | GOOG,2019-09-16,1229.52002,1239.560059,1225.609985,1231.300049 558 | GOOG,2019-09-17,1230.400024,1235,1223.689941,1229.150024 559 | GOOG,2019-09-18,1227.51001,1235.609985,1216.530029,1232.410034 560 | GOOG,2019-09-19,1232.060059,1244.439941,1232.02002,1238.709961 561 | GOOG,2019-09-20,1233.119995,1243.319946,1223.079956,1229.930054 562 | GOOG,2019-09-23,1226,1239.089966,1224.170044,1234.030029 563 | GOOG,2019-09-24,1240,1246.73999,1210.680054,1218.76001 564 | GOOG,2019-09-25,1215.819946,1248.300049,1210.089966,1246.52002 565 | GOOG,2019-09-26,1241.959961,1245,1232.267944,1241.390015 566 | GOOG,2019-09-27,1243.01001,1244.02002,1214.449951,1225.089966 567 | GOOG,2019-09-30,1220.969971,1226,1212.300049,1219 568 | GOOG,2019-10-01,1219,1231.22998,1203.579956,1205.099976 569 | GOOG,2019-10-02,1196.97998,1196.97998,1171.290039,1176.630005 570 | GOOG,2019-10-03,1180,1189.060059,1162.430054,1187.829956 571 | GOOG,2019-10-04,1191.890015,1211.439941,1189.170044,1209 572 | GOOG,2019-10-07,1204.400024,1218.203979,1203.75,1207.680054 573 | GOOG,2019-10-08,1197.589966,1206.079956,1189.01001,1189.130005 574 | GOOG,2019-10-09,1199.349976,1208.349976,1197.630005,1202.310059 575 | GOOG,2019-10-10,1198.579956,1215,1197.339966,1208.670044 576 | GOOG,2019-10-11,1222.209961,1228.390015,1213.73999,1215.449951 577 | GOOG,2019-10-14,1212.339966,1226.329956,1211.76001,1217.140015 578 | GOOG,2019-10-15,1220.400024,1247.329956,1220.400024,1243.01001 579 | GOOG,2019-10-16,1241.170044,1254.73999,1238.449951,1243.640015 580 | GOOG,2019-10-17,1250.930054,1263.324951,1249.939941,1253.069946 581 | GOOG,2019-10-18,1253.459961,1258.890015,1241.079956,1245.48999 582 | GOOG,2019-10-21,1252.26001,1254.629028,1240.599976,1246.150024 583 | GOOG,2019-10-22,1247.849976,1250.599976,1241.380005,1242.800049 584 | GOOG,2019-10-23,1242.359985,1259.890015,1242.359985,1259.130005 585 | GOOG,2019-10-24,1260.900024,1264,1253.714966,1260.98999 586 | GOOG,2019-10-25,1251.030029,1269.599976,1250.01001,1265.130005 587 | GOOG,2019-10-28,1275.449951,1299.310059,1272.540039,1290 588 | GOOG,2019-10-29,1276.22998,1281.589966,1257.212036,1262.619995 589 | GOOG,2019-10-30,1252.969971,1269.359985,1252,1261.290039 590 | GOOG,2019-10-31,1261.280029,1267.670044,1250.843018,1260.109985 591 | GOOG,2019-11-01,1265,1274.619995,1260.5,1273.73999 592 | GOOG,2019-11-04,1276.449951,1294.130005,1276.35498,1291.369995 593 | GOOG,2019-11-05,1292.890015,1298.930054,1291.229004,1292.030029 594 | GOOG,2019-11-06,1289.459961,1293.72998,1282.5,1291.800049 595 | GOOG,2019-11-07,1294.280029,1323.73999,1294.244995,1308.859985 596 | GOOG,2019-11-08,1305.280029,1318,1304.36499,1311.369995 597 | GOOG,2019-11-11,1303.180054,1306.425049,1297.410034,1299.189941 598 | GOOG,2019-11-12,1300,1310,1295.77002,1298.800049 599 | GOOG,2019-11-13,1294.069946,1304.300049,1293.51001,1298 600 | GOOG,2019-11-14,1297.5,1317,1295.650024,1311.459961 601 | GOOG,2019-11-15,1318.939941,1334.880005,1314.280029,1334.869995 602 | GOOG,2019-11-18,1332.219971,1335.529053,1317.5,1320.699951 603 | GOOG,2019-11-19,1327.699951,1327.699951,1312.800049,1315.459961 604 | GOOG,2019-11-20,1311.73999,1315,1291.150024,1303.050049 605 | GOOG,2019-11-21,1301.47998,1312.589966,1293,1301.349976 606 | GOOG,2019-11-22,1305.619995,1308.72998,1291.410034,1295.339966 607 | GOOG,2019-11-25,1299.180054,1311.310059,1298.130005,1306.689941 608 | GOOG,2019-11-26,1309.859985,1314.800049,1305.089966,1313.550049 609 | GOOG,2019-11-27,1315,1318.359985,1309.630005,1312.98999 610 | GOOG,2019-11-29,1307.119995,1310.204956,1303.969971,1304.959961 611 | GOOG,2019-12-02,1301,1305.829956,1281,1289.920044 612 | GOOG,2019-12-03,1279.569946,1298.46106,1279,1295.280029 613 | GOOG,2019-12-04,1307.01001,1325.800049,1304.869995,1320.540039 614 | GOOG,2019-12-05,1328,1329.358032,1316.439941,1328.130005 615 | GOOG,2019-12-06,1333.439941,1344,1333.439941,1340.619995 616 | GOOG,2019-12-09,1338.040039,1359.449951,1337.839966,1343.560059 617 | GOOG,2019-12-10,1341.5,1349.974976,1336.040039,1344.660034 618 | GOOG,2019-12-11,1350.839966,1351.199951,1342.670044,1345.02002 619 | GOOG,2019-12-12,1345.939941,1355.775024,1340.5,1350.27002 620 | GOOG,2019-12-13,1347.949951,1353.093018,1343.869995,1347.829956 621 | GOOG,2019-12-16,1356.5,1364.680054,1352.670044,1361.170044 622 | GOOG,2019-12-17,1362.890015,1365,1351.322998,1355.119995 623 | GOOG,2019-12-18,1356.599976,1360.469971,1351,1352.619995 624 | GOOG,2019-12-19,1351.819946,1358.099976,1348.984985,1356.040039 625 | GOOG,2019-12-20,1363.349976,1363.640015,1349,1349.589966 626 | GOOG,2019-12-23,1355.869995,1359.800049,1346.51001,1348.839966 627 | GOOG,2019-12-24,1348.5,1350.26001,1342.780029,1343.560059 628 | GOOG,2019-12-26,1346.170044,1361.327026,1344.469971,1360.400024 629 | GOOG,2019-12-27,1362.98999,1364.530029,1349.310059,1351.890015 630 | GOOG,2019-12-30,1350,1353,1334.02002,1336.140015 631 | GOOG,2019-12-31,1330.109985,1338,1329.084961,1337.02002 632 | GOOG,2020-01-02,1341.550049,1368.140015,1341.550049,1367.369995 633 | GOOG,2020-01-03,1347.859985,1372.5,1345.543945,1360.660034 634 | GOOG,2020-01-06,1350,1396.5,1350,1394.209961 635 | GOOG,2020-01-07,1397.939941,1402.98999,1390.380005,1393.339966 636 | GOOG,2020-01-08,1392.079956,1411.579956,1390.839966,1404.319946 637 | GOOG,2020-01-09,1420.569946,1427.329956,1410.27002,1419.829956 638 | GOOG,2020-01-10,1427.560059,1434.928955,1418.349976,1429.72998 639 | GOOG,2020-01-13,1436.130005,1440.52002,1426.02002,1439.22998 640 | GOOG,2020-01-14,1439.01001,1441.800049,1428.369995,1430.880005 641 | GOOG,2020-01-15,1430.209961,1441.39502,1430.209961,1439.199951 642 | GOOG,2020-01-16,1447.439941,1451.98999,1440.920044,1451.699951 643 | GOOG,2020-01-17,1462.910034,1481.295044,1458.219971,1480.390015 644 | GOOG,2020-01-21,1479.119995,1491.849976,1471.199951,1484.400024 645 | GOOG,2020-01-22,1491,1503.213989,1484.930054,1485.949951 646 | GOOG,2020-01-23,1487.640015,1495.52002,1482.099976,1486.650024 647 | GOOG,2020-01-24,1493.589966,1495.494995,1465.25,1466.709961 648 | GOOG,2020-01-27,1431,1438.069946,1421.199951,1433.900024 649 | GOOG,2020-01-28,1443,1456,1432.469971,1452.560059 650 | GOOG,2020-01-29,1458.800049,1465.430054,1446.73999,1458.630005 651 | GOOG,2020-01-30,1439.959961,1457.280029,1436.400024,1455.839966 652 | GOOG,2020-01-31,1468.900024,1470.130005,1428.530029,1434.22998 653 | GOOG,2020-02-03,1462,1490,1458.98999,1485.939941 654 | GOOG,2020-02-04,1457.069946,1469.5,1426.300049,1447.069946 655 | GOOG,2020-02-05,1462.420044,1463.839966,1430.560059,1448.22998 656 | GOOG,2020-02-06,1450.329956,1482,1449.569946,1476.22998 657 | GOOG,2020-02-07,1467.300049,1485.839966,1466.349976,1479.22998 658 | GOOG,2020-02-10,1474.319946,1509.5,1474.319946,1508.680054 659 | GOOG,2020-02-11,1511.810059,1529.630005,1505.637939,1508.790039 660 | GOOG,2020-02-12,1514.47998,1520.694946,1508.109985,1518.27002 661 | GOOG,2020-02-13,1512.689941,1527.180054,1504.599976,1514.660034 662 | GOOG,2020-02-14,1515.599976,1520.73999,1507.339966,1520.73999 663 | GOOG,2020-02-18,1515,1531.630005,1512.589966,1519.670044 664 | GOOG,2020-02-19,1525.069946,1532.105957,1521.400024,1526.689941 665 | GOOG,2020-02-20,1522,1529.640015,1506.819946,1518.150024 666 | GOOG,2020-02-21,1508.030029,1512.214966,1480.439941,1485.109985 667 | GOOG,2020-02-24,1426.109985,1436.969971,1411.390015,1421.589966 668 | GOOG,2020-02-25,1433,1438.140015,1382.400024,1388.449951 669 | GOOG,2020-02-26,1396.140015,1415.699951,1379,1393.180054 670 | GOOG,2020-02-27,1362.060059,1371.703979,1317.170044,1318.089966 671 | GOOG,2020-02-28,1277.5,1341.140015,1271,1339.329956 672 | GOOG,2020-03-02,1351.609985,1390.869995,1326.814941,1389.109985 673 | GOOG,2020-03-03,1399.420044,1410.150024,1332,1341.390015 674 | GOOG,2020-03-04,1359.22998,1388.089966,1343.109985,1386.52002 675 | GOOG,2020-03-05,1350.199951,1358.910034,1305.099976,1319.040039 676 | GOOG,2020-03-06,1277.060059,1306.219971,1261.050049,1298.410034 677 | GOOG,2020-03-09,1205.300049,1254.76001,1200,1215.560059 678 | GOOG,2020-03-10,1260,1281.150024,1218.77002,1280.390015 679 | GOOG,2020-03-11,1249.699951,1260.959961,1196.069946,1215.410034 680 | GOOG,2020-03-12,1126,1193.869995,1113.300049,1114.910034 681 | GOOG,2020-03-13,1179,1219.76001,1117.142944,1219.72998 682 | GOOG,2020-03-16,1096,1152.266968,1074.439941,1084.329956 683 | GOOG,2020-03-17,1093.109985,1130.859985,1056.01001,1119.800049 684 | GOOG,2020-03-18,1056.51001,1106.5,1037.280029,1096.800049 685 | GOOG,2020-03-19,1093.050049,1157.969971,1060.108032,1115.290039 686 | GOOG,2020-03-20,1135.719971,1143.98999,1065.48999,1072.319946 687 | GOOG,2020-03-23,1061.319946,1071.319946,1013.536011,1056.619995 688 | GOOG,2020-03-24,1103.77002,1135,1090.619995,1134.459961 689 | GOOG,2020-03-25,1126.469971,1148.900024,1086.01001,1102.48999 690 | GOOG,2020-03-26,1111.800049,1169.969971,1093.530029,1161.75 691 | GOOG,2020-03-27,1125.670044,1150.670044,1105.910034,1110.709961 692 | GOOG,2020-03-30,1125.040039,1151.630005,1096.47998,1146.819946 693 | GOOG,2020-03-31,1147.300049,1175.310059,1138.140015,1162.810059 694 | GOOG,2020-04-01,1122,1129.689941,1097.449951,1105.619995 695 | GOOG,2020-04-02,1098.26001,1126.859985,1096.400024,1120.839966 696 | GOOG,2020-04-03,1119.015015,1123.540039,1079.810059,1097.880005 697 | GOOG,2020-04-06,1138,1194.660034,1130.939941,1186.920044 698 | GOOG,2020-04-07,1221,1225,1182.22998,1186.51001 699 | GOOG,2020-04-08,1206.5,1219.069946,1188.160034,1210.280029 700 | GOOG,2020-04-09,1224.079956,1225.569946,1196.734985,1211.449951 701 | GOOG,2020-04-13,1209.180054,1220.51001,1187.598022,1217.560059 702 | GOOG,2020-04-14,1245.089966,1282.069946,1236.930054,1269.22998 703 | GOOG,2020-04-15,1245.609985,1280.459961,1240.400024,1262.469971 704 | GOOG,2020-04-16,1274.099976,1279,1242.619995,1263.469971 705 | GOOG,2020-04-17,1284.849976,1294.430054,1271.22998,1283.25 706 | GOOG,2020-04-20,1271,1281.599976,1261.369995,1266.609985 707 | GOOG,2020-04-21,1247,1254.27002,1209.709961,1216.339966 708 | GOOG,2020-04-22,1245.540039,1285.613037,1242,1263.209961 709 | GOOG,2020-04-23,1271.550049,1293.310059,1265.670044,1276.310059 710 | GOOG,2020-04-24,1261.170044,1280.400024,1249.449951,1279.310059 711 | GOOG,2020-04-27,1296,1296.150024,1269,1275.880005 712 | GOOG,2020-04-28,1287.930054,1288.050049,1232.199951,1233.670044 713 | GOOG,2020-04-29,1341.459961,1359.98999,1325.339966,1341.47998 714 | GOOG,2020-04-30,1324.880005,1352.819946,1322.48999,1348.660034 715 | GOOG,2020-05-01,1328.5,1352.069946,1311,1320.609985 716 | GOOG,2020-05-04,1308.22998,1327.660034,1299,1326.800049 717 | GOOG,2020-05-05,1337.920044,1373.939941,1337.459961,1351.109985 718 | GOOG,2020-05-06,1361.689941,1371.119995,1347.290039,1347.300049 719 | GOOG,2020-05-07,1365.939941,1377.599976,1355.27002,1372.560059 720 | GOOG,2020-05-08,1383.130005,1398.76001,1375.47998,1388.369995 721 | GOOG,2020-05-11,1378.280029,1416.530029,1377.151978,1403.26001 722 | GOOG,2020-05-12,1407.119995,1415,1374.77002,1375.73999 723 | GOOG,2020-05-13,1377.050049,1385.482056,1328.400024,1349.329956 724 | GOOG,2020-05-14,1335.02002,1357.420044,1323.910034,1356.130005 725 | GOOG,2020-05-15,1350,1374.47998,1339,1373.189941 726 | GOOG,2020-05-18,1361.75,1392.324951,1354.25,1383.939941 727 | GOOG,2020-05-19,1386.996948,1392,1373.484985,1373.484985 728 | GOOG,2020-05-20,1389.579956,1410.420044,1387.25,1406.719971 729 | GOOG,2020-05-21,1408,1415.48999,1393.449951,1402.800049 730 | GOOG,2020-05-22,1396.709961,1412.76001,1391.829956,1410.420044 731 | GOOG,2020-05-26,1437.27002,1441,1412.130005,1417.02002 732 | GOOG,2020-05-27,1417.25,1421.73999,1391.290039,1417.839966 733 | GOOG,2020-05-28,1396.859985,1440.839966,1396,1416.72998 734 | GOOG,2020-05-29,1416.939941,1432.569946,1413.349976,1428.920044 735 | GOOG,2020-06-01,1418.390015,1437.959961,1418,1431.819946 736 | GOOG,2020-06-02,1430.550049,1439.609985,1418.829956,1439.219971 737 | GOOG,2020-06-03,1438.300049,1446.552002,1429.776978,1436.380005 738 | GOOG,2020-06-04,1430.400024,1438.959961,1404.72998,1412.180054 739 | GOOG,2020-06-05,1413.170044,1445.050049,1406,1438.390015 740 | GOOG,2020-06-08,1422.339966,1447.98999,1422.339966,1446.609985 741 | GOOG,2020-06-09,1445.359985,1468,1443.209961,1456.160034 742 | GOOG,2020-06-10,1459.540039,1474.259033,1456.27002,1465.849976 743 | GOOG,2020-06-11,1442.47998,1454.474976,1402,1403.839966 744 | GOOG,2020-06-12,1428.48999,1437,1386.02002,1413.180054 745 | GOOG,2020-06-15,1390.800049,1424.800049,1387.920044,1419.849976 746 | GOOG,2020-06-16,1445.219971,1455.02002,1425.900024,1442.719971 747 | GOOG,2020-06-17,1447.160034,1460,1431.380005,1451.119995 748 | GOOG,2020-06-18,1449.160034,1451.410034,1427.01001,1435.959961 749 | GOOG,2020-06-19,1444,1447.800049,1421.349976,1431.719971 750 | GOOG,2020-06-22,1429,1452.75,1423.209961,1451.859985 751 | GOOG,2020-06-23,1455.640015,1475.94104,1445.23999,1464.410034 752 | GOOG,2020-06-24,1461.51001,1475.420044,1429.75,1431.969971 753 | GOOG,2020-06-25,1429.900024,1442.900024,1420,1441.329956 754 | GOOG,2020-06-26,1431.390015,1433.449951,1351.98999,1359.900024 755 | GOOG,2020-06-29,1358.180054,1395.599976,1347.01001,1394.969971 756 | GOOG,2020-06-30,1390.439941,1418.650024,1383.959961,1413.609985 757 | GOOG,2020-07-01,1411.099976,1443,1409.819946,1438.040039 758 | GOOG,2020-07-02,1446.939941,1482.949951,1446.420044,1464.699951 759 | GOOG,2020-07-06,1480.060059,1506.589966,1472.859985,1495.699951 760 | GOOG,2020-07-07,1490,1516.800049,1483.550049,1485.180054 761 | GOOG,2020-07-08,1494.319946,1505.880005,1485.630005,1496 762 | GOOG,2020-07-09,1506.449951,1522.719971,1488.084961,1510.98999 763 | GOOG,2020-07-10,1506.150024,1543.829956,1496.540039,1541.73999 764 | GOOG,2020-07-13,1550,1577.131958,1505.243042,1511.339966 765 | GOOG,2020-07-14,1490.310059,1522.949951,1483.5,1520.579956 766 | GOOG,2020-07-15,1523.130005,1535.329956,1498,1513.640015 767 | GOOG,2020-07-16,1500,1518.689941,1486.310059,1518 768 | GOOG,2020-07-17,1521.619995,1523.439941,1498.420044,1515.550049 769 | GOOG,2020-07-20,1515.26001,1570.290039,1503.599976,1565.719971 770 | GOOG,2020-07-21,1586.98999,1586.98999,1554.280029,1558.420044 771 | GOOG,2020-07-22,1560.5,1570,1546.099976,1568.48999 772 | GOOG,2020-07-23,1566.969971,1571.869995,1507.391968,1515.680054 773 | GOOG,2020-07-24,1498.930054,1517.635986,1488.400024,1511.869995 774 | GOOG,2020-07-27,1515.599976,1540.969971,1515.209961,1530.199951 775 | GOOG,2020-07-28,1525.180054,1526.47998,1497.660034,1500.339966 776 | GOOG,2020-07-29,1506.319946,1531.251953,1501.329956,1522.02002 777 | GOOG,2020-07-30,1497,1537.869995,1492.219971,1531.449951 778 | GOOG,2020-07-31,1505.01001,1508.949951,1454.030029,1482.959961 779 | GOOG,2020-08-03,1486.640015,1490.469971,1465.640015,1474.449951 780 | GOOG,2020-08-04,1476.569946,1485.560059,1458.650024,1464.969971 781 | GOOG,2020-08-05,1469.300049,1482.410034,1463.459961,1473.609985 782 | GOOG,2020-08-06,1471.75,1502.390015,1466,1500.099976 783 | GOOG,2020-08-07,1500,1516.844971,1481.640015,1494.48999 784 | GOOG,2020-08-10,1487.180054,1504.074951,1473.079956,1496.099976 785 | GOOG,2020-08-11,1492.439941,1510,1478,1480.319946 786 | GOOG,2020-08-12,1485.579956,1512.385986,1485.25,1506.619995 787 | GOOG,2020-08-13,1510.339966,1537.25,1508.005005,1518.449951 788 | GOOG,2020-08-14,1515.660034,1521.900024,1502.880005,1507.72998 789 | GOOG,2020-08-17,1514.670044,1525.609985,1507.969971,1517.97998 790 | GOOG,2020-08-18,1526.180054,1562.469971,1523.709961,1558.599976 791 | GOOG,2020-08-19,1553.310059,1573.680054,1543.949951,1547.530029 792 | GOOG,2020-08-20,1543.449951,1585.869995,1538.199951,1581.75 793 | GOOG,2020-08-21,1577.030029,1597.719971,1568.005005,1580.420044 794 | GOOG,2020-08-24,1593.97998,1614.170044,1580.569946,1588.199951 795 | GOOG,2020-08-25,1582.069946,1611.619995,1582.069946,1608.219971 796 | GOOG,2020-08-26,1608,1659.219971,1603.599976,1652.380005 797 | GOOG,2020-08-27,1653.680054,1655,1625.75,1634.329956 798 | GOOG,2020-08-28,1633.48999,1647.170044,1630.75,1644.410034 799 | GOOG,2020-08-31,1647.890015,1647.964966,1630.310059,1634.180054 800 | GOOG,2020-09-01,1636.630005,1665.72998,1632.219971,1660.709961 801 | GOOG,2020-09-02,1673.775024,1733.180054,1666.329956,1728.280029 802 | GOOG,2020-09-03,1709.713989,1709.713989,1615.060059,1641.839966 803 | GOOG,2020-09-04,1624.26001,1645.109985,1547.613037,1591.040039 804 | GOOG,2020-09-08,1533.51001,1563.86499,1528.01001,1532.390015 805 | GOOG,2020-09-09,1557.530029,1569,1536.051025,1556.959961 806 | GOOG,2020-09-10,1560.640015,1584.081055,1525.805054,1532.02002 807 | GOOG,2020-09-11,1536,1575.199951,1497.359985,1520.719971 808 | GOOG,2020-09-14,1539.005005,1564,1515.73999,1519.280029 809 | GOOG,2020-09-15,1536,1559.569946,1531.834961,1541.439941 810 | GOOG,2020-09-16,1555.540039,1562,1519.819946,1520.900024 811 | GOOG,2020-09-17,1496,1508.297974,1470,1495.530029 812 | GOOG,2020-09-18,1498.01001,1503.003052,1437.130005,1459.98999 813 | GOOG,2020-09-21,1440.060059,1448.359985,1406.550049,1431.160034 814 | GOOG,2020-09-22,1450.089966,1469.52002,1434.530029,1465.459961 815 | GOOG,2020-09-23,1458.780029,1460.959961,1407.699951,1415.209961 816 | GOOG,2020-09-24,1411.030029,1443.708984,1409.849976,1428.290039 817 | GOOG,2020-09-25,1432.630005,1450,1413.339966,1444.959961 818 | GOOG,2020-09-28,1474.209961,1476.800049,1449.301025,1464.52002 819 | GOOG,2020-09-29,1470.390015,1476.662964,1458.805054,1469.329956 820 | GOOG,2020-09-30,1466.800049,1489.75,1459.880005,1469.599976 821 | GOOG,2020-10-01,1484.27002,1499.040039,1479.209961,1490.089966 822 | GOOG,2020-10-02,1462.030029,1483.199951,1450.920044,1458.420044 823 | GOOG,2020-10-05,1466.209961,1488.209961,1464.27002,1486.02002 824 | GOOG,2020-10-06,1475.579956,1486.76001,1448.589966,1453.439941 825 | GOOG,2020-10-07,1464.290039,1468.959961,1436,1460.290039 826 | GOOG,2020-10-08,1465.089966,1490,1465.089966,1485.930054 827 | GOOG,2020-10-09,1494.699951,1516.52002,1489.449951,1515.219971 828 | GOOG,2020-10-12,1543,1593.859985,1532.569946,1569.150024 829 | GOOG,2020-10-13,1583.72998,1590,1563.199951,1571.680054 830 | GOOG,2020-10-14,1578.589966,1587.68396,1550.530029,1568.079956 831 | GOOG,2020-10-15,1547.150024,1575.10498,1545.030029,1559.130005 832 | GOOG,2020-10-16,1565.849976,1581.130005,1563,1573.01001 833 | GOOG,2020-10-19,1580.459961,1588.150024,1528,1534.609985 834 | GOOG,2020-10-20,1527.050049,1577.5,1525.670044,1555.930054 835 | GOOG,2020-10-21,1573.329956,1618.72998,1571.630005,1593.310059 836 | GOOG,2020-10-22,1593.050049,1621.98999,1585,1615.329956 837 | GOOG,2020-10-23,1626.069946,1642.359985,1620.51001,1641 838 | GOOG,2020-10-26,1625.01001,1638.23999,1576.5,1590.449951 839 | GOOG,2020-10-27,1595.670044,1606.844971,1582.780029,1604.26001 840 | GOOG,2020-10-28,1559.73999,1561.349976,1514.619995,1516.619995 841 | GOOG,2020-10-29,1522.359985,1593.709961,1522.23999,1567.23999 842 | GOOG,2020-10-30,1672.109985,1687,1604.459961,1621.01001 843 | GOOG,2020-11-02,1628.160034,1660.77002,1616.030029,1626.030029 844 | GOOG,2020-11-03,1631.780029,1661.699951,1616.619995,1650.209961 845 | GOOG,2020-11-04,1710.280029,1771.36499,1706.030029,1749.130005 846 | GOOG,2020-11-05,1781,1793.640015,1750.51001,1763.369995 847 | GOOG,2020-11-06,1753.949951,1772.430054,1740.349976,1761.75 848 | GOOG,2020-11-09,1790.900024,1818.060059,1760.02002,1763 849 | GOOG,2020-11-10,1731.089966,1763,1717.300049,1740.390015 850 | GOOG,2020-11-11,1750,1764.219971,1747.36499,1752.709961 851 | GOOG,2020-11-12,1747.630005,1768.27002,1745.599976,1749.839966 852 | GOOG,2020-11-13,1757.630005,1781.040039,1744.550049,1777.02002 853 | GOOG,2020-11-16,1771.699951,1799.069946,1767.689941,1781.380005 854 | GOOG,2020-11-17,1776.939941,1785,1767,1770.150024 855 | GOOG,2020-11-18,1765.22998,1773.469971,1746.140015,1746.780029 856 | GOOG,2020-11-19,1738.380005,1769.589966,1737.005005,1763.920044 857 | GOOG,2020-11-20,1765.209961,1774,1741.859985,1742.189941 858 | GOOG,2020-11-23,1749.599976,1753.900024,1717.719971,1734.859985 859 | GOOG,2020-11-24,1730.5,1771.599976,1727.689941,1768.880005 860 | GOOG,2020-11-25,1772.890015,1778.540039,1756.540039,1771.430054 861 | GOOG,2020-11-27,1773.089966,1804,1772.439941,1793.189941 862 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/monday_no_plugins_result.py: -------------------------------------------------------------------------------- 1 | # Databricks notebook source 2 | import pandas as pd; import numpy as np 3 | aapl = spark.table("ticker_aapl").limit(100000).toPandas() 4 | 5 | 6 | # COMMAND ---------- 7 | 8 | import pandas as pd; import numpy as np 9 | goog = spark.table("ticker_goog").limit(100000).toPandas() 10 | # Step: Concatenate dataframes vertically 11 | stocks = pd.concat([goog, aapl], axis=0, ignore_index=True) 12 | 13 | # Step: Sort column(s) date ascending (A-Z) 14 | stocks = stocks.sort_values(by=['date'], ascending=[True]) 15 | 16 | # Step: Drop rows where date < 2018-01-01 17 | stocks = stocks.loc[~(stocks['date'] < '2018-01-01')] 18 | 19 | # Step: Percentage change 20 | stocks['price_return'] = stocks.groupby(['label'])['close'].transform('pct_change') 21 | 22 | # Step: Create new column 'index_return' from formula 'price_return + 1' 23 | stocks['index_return'] = stocks['price_return'] + 1 24 | 25 | # Step: Replace missing values 26 | stocks[['index_return']] = stocks[['index_return']].fillna(1) 27 | 28 | # Step: Cumulative product 29 | stocks['index_return'] = stocks.groupby(['label'])['index_return'].cumprod() 30 | 31 | 32 | 33 | # COMMAND ---------- 34 | 35 | import plotly.express as px 36 | fig = px.line(stocks.sort_values(by=['date'], ascending=[True]), x='date', y='index_return', color='label') 37 | fig.update_layout(xaxis_rangeselector_buttons=list([ 38 | dict(label="1m", count=1, step="month", stepmode="backward"), 39 | dict(label="6m", count=6, step="month", stepmode="backward"), 40 | dict(label="YTD", count=1, step="year", stepmode="todate"), 41 | dict(label="1y", count=1, step="year", stepmode="backward"), 42 | dict(step="all") 43 | ])) 44 | fig.update_layout(xaxis_rangeslider_visible=True) 45 | fig 46 | 47 | # COMMAND ---------- 48 | 49 | 50 | -------------------------------------------------------------------------------- /plugins/examples/projects/blog_post_demo_bluerock_analytics/wednesday_with_plugins_result.py: -------------------------------------------------------------------------------- 1 | # Databricks notebook source 2 | import bamboolib as bam 3 | import br_analytics as br 4 | 5 | # COMMAND ---------- 6 | 7 | import pandas as pd; import numpy as np 8 | df = br.load_ticker(['goog_ticker_clean', 'aapl_ticker_clean']) 9 | # Step: Calculate index return 10 | df = br.add_index_return(df, 'close', ['label']) 11 | 12 | # COMMAND ---------- 13 | 14 | import plotly.express as px 15 | fig = px.line(df.sort_values(by=['date'], ascending=[True]), x='date', y='index_return', color='label') 16 | fig.update_layout(xaxis_rangeslider_visible=True) 17 | fig.update_layout(xaxis_rangeselector_buttons=list([ 18 | dict(label="1m", count=1, step="month", stepmode="backward"), 19 | dict(label="6m", count=6, step="month", stepmode="backward"), 20 | dict(label="YTD", count=1, step="year", stepmode="todate"), 21 | dict(label="1y", count=1, step="year", stepmode="backward"), 22 | dict(step="all") 23 | ])) 24 | fig 25 | -------------------------------------------------------------------------------- /plugins/examples/projects/sales_plugin_demo/README.md: -------------------------------------------------------------------------------- 1 | # Sales plugin demo 2 | 3 | This project gives an example of how to combine loader, transformation and visualization plugins. All the function and plugin code lies under `/abc_analytics`. For a tutorial notebook, check out `bam - plugin demo.ipynb` -------------------------------------------------------------------------------- /plugins/examples/projects/sales_plugin_demo/abc_analytics/__init__.py: -------------------------------------------------------------------------------- 1 | from abc_analytics.calculations import load_data_from_database_table, compute_revenue_share 2 | 3 | import abc_analytics.loader_plugins 4 | import abc_analytics.transformation_plugins 5 | import abc_analytics.figure_plugins 6 | -------------------------------------------------------------------------------- /plugins/examples/projects/sales_plugin_demo/abc_analytics/calculations.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | import bamboolib as bam 3 | 4 | 5 | def compute_revenue_share(df, groupby_columns): 6 | shares = df.groupby(groupby_columns).agg({"total_revenue": "sum"}).reset_index() 7 | shares["total_revenue_share"] = shares["total_revenue"] / shares["total_revenue"].sum() * 100 8 | shares = shares.drop(columns=["total_revenue"]) 9 | return shares 10 | 11 | 12 | def load_data_from_database_table(*args, **kwargs): 13 | df = bam.get_sales_df() 14 | return df -------------------------------------------------------------------------------- /plugins/examples/projects/sales_plugin_demo/abc_analytics/figure_plugins.py: -------------------------------------------------------------------------------- 1 | import bamboolib.views.plot_creator as pc 2 | 3 | 4 | class XAxisForRevenueShare(pc.XAxisWithMaybeSortColumn): 5 | default_value = "region" 6 | 7 | 8 | class YAxisForRevenueShare(pc.YAxisWithMultipleColumns): 9 | default_value = ["total_revenue_share"] 10 | 11 | 12 | class ColorForRevenueShare(pc.Color): 13 | default_value = "sales_channel" 14 | 15 | 16 | class FiureThemeForRevenueShare(pc.FigureTheme): 17 | default_value = "seaborn" 18 | 19 | 20 | class TitleForRevenueShare(pc.FigureTitle): 21 | value = "Revenue Share (%) by Region and Channel" 22 | 23 | 24 | class ABCRevenueShareBarPlot(pc.BarPlot): 25 | name = "ABC: plot revenue share" 26 | recommended_configs = [ 27 | XAxisForRevenueShare, 28 | YAxisForRevenueShare, 29 | ColorForRevenueShare, 30 | FiureThemeForRevenueShare, 31 | TitleForRevenueShare, 32 | ] 33 | # optional_configs = [] 34 | -------------------------------------------------------------------------------- /plugins/examples/projects/sales_plugin_demo/abc_analytics/loader_plugins.py: -------------------------------------------------------------------------------- 1 | # %% 2 | from bamboolib.plugins import LoaderPlugin, DF_NEW, Singleselect 3 | 4 | # %% 5 | import ipywidgets as widgets 6 | 7 | 8 | # %% 9 | class LoadDatabaseTable(LoaderPlugin): 10 | 11 | name = "ABC Corp: Load data from database" 12 | 13 | def __init__(self, **kwargs): 14 | super().__init__(**kwargs) 15 | 16 | tables_option = ["Sales Data", "Meta data", "Production data"] 17 | self.table_input = Singleselect(options=tables_option, value="", width="xl", placeholder="Choose table...") 18 | 19 | def render(self): 20 | self.set_title("Load data from database") 21 | self.set_content( 22 | widgets.HTML("Load data from table"), 23 | self.table_input, 24 | self.new_df_name_group, 25 | self.execute_button, 26 | ) 27 | 28 | def get_code(self): 29 | return f"""{DF_NEW} = abc.load_data_from_database_table("{self.table_input.value}")""" 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /plugins/examples/projects/sales_plugin_demo/abc_analytics/transformation_plugins.py: -------------------------------------------------------------------------------- 1 | from bamboolib.plugins import TransformationPlugin, DF_OLD, DF_NEW, Multiselect 2 | import ipywidgets as widgets 3 | 4 | 5 | class TotalRevenueShare(TransformationPlugin): 6 | 7 | name = "ABC Corp: Calculate Revenue Share" 8 | description = "This is an ABC corp internal function that computes the revenue share" 9 | 10 | def __init__(self, *args, **kwargs): 11 | super().__init__(*args, **kwargs) 12 | 13 | self.groupby_columns = Multiselect( 14 | options=list(self.get_df().columns), 15 | placeholder="Choose column", 16 | focus_after_init=True 17 | ) 18 | 19 | def render(self): 20 | self.set_title("Calculate Revenue Share") 21 | self.set_content( 22 | widgets.HTML("Compute the total revenue share for each value in"), 23 | self.groupby_columns, 24 | self.rename_df_group, 25 | ) 26 | 27 | def get_code(self): 28 | return f"{DF_NEW} = abc.compute_revenue_share({DF_OLD}, {self.groupby_columns.value})" 29 | -------------------------------------------------------------------------------- /plugins/examples/projects/sales_plugin_demo/bam - plugin demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Plugin demo with complete project" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "In this notebook, you can check out a loader, transformation and visualization plugin with one concrete project." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "### Run the cells below" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": { 28 | "scrolled": true 29 | }, 30 | "outputs": [], 31 | "source": [ 32 | "import bamboolib as bam\n", 33 | "import abc_analytics as abc" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "**When you run the cell below ...**\n", 41 | "- You will immediately see the **loader plugin** \"ABC Corp: Load data from database\"\n", 42 | "- You can find the **transformation plugin** in the transformation search bar by typing \"abc\"\n", 43 | "- You can find the **plot creator plugin** by going to the plot creator and searching \"abc\" in Figure type" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "bam" 53 | ] 54 | } 55 | ], 56 | "metadata": { 57 | "jupytext": { 58 | "cell_metadata_filter": "-all", 59 | "notebook_metadata_filter": "-all" 60 | }, 61 | "kernelspec": { 62 | "display_name": "bamboolib_dev", 63 | "language": "python", 64 | "name": "bamboolib_dev" 65 | }, 66 | "language_info": { 67 | "codemirror_mode": { 68 | "name": "ipython", 69 | "version": 3 70 | }, 71 | "file_extension": ".py", 72 | "mimetype": "text/x-python", 73 | "name": "python", 74 | "nbconvert_exporter": "python", 75 | "pygments_lexer": "ipython3", 76 | "version": "3.8.8" 77 | } 78 | }, 79 | "nbformat": 4, 80 | "nbformat_minor": 4 81 | } 82 | -------------------------------------------------------------------------------- /plugins/examples/projects/sales_plugin_demo/bam - plugin demo.py: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # # Plugin demo with complete project 3 | 4 | # %% [markdown] 5 | # In this notebook, you can check out a loader, transformation and visualization plugin with one concrete project. 6 | 7 | # %% [markdown] 8 | # ### Run the cells below 9 | 10 | # %% 11 | import bamboolib as bam 12 | import abc_analytics as abc 13 | 14 | # %% [markdown] 15 | # **When you run the cell below ...** 16 | # - You will immediately see the **loader plugin** "ABC Corp: Load data from database" 17 | # - You can find the **transformation plugin** in the transformation search bar by typing "abc" 18 | # - You can find the **plot creator plugin** by going to the plot creator and searching "abc" in Figure type 19 | 20 | # %% 21 | bam 22 | -------------------------------------------------------------------------------- /plugins/examples/transformations/calculate_diff_within_groups.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Calculating the diff within groups via a TransformationPlugin\n", 8 | "\n", 9 | "inspired by Sailu and the following stackoverflow post:\n", 10 | "- https://stackoverflow.com/questions/20648346/computing-diffs-within-groups-of-a-dataframe\n", 11 | "\n", 12 | "\n", 13 | "__Goal:__ For each company, calculate the revenue diff to the previous month/row" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": null, 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "import pandas as pd\n", 23 | "import numpy as np" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "df = pd.DataFrame()" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "df[\"company\"] = [\"A\", \"A\", \"A\", \"A\", \"B\", \"B\", \"B\", \"B\", \"C\", \"C\", \"C\", \"C\"]" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "df[\"month\"] = [\n", 51 | " \"Jan-19\",\n", 52 | " \"Feb-19\",\n", 53 | " \"Mar-19\",\n", 54 | " \"Apr-19\",\n", 55 | " \"Jan-19\",\n", 56 | " \"Feb-19\",\n", 57 | " \"Mar-19\",\n", 58 | " \"Apr-19\",\n", 59 | " \"Jan-19\",\n", 60 | " \"Feb-19\",\n", 61 | " \"Mar-19\",\n", 62 | " \"Apr-19\",\n", 63 | "]" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "metadata": {}, 70 | "outputs": [], 71 | "source": [ 72 | "df[\"revenue\"] = [100, 200, 120, 220, 80, 75, 97, 123, 340, 98, 23, 124]" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [ 81 | "# # solution:\n", 82 | "# df['diff'] = df.groupby(['company'])['revenue'].transform(lambda series: series.diff())" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "import ipywidgets as widgets\n", 92 | "\n", 93 | "from bamboolib.plugins import TransformationPlugin, DF_OLD, Multiselect, Singleselect, Text\n", 94 | "\n", 95 | "\n", 96 | "class DiffWithinGroups(TransformationPlugin):\n", 97 | "\n", 98 | " name = \"Diff within groups\"\n", 99 | " description = \"E.g. for each company, calculate the revenue diff to the previous month/row\"\n", 100 | "\n", 101 | " def __init__(self, *args, **kwargs):\n", 102 | " super().__init__(*args, **kwargs)\n", 103 | "\n", 104 | " columns = list(self.get_df().columns)\n", 105 | "\n", 106 | " self.groupby_columns = Multiselect(\n", 107 | " options=columns,\n", 108 | " placeholder=\"Choose groupby column(s)\",\n", 109 | " focus_after_init=True,\n", 110 | " )\n", 111 | "\n", 112 | " self.value_column = Singleselect(options=columns, placeholder=\"Choose value column\")\n", 113 | "\n", 114 | " self.new_column_name = Text(\n", 115 | " value=\"diff\", placeholder=\"Name of diff column\"\n", 116 | " )\n", 117 | "\n", 118 | " def render(self):\n", 119 | " self.set_title(\"Diff within groups\")\n", 120 | " self.set_content(\n", 121 | " widgets.HTML(\"Groupby\"),\n", 122 | " self.groupby_columns,\n", 123 | " widgets.HTML(\"and calculate diff of\"),\n", 124 | " self.value_column,\n", 125 | " widgets.HTML(\"Name of new column\"),\n", 126 | " self.new_column_name,\n", 127 | " )\n", 128 | "\n", 129 | " def get_code(self):\n", 130 | " return f\"{DF_OLD}['{self.new_column_name.value}'] = {DF_OLD}.groupby({self.groupby_columns.value})['{self.value_column.value}'].transform(lambda series: series.diff())\"" 131 | ] 132 | }, 133 | { 134 | "cell_type": "code", 135 | "execution_count": null, 136 | "metadata": {}, 137 | "outputs": [], 138 | "source": [ 139 | "df" 140 | ] 141 | }, 142 | { 143 | "cell_type": "code", 144 | "execution_count": null, 145 | "metadata": {}, 146 | "outputs": [], 147 | "source": [] 148 | } 149 | ], 150 | "metadata": { 151 | "jupytext": { 152 | "cell_metadata_filter": "-all", 153 | "notebook_metadata_filter": "-all" 154 | }, 155 | "kernelspec": { 156 | "display_name": "Python 3", 157 | "language": "python", 158 | "name": "python3" 159 | }, 160 | "language_info": { 161 | "codemirror_mode": { 162 | "name": "ipython", 163 | "version": 3 164 | }, 165 | "file_extension": ".py", 166 | "mimetype": "text/x-python", 167 | "name": "python", 168 | "nbconvert_exporter": "python", 169 | "pygments_lexer": "ipython3", 170 | "version": "3.7.3" 171 | } 172 | }, 173 | "nbformat": 4, 174 | "nbformat_minor": 4 175 | } 176 | -------------------------------------------------------------------------------- /plugins/examples/transformations/calculate_diff_within_groups.py: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # # Calculating the diff within groups via a TransformationPlugin 3 | # 4 | # inspired by Sailu and the following stackoverflow post: 5 | # - https://stackoverflow.com/questions/20648346/computing-diffs-within-groups-of-a-dataframe 6 | # 7 | # 8 | # __Goal:__ For each company, calculate the revenue diff to the previous month/row 9 | 10 | # %% 11 | import pandas as pd 12 | import numpy as np 13 | 14 | # %% 15 | df = pd.DataFrame() 16 | 17 | # %% 18 | df["company"] = ["A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C"] 19 | 20 | # %% 21 | df["month"] = [ 22 | "Jan-19", 23 | "Feb-19", 24 | "Mar-19", 25 | "Apr-19", 26 | "Jan-19", 27 | "Feb-19", 28 | "Mar-19", 29 | "Apr-19", 30 | "Jan-19", 31 | "Feb-19", 32 | "Mar-19", 33 | "Apr-19", 34 | ] 35 | 36 | # %% 37 | df["revenue"] = [100, 200, 120, 220, 80, 75, 97, 123, 340, 98, 23, 124] 38 | 39 | # %% 40 | # # solution: 41 | # df['diff'] = df.groupby(['company'])['revenue'].transform(lambda series: series.diff()) 42 | 43 | # %% 44 | import ipywidgets as widgets 45 | 46 | from bamboolib.plugins import TransformationPlugin, DF_OLD, Multiselect, Singleselect, Text 47 | 48 | 49 | class DiffWithinGroups(TransformationPlugin): 50 | 51 | name = "Diff within groups" 52 | description = "E.g. for each company, calculate the revenue diff to the previous month/row" 53 | 54 | def __init__(self, *args, **kwargs): 55 | super().__init__(*args, **kwargs) 56 | 57 | columns = list(self.get_df().columns) 58 | 59 | self.groupby_columns = Multiselect( 60 | options=columns, 61 | placeholder="Choose groupby column(s)", 62 | focus_after_init=True, 63 | ) 64 | 65 | self.value_column = Singleselect(options=columns, placeholder="Choose value column") 66 | 67 | self.new_column_name = Text( 68 | value="diff", placeholder="Name of diff column" 69 | ) 70 | 71 | def render(self): 72 | self.set_title("Diff within groups") 73 | self.set_content( 74 | widgets.HTML("Groupby"), 75 | self.groupby_columns, 76 | widgets.HTML("and calculate diff of"), 77 | self.value_column, 78 | widgets.HTML("Name of new column"), 79 | self.new_column_name, 80 | ) 81 | 82 | def get_code(self): 83 | return f"{DF_OLD}['{self.new_column_name.value}'] = {DF_OLD}.groupby({self.groupby_columns.value})['{self.value_column.value}'].transform(lambda series: series.diff())" 84 | 85 | 86 | # %% 87 | df 88 | 89 | # %% 90 | -------------------------------------------------------------------------------- /plugins/examples/transformations/calculate_revenue_shares_by_group.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Calculating the revenue share of regions via a TransformationPlugin\n", 8 | "\n", 9 | "__Goal:__ For each **region**, we want to compute the revenue share (i.e. the percentage of our global revenue coming from that region)" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": null, 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import pandas as pd\n", 19 | "import bamboolib as bam" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "sales_df = bam.get_sales_df()" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "# Custom function used in Plugin\n", 38 | "def compute_share(df, groupby_column, value_column):\n", 39 | " shares = df.groupby(groupby_column).agg({value_column: \"sum\"}).reset_index()\n", 40 | " shares[value_column + \"_share\"] = shares[value_column] / shares[value_column].sum() * 100\n", 41 | " shares = shares.drop(columns=[value_column])\n", 42 | " return shares" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "# Solution:\n", 52 | "# revenue_shares_df = compute_share(sales_df, 'region', 'total_revenue')" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "import ipywidgets as widgets\n", 62 | "\n", 63 | "from bamboolib.plugins import TransformationPlugin, DF_OLD, DF_NEW, Singleselect\n", 64 | "\n", 65 | "\n", 66 | "class TotalRevenueShare(TransformationPlugin):\n", 67 | "\n", 68 | " name = \"Compute total revenue share\"\n", 69 | " description = \"This is a custom plugin that computes the total revenue share\"\n", 70 | "\n", 71 | " def __init__(self, *args, **kwargs):\n", 72 | " super().__init__(*args, **kwargs)\n", 73 | "\n", 74 | " self.groupby_columns = Singleselect(\n", 75 | " options=list(self.get_df().columns), \n", 76 | " placeholder=\"Choose column\",\n", 77 | " focus_after_init=True\n", 78 | " )\n", 79 | "\n", 80 | " def render(self):\n", 81 | " self.set_title(\"Total revenue share\")\n", 82 | " self.set_content(\n", 83 | " widgets.HTML(\"Compute the total revenue share for each value in\"),\n", 84 | " self.groupby_columns,\n", 85 | " self.rename_df_group,\n", 86 | " )\n", 87 | "\n", 88 | " def get_code(self):\n", 89 | " return f\"{DF_NEW} = compute_share({DF_OLD}, '{self.groupby_columns.value}', 'total_revenue')\"" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": {}, 95 | "source": [ 96 | "**Hint:** You can find the plugin by searching \"total revenue\"" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "metadata": {}, 103 | "outputs": [], 104 | "source": [ 105 | "sales_df" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "**Inspiration:** Can you extend the plugin so that the user can choose which column she wants to compute the shares from?" 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "execution_count": null, 118 | "metadata": {}, 119 | "outputs": [], 120 | "source": [] 121 | } 122 | ], 123 | "metadata": { 124 | "jupytext": { 125 | "cell_metadata_filter": "-all", 126 | "notebook_metadata_filter": "-all" 127 | }, 128 | "kernelspec": { 129 | "display_name": "Python 3", 130 | "language": "python", 131 | "name": "python3" 132 | }, 133 | "language_info": { 134 | "codemirror_mode": { 135 | "name": "ipython", 136 | "version": 3 137 | }, 138 | "file_extension": ".py", 139 | "mimetype": "text/x-python", 140 | "name": "python", 141 | "nbconvert_exporter": "python", 142 | "pygments_lexer": "ipython3", 143 | "version": "3.7.3" 144 | } 145 | }, 146 | "nbformat": 4, 147 | "nbformat_minor": 4 148 | } -------------------------------------------------------------------------------- /plugins/examples/transformations/calculate_revenue_shares_by_group.py: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # # Calculating the revenue share of regions via a TransformationPlugin 3 | # 4 | # __Goal:__ For each **region**, we want to compute the revenue share (i.e. the percentage of our global revenue coming from that region) 5 | 6 | # %% 7 | import pandas as pd 8 | import bamboolib as bam 9 | 10 | # %% 11 | sales_df = bam.get_sales_df() 12 | 13 | 14 | # %% 15 | # Custom function used in Plugin 16 | def compute_share(df, groupby_column, value_column): 17 | shares = df.groupby(groupby_column).agg({value_column: "sum"}).reset_index() 18 | shares[value_column + "_share"] = shares[value_column] / shares[value_column].sum() * 100 19 | shares = shares.drop(columns=[value_column]) 20 | return shares 21 | 22 | 23 | # %% 24 | # Solution: 25 | # revenue_shares_df = compute_share(sales_df, 'region', 'total_revenue') 26 | 27 | # %% 28 | import ipywidgets as widgets 29 | 30 | from bamboolib.plugins import TransformationPlugin, DF_OLD, DF_NEW, Singleselect 31 | 32 | 33 | class TotalRevenueShare(TransformationPlugin): 34 | 35 | name = "Compute total revenue share" 36 | description = "This is a custom plugin that computes the total revenue share" 37 | 38 | def __init__(self, *args, **kwargs): 39 | super().__init__(*args, **kwargs) 40 | 41 | self.groupby_column = Singleselect( 42 | options=list(self.get_df().columns), 43 | placeholder="Choose column", 44 | focus_after_init=True 45 | ) 46 | 47 | def render(self): 48 | self.set_title("Total revenue share") 49 | self.set_content( 50 | widgets.HTML("Compute the total revenue share for each value in"), 51 | self.groupby_column, 52 | self.rename_df_group, 53 | ) 54 | 55 | def get_code(self): 56 | return f"{DF_NEW} = compute_share({DF_OLD}, '{self.groupby_column.value}', 'total_revenue')" 57 | 58 | 59 | # %% [markdown] 60 | # **Hint:** You can find the plugin by searching "total revenue" 61 | 62 | # %% 63 | sales_df 64 | 65 | # %% [markdown] 66 | # **Inspiration:** Can you extend the plugin so that the user can choose which column she wants to compute the shares from? 67 | 68 | # %% 69 | -------------------------------------------------------------------------------- /plugins/examples/transformations/drop_columns_with_missing_values.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Drop columns that only contain missing values" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import pandas as pd\n", 17 | "import bamboolib as bam\n", 18 | "\n", 19 | "titanic_df = bam.get_titanic_df()\n", 20 | "titanic_df[\"na_column\"] = pd.NA" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "# Solution:\n", 30 | "# titanic_df_cleaned = titanic_df.dropna(how=\"all\", axis=1)" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": { 37 | "lines_to_next_cell": 1 38 | }, 39 | "outputs": [], 40 | "source": [ 41 | "from bamboolib.plugins import TransformationPlugin, DF_OLD, DF_NEW, Singleselect\n", 42 | "import ipywidgets as widgets\n", 43 | "\n", 44 | "\n", 45 | "DROP_NA_COLUMNS_OPTIONS = (\n", 46 | " (\"only missing values\", \"all\"),\n", 47 | " (\"at least 1 missing value\", \"any\")\n", 48 | ")\n", 49 | "\n", 50 | "\n", 51 | "class DropColumnsWithMissingValues(TransformationPlugin):\n", 52 | "\n", 53 | " name = \"Drop columns with missing values\"\n", 54 | " description = \"Drop columns that contain at least one missing value or only missing values\"\n", 55 | "\n", 56 | " def __init__(self, *args, **kwargs):\n", 57 | " super().__init__(*args, **kwargs)\n", 58 | "\n", 59 | " self.drop_na_option = Singleselect(\n", 60 | " options=DROP_NA_COLUMNS_OPTIONS,\n", 61 | " placeholder=\"Choose ...\",\n", 62 | " focus_after_init=True,\n", 63 | " set_soft_value=True\n", 64 | " )\n", 65 | "\n", 66 | " def render(self):\n", 67 | " self.set_title(\"Drop columns with missing values\")\n", 68 | " self.set_content(\n", 69 | " widgets.HTML(\"Drop all columns that contain\"),\n", 70 | " self.drop_na_option,\n", 71 | " self.rename_df_group,\n", 72 | " )\n", 73 | "\n", 74 | " def get_code(self):\n", 75 | " return f\"{DF_NEW} = {DF_OLD}.dropna(how='{self.drop_na_option.value}', axis=1)\"" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "**Hint:** You can find the plugin by searching \"drop columns\". " 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "titanic_df" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": null, 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [] 100 | } 101 | ], 102 | "metadata": { 103 | "jupytext": { 104 | "cell_metadata_filter": "-all", 105 | "notebook_metadata_filter": "-all", 106 | "text_representation": { 107 | "extension": ".py", 108 | "format_name": "percent" 109 | } 110 | }, 111 | "kernelspec": { 112 | "display_name": "Python 3", 113 | "language": "python", 114 | "name": "python3" 115 | }, 116 | "language_info": { 117 | "codemirror_mode": { 118 | "name": "ipython", 119 | "version": 3 120 | }, 121 | "file_extension": ".py", 122 | "mimetype": "text/x-python", 123 | "name": "python", 124 | "nbconvert_exporter": "python", 125 | "pygments_lexer": "ipython3", 126 | "version": "3.7.3" 127 | } 128 | }, 129 | "nbformat": 4, 130 | "nbformat_minor": 4 131 | } 132 | -------------------------------------------------------------------------------- /plugins/examples/transformations/drop_columns_with_missing_values.py: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # # Drop columns that only contain missing values 3 | 4 | # %% 5 | import pandas as pd 6 | import bamboolib as bam 7 | 8 | titanic_df = bam.get_titanic_df() 9 | titanic_df["na_column"] = pd.NA 10 | 11 | # %% 12 | # Solution: 13 | # titanic_df_cleaned = titanic_df.dropna(how="all", axis=1) 14 | 15 | # %% 16 | from bamboolib.plugins import TransformationPlugin, DF_OLD, DF_NEW, Singleselect 17 | import ipywidgets as widgets 18 | 19 | 20 | DROP_NA_COLUMNS_OPTIONS = ( 21 | ("only missing values", "all"), 22 | ("at least 1 missing value", "any") 23 | ) 24 | 25 | 26 | class DropColumnsWithMissingValues(TransformationPlugin): 27 | 28 | name = "Drop columns with missing values" 29 | description = "Drop columns that contain at least one missing value or only missing values" 30 | 31 | def __init__(self, *args, **kwargs): 32 | super().__init__(*args, **kwargs) 33 | 34 | self.drop_na_option = Singleselect( 35 | options=DROP_NA_COLUMNS_OPTIONS, 36 | placeholder="Choose ...", 37 | focus_after_init=True, 38 | set_soft_value=True 39 | ) 40 | 41 | def render(self): 42 | self.set_title("Drop columns with missing values") 43 | self.set_content( 44 | widgets.HTML("Drop all columns that contain"), 45 | self.drop_na_option, 46 | self.rename_df_group, 47 | ) 48 | 49 | def get_code(self): 50 | return f"{DF_NEW} = {DF_OLD}.dropna(how='{self.drop_na_option.value}', axis=1)" 51 | 52 | # %% [markdown] 53 | # **Hint:** You can find the plugin by searching "drop columns". 54 | 55 | # %% 56 | titanic_df 57 | 58 | # %% 59 | -------------------------------------------------------------------------------- /plugins/examples/transformations/groupby_custom_function.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Using custom groupby functions via a TransformationPlugin\n", 8 | "\n", 9 | "inspired by Harneet, Will and Zach\n", 10 | "\n", 11 | "__Goal:__ Groupby a column and execute either a lambda function or a custom function" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "import pandas as pd\n", 21 | "import bamboolib as bam" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "df = pd.DataFrame()" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "df[\"group\"] = [\"A\", \"A\", \"A\", \"B\", \"B\", \"B\"]" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "metadata": {}, 46 | "outputs": [], 47 | "source": [ 48 | "df[\"item\"] = [\"x\", \"y\", \"z\", \"x\", \"y\", \"z\"]" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "df[\"number\"] = [1, 2, 3, 4, 5, 6]" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "def my_custom_function(series):\n", 67 | " return min(series)" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "# # Solution 1:\n", 77 | "# df.groupby('group').agg(lambda x: min(x))" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "# # Solution 2:\n", 87 | "# df.groupby('group').agg(my_custom_function)" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "import ipywidgets as widgets\n", 97 | "\n", 98 | "from bamboolib.plugins import TransformationPlugin, DF_OLD, DF_NEW, Multiselect, Text\n", 99 | "\n", 100 | "\n", 101 | "class GroupbyCustomFunction(TransformationPlugin):\n", 102 | "\n", 103 | " name = \"Groupby with custom function\"\n", 104 | " description = \"Apply a custom function to each group in one or multiple columns\"\n", 105 | "\n", 106 | " def __init__(self, *args, **kwargs):\n", 107 | " super().__init__(*args, **kwargs)\n", 108 | "\n", 109 | " columns = list(self.get_df().columns)\n", 110 | "\n", 111 | " self.groupby_columns = Multiselect(\n", 112 | " options=columns, placeholder=\"Choose column(s)\"\n", 113 | " )\n", 114 | "\n", 115 | " self.custom_function_text = Text(\n", 116 | " value=\"lambda x: min(x)\", placeholder=\"lambda expression or function name\"\n", 117 | " )\n", 118 | "\n", 119 | " def render(self):\n", 120 | " self.set_title(\"Groupy with custom function\")\n", 121 | " self.set_content(\n", 122 | " widgets.HTML(\"Groupby\"),\n", 123 | " self.groupby_columns,\n", 124 | " widgets.HTML(\"and apply aggregation\"),\n", 125 | " self.custom_function_text,\n", 126 | " self.rename_df_group,\n", 127 | " self.code_preview_group,\n", 128 | " )\n", 129 | "\n", 130 | " def get_code(self):\n", 131 | " return f\"{DF_NEW} = {DF_OLD}.groupby({self.groupby_columns.value}).agg({self.custom_function_text.value})\"" 132 | ] 133 | }, 134 | { 135 | "cell_type": "code", 136 | "execution_count": null, 137 | "metadata": {}, 138 | "outputs": [], 139 | "source": [ 140 | "df" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": null, 146 | "metadata": {}, 147 | "outputs": [], 148 | "source": [] 149 | } 150 | ], 151 | "metadata": { 152 | "jupytext": { 153 | "cell_metadata_filter": "-all", 154 | "notebook_metadata_filter": "-all" 155 | }, 156 | "kernelspec": { 157 | "display_name": "Python 3", 158 | "language": "python", 159 | "name": "python3" 160 | }, 161 | "language_info": { 162 | "codemirror_mode": { 163 | "name": "ipython", 164 | "version": 3 165 | }, 166 | "file_extension": ".py", 167 | "mimetype": "text/x-python", 168 | "name": "python", 169 | "nbconvert_exporter": "python", 170 | "pygments_lexer": "ipython3", 171 | "version": "3.7.3" 172 | } 173 | }, 174 | "nbformat": 4, 175 | "nbformat_minor": 4 176 | } 177 | -------------------------------------------------------------------------------- /plugins/examples/transformations/groupby_custom_function.py: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # # Using custom groupby functions via a TransformationPlugin 3 | # 4 | # inspired by Harneet, Will and Zach 5 | # 6 | # __Goal:__ Groupby a column and execute either a lambda function or a custom function 7 | 8 | # %% 9 | import pandas as pd 10 | import bamboolib as bam 11 | 12 | # %% 13 | df = pd.DataFrame() 14 | 15 | # %% 16 | df["group"] = ["A", "A", "A", "B", "B", "B"] 17 | 18 | # %% 19 | df["item"] = ["x", "y", "z", "x", "y", "z"] 20 | 21 | # %% 22 | df["number"] = [1, 2, 3, 4, 5, 6] 23 | 24 | 25 | # %% 26 | def my_custom_function(series): 27 | return min(series) 28 | 29 | 30 | # %% 31 | # # Solution 1: 32 | # df.groupby('group').agg(lambda x: min(x)) 33 | 34 | # %% 35 | # # Solution 2: 36 | # df.groupby('group').agg(my_custom_function) 37 | 38 | # %% 39 | import ipywidgets as widgets 40 | 41 | from bamboolib.plugins import TransformationPlugin, DF_OLD, DF_NEW, Multiselect, Text 42 | 43 | 44 | class GroupbyCustomFunction(TransformationPlugin): 45 | 46 | name = "Groupby with custom function" 47 | description = "Apply a custom function to each group in one or multiple columns" 48 | 49 | def __init__(self, *args, **kwargs): 50 | super().__init__(*args, **kwargs) 51 | 52 | columns = list(self.get_df().columns) 53 | 54 | self.groupby_columns = Multiselect( 55 | options=columns, placeholder="Choose column(s)" 56 | ) 57 | 58 | self.custom_function_text = Text( 59 | value="lambda x: min(x)", placeholder="lambda expression or function name" 60 | ) 61 | 62 | def render(self): 63 | self.set_title("Groupy with custom function") 64 | self.set_content( 65 | widgets.HTML("Groupby"), 66 | self.groupby_columns, 67 | widgets.HTML("and apply aggregation"), 68 | self.custom_function_text, 69 | self.rename_df_group, 70 | self.code_preview_group, 71 | ) 72 | 73 | def get_code(self): 74 | return f"{DF_NEW} = {DF_OLD}.groupby({self.groupby_columns.value}).agg({self.custom_function_text.value})" 75 | 76 | 77 | # %% 78 | df 79 | 80 | # %% 81 | -------------------------------------------------------------------------------- /plugins/examples/transformations/timedelta_extract_attributes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Extracting attributes from timedelta columns via a TransformationPlugin\n", 8 | "\n", 9 | "inspired by Sailu and the following stackoverflow question:\n", 10 | "- https://stackoverflow.com/questions/38355816/pandas-add-timedelta-column-to-datetime-column-vectorized\n", 11 | "\n", 12 | "__Goal:__ extract the number of weeks as float based on the timedelta column" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "import pandas as pd\n", 22 | "import numpy as np\n", 23 | "import bamboolib as bam" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "df = pd.DataFrame()" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "df[\"date\"] = [\"2016-01-10\", \"2016-05-11\", \"2016-02-23\", \"2015-12-08\"]\n", 42 | "df[\"date\"] = pd.to_datetime(df[\"date\"])" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "df[\"days\"] = [28, 7, 15, 30]\n", 52 | "df[\"days\"] = pd.to_timedelta(df[\"days\"], \"d\")" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "# # solution:\n", 62 | "# df['weeks'] = df['days'] / np.timedelta64(1, 'W')" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": null, 68 | "metadata": {}, 69 | "outputs": [], 70 | "source": [ 71 | "import ipywidgets as widgets\n", 72 | "\n", 73 | "from bamboolib.plugins import TransformationPlugin, DF_OLD, Singleselect, Text\n", 74 | "\n", 75 | "\n", 76 | "class TimedeltaExtractAttribute(TransformationPlugin):\n", 77 | "\n", 78 | " name = \"Timedelta: extract attribute\"\n", 79 | "\n", 80 | " def __init__(self, *args, **kwargs):\n", 81 | " super().__init__(*args, **kwargs)\n", 82 | "\n", 83 | " self.column = Singleselect(\n", 84 | " options=list(self.get_df().columns), focus_after_init=True\n", 85 | " )\n", 86 | "\n", 87 | " # based on https://docs.scipy.org/doc/numpy/reference/arrays.datetime.html#datetime-units\n", 88 | " self.attribute = Singleselect(\n", 89 | " options=[\n", 90 | " (\"years\", \"Y\"),\n", 91 | " (\"months\", \"M\"),\n", 92 | " (\"weeks\", \"W\"),\n", 93 | " (\"days\", \"D\"),\n", 94 | " (\"hours\", \"h\"),\n", 95 | " (\"minutes\", \"m\"),\n", 96 | " (\"seconds\", \"s\"),\n", 97 | " ],\n", 98 | " value=\"D\",\n", 99 | " )\n", 100 | " self.new_column_name = Text(\n", 101 | " description=\"New column name\", width=\"lg\", execute=self\n", 102 | " )\n", 103 | "\n", 104 | " def render(self):\n", 105 | " self.set_title(\"Extract attribute\")\n", 106 | " self.set_content(\n", 107 | " widgets.HTML(\"Convert\"),\n", 108 | " self.column,\n", 109 | " widgets.HTML(\"to\"),\n", 110 | " self.attribute,\n", 111 | " self.new_column_name,\n", 112 | " )\n", 113 | "\n", 114 | " def get_description(self):\n", 115 | " return f\"Extract timedelta attribute {self.attribute.label} from '{self.column.value}'\"\n", 116 | "\n", 117 | " def get_code(self):\n", 118 | " return f\"{DF_OLD}['{self.new_column_name.value}'] = {DF_OLD}['{self.column.value}'] / np.timedelta64(1, '{self.attribute.value}')\"" 119 | ] 120 | }, 121 | { 122 | "cell_type": "markdown", 123 | "metadata": {}, 124 | "source": [ 125 | "__Hint:__ The plugin is shown in bamboolib when searching for \"Timedelta: extract attribute\"" 126 | ] 127 | }, 128 | { 129 | "cell_type": "code", 130 | "execution_count": null, 131 | "metadata": {}, 132 | "outputs": [], 133 | "source": [ 134 | "df" 135 | ] 136 | }, 137 | { 138 | "cell_type": "code", 139 | "execution_count": null, 140 | "metadata": {}, 141 | "outputs": [], 142 | "source": [] 143 | } 144 | ], 145 | "metadata": { 146 | "jupytext": { 147 | "cell_metadata_filter": "-all", 148 | "notebook_metadata_filter": "-all" 149 | }, 150 | "kernelspec": { 151 | "display_name": "Python 3", 152 | "language": "python", 153 | "name": "python3" 154 | }, 155 | "language_info": { 156 | "codemirror_mode": { 157 | "name": "ipython", 158 | "version": 3 159 | }, 160 | "file_extension": ".py", 161 | "mimetype": "text/x-python", 162 | "name": "python", 163 | "nbconvert_exporter": "python", 164 | "pygments_lexer": "ipython3", 165 | "version": "3.7.3" 166 | } 167 | }, 168 | "nbformat": 4, 169 | "nbformat_minor": 4 170 | } 171 | -------------------------------------------------------------------------------- /plugins/examples/transformations/timedelta_extract_attributes.py: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # # Extracting attributes from timedelta columns via a TransformationPlugin 3 | # 4 | # inspired by Sailu and the following stackoverflow question: 5 | # - https://stackoverflow.com/questions/38355816/pandas-add-timedelta-column-to-datetime-column-vectorized 6 | # 7 | # __Goal:__ extract the number of weeks as float based on the timedelta column 8 | 9 | # %% 10 | import pandas as pd 11 | import numpy as np 12 | import bamboolib as bam 13 | 14 | # %% 15 | df = pd.DataFrame() 16 | 17 | # %% 18 | df["date"] = ["2016-01-10", "2016-05-11", "2016-02-23", "2015-12-08"] 19 | df["date"] = pd.to_datetime(df["date"]) 20 | 21 | # %% 22 | df["days"] = [28, 7, 15, 30] 23 | df["days"] = pd.to_timedelta(df["days"], "d") 24 | 25 | # %% 26 | # # solution: 27 | # df['weeks'] = df['days'] / np.timedelta64(1, 'W') 28 | 29 | # %% 30 | import ipywidgets as widgets 31 | 32 | from bamboolib.plugins import TransformationPlugin, DF_OLD, Singleselect, Text 33 | 34 | 35 | class TimedeltaExtractAttribute(TransformationPlugin): 36 | 37 | name = "Timedelta: extract attribute" 38 | 39 | def __init__(self, *args, **kwargs): 40 | super().__init__(*args, **kwargs) 41 | 42 | self.column = Singleselect( 43 | options=list(self.get_df().columns), focus_after_init=True 44 | ) 45 | 46 | # based on https://docs.scipy.org/doc/numpy/reference/arrays.datetime.html#datetime-units 47 | self.attribute = Singleselect( 48 | options=[ 49 | ("years", "Y"), 50 | ("months", "M"), 51 | ("weeks", "W"), 52 | ("days", "D"), 53 | ("hours", "h"), 54 | ("minutes", "m"), 55 | ("seconds", "s"), 56 | ], 57 | value="D", 58 | ) 59 | self.new_column_name = Text( 60 | description="New column name", width="lg", execute=self 61 | ) 62 | 63 | def render(self): 64 | self.set_title("Extract attribute") 65 | self.set_content( 66 | widgets.HTML("Convert"), 67 | self.column, 68 | widgets.HTML("to"), 69 | self.attribute, 70 | self.new_column_name, 71 | ) 72 | 73 | def get_description(self): 74 | return f"Extract timedelta attribute {self.attribute.label} from '{self.column.value}'" 75 | 76 | def get_code(self): 77 | return f"{DF_OLD}['{self.new_column_name.value}'] = {DF_OLD}['{self.column.value}'] / np.timedelta64(1, '{self.attribute.value}')" 78 | 79 | 80 | # %% [markdown] 81 | # __Hint:__ The plugin is shown in bamboolib when searching for "Timedelta: extract attribute" 82 | 83 | # %% 84 | df 85 | 86 | # %% 87 | -------------------------------------------------------------------------------- /plugins/examples/views/display_mean_of_column.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Viewplugin demo - computing and displaying the mean of a column\n", 8 | "This little demo shows the basics of how to write a Viewplugin. \n", 9 | "\n", 10 | "**Goal of the plugin** \n", 11 | "For a user specified column, display its mean. If the mean cannot be computed (e.g. because it's a string column), show the user a message.\n", 12 | "\n", 13 | "**Need help?** \n", 14 | "If you have any questions or need help, please reach out." 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "**Your turn** \n", 22 | "Run the code below. After that, you can call the plugin in two ways:\n", 23 | "1. **For the end user:** open bamboolib by calling `df_titanic` and search for the plugin by its name (or description)\n", 24 | "2. **During development:** call the plugin directly with `ComputeMeanOfColumn(df=df_titanic)`" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": null, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "import bamboolib as bam\n", 34 | "import pandas as pd\n", 35 | "\n", 36 | "# For this demo, we work with the titanic data set that comes pre-installed with bamboolib\n", 37 | "df_titanic = pd.read_csv(bam.titanic_csv)\n", 38 | "\n", 39 | "import ipywidgets as widgets # We use that to display e.g. HTML\n", 40 | "\n", 41 | "from bamboolib.plugins import ViewPlugin, Singleselect, Button\n", 42 | "\n", 43 | "\n", 44 | "class ComputeMeanOfColumn(ViewPlugin):\n", 45 | "\n", 46 | " # You will find the plugin via it's name and/or description.\n", 47 | " name = \"Compute mean of a column\"\n", 48 | " description = \"Compute the mean of a selected column\"\n", 49 | "\n", 50 | " def render(self):\n", 51 | " column_names = list(self.get_df().columns)\n", 52 | "\n", 53 | " self.column_input = Singleselect(\n", 54 | " options=column_names,\n", 55 | " placeholder=\"Choose column\",\n", 56 | " focus_after_init=True,\n", 57 | " )\n", 58 | " \n", 59 | " self.execute_button = Button(\n", 60 | " description=\"Compute mean\", \n", 61 | " style=\"primary\", # Make the button green.\n", 62 | " # Whenever user clicks on self.execute_button, we call update_output.\n", 63 | " # For more info, type `help(Button)`\n", 64 | " on_click=self.update_output \n", 65 | " )\n", 66 | " \n", 67 | " self.output = widgets.VBox([])\n", 68 | " \n", 69 | " self.set_title(\"Compute mean of column\")\n", 70 | " self.set_content(\n", 71 | " widgets.HTML(\"Column\"),\n", 72 | " self.column_input,\n", 73 | " self.execute_button,\n", 74 | " self.output,\n", 75 | " )\n", 76 | " \n", 77 | " def update_output(self, button): # button is a required argument (convention by ipywidgets).\n", 78 | " selected_column_name = self.column_input.value\n", 79 | " selected_series = self.get_df()[selected_column_name]\n", 80 | " \n", 81 | " try:\n", 82 | " result = selected_series.mean()\n", 83 | " message = f\"Mean of {selected_column_name}: {result:.2f}\"\n", 84 | " except:\n", 85 | " # Fails e.g. if column is not numeric.\n", 86 | " message = f\"Couldn't compute the mean for column {selected_column_name}\"\n", 87 | " \n", 88 | " # This re-renders self.output.\n", 89 | " self.output.children = [widgets.HTML(message)] # Need to use ipywidgets." 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": {}, 95 | "source": [ 96 | "When you adjusted the class, you can also debug and view the plugin UI via executing `ComputeMeanOfColumn(df=df_titanic)`. This saves you the time of navigating to the plugin in the UI in order to view your changes." 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "metadata": { 103 | "scrolled": true 104 | }, 105 | "outputs": [], 106 | "source": [ 107 | "ComputeMeanOfColumn(df=df_titanic)" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "Your users can find the plugin by searching for it's name (or description) inside of bamboolib." 115 | ] 116 | }, 117 | { 118 | "cell_type": "code", 119 | "execution_count": null, 120 | "metadata": {}, 121 | "outputs": [], 122 | "source": [ 123 | "# Run cell and search for \"mean\" in the bamboolib search bar.\n", 124 | "df_titanic" 125 | ] 126 | }, 127 | { 128 | "cell_type": "markdown", 129 | "metadata": {}, 130 | "source": [ 131 | "**Do you have any questions or feedback?** \n", 132 | "We're happy to hear it! Please shoot us a message." 133 | ] 134 | } 135 | ], 136 | "metadata": { 137 | "jupytext": { 138 | "cell_metadata_filter": "-all", 139 | "notebook_metadata_filter": "-all", 140 | "text_representation": { 141 | "extension": ".py", 142 | "format_name": "percent" 143 | } 144 | }, 145 | "kernelspec": { 146 | "display_name": "Python 3", 147 | "language": "python", 148 | "name": "python3" 149 | }, 150 | "language_info": { 151 | "codemirror_mode": { 152 | "name": "ipython", 153 | "version": 3 154 | }, 155 | "file_extension": ".py", 156 | "mimetype": "text/x-python", 157 | "name": "python", 158 | "nbconvert_exporter": "python", 159 | "pygments_lexer": "ipython3", 160 | "version": "3.7.3" 161 | } 162 | }, 163 | "nbformat": 4, 164 | "nbformat_minor": 4 165 | } 166 | -------------------------------------------------------------------------------- /plugins/examples/views/display_mean_of_column.py: -------------------------------------------------------------------------------- 1 | # %% [markdown] 2 | # # Viewplugin demo - computing and displaying the mean of a column 3 | # This little demo shows the basics of how to write a Viewplugin. 4 | # 5 | # **Goal of the plugin** 6 | # For a user specified column, display its mean. If the mean cannot be computed (e.g. because it's a string column), show the user a message. 7 | # 8 | # **Need help?** 9 | # If you have any questions or need help, please reach out. 10 | 11 | # %% [markdown] 12 | # **Your turn** 13 | # Run the code below. After that, you can call the plugin in two ways: 14 | # 1. **For the end user:** open bamboolib by calling `df_titanic` and search for the plugin by its name (or description) 15 | # 2. **During development:** call the plugin directly with `ComputeMeanOfColumn(df=df_titanic)` 16 | 17 | # %% 18 | import bamboolib as bam 19 | import pandas as pd 20 | 21 | # For this demo, we work with the titanic data set that comes pre-installed with bamboolib 22 | df_titanic = pd.read_csv(bam.titanic_csv) 23 | 24 | import ipywidgets as widgets # We use that to display e.g. HTML 25 | 26 | from bamboolib.plugins import ViewPlugin, Singleselect, Button 27 | 28 | 29 | class ComputeMeanOfColumn(ViewPlugin): 30 | 31 | # You will find the plugin via it's name and/or description. 32 | name = "Compute mean of a column" 33 | description = "Compute the mean of a selected column" 34 | 35 | def render(self): 36 | column_names = list(self.get_df().columns) 37 | 38 | self.column_input = Singleselect( 39 | options=column_names, 40 | placeholder="Choose column", 41 | focus_after_init=True, 42 | ) 43 | 44 | self.execute_button = Button( 45 | description="Compute mean", 46 | style="primary", # Make the button green. 47 | # Whenever user clicks on self.execute_button, we call update_output. 48 | # For more info, type `help(Button)` 49 | on_click=self.update_output 50 | ) 51 | 52 | self.output = widgets.VBox([]) 53 | 54 | self.set_title("Compute mean of column") 55 | self.set_content( 56 | widgets.HTML("Column"), 57 | self.column_input, 58 | self.execute_button, 59 | self.output, 60 | ) 61 | 62 | def update_output(self, button): # button is a required argument (convention by ipywidgets). 63 | selected_column_name = self.column_input.value 64 | selected_series = self.get_df()[selected_column_name] 65 | 66 | try: 67 | result = selected_series.mean() 68 | message = f"Mean of {selected_column_name}: {result:.2f}" 69 | except: 70 | # Fails e.g. if column is not numeric. 71 | message = f"Couldn't compute the mean for column {selected_column_name}" 72 | 73 | # This re-renders self.output. 74 | self.output.children = [widgets.HTML(message)] # Need to use ipywidgets. 75 | 76 | 77 | # %% [markdown] 78 | # When you adjusted the class, you can also debug and view the plugin UI via executing `ComputeMeanOfColumn(df=df_titanic)`. This saves you the time of navigating to the plugin in the UI in order to view your changes. 79 | 80 | # %% 81 | ComputeMeanOfColumn(df=df_titanic) 82 | 83 | # %% [markdown] 84 | # Your users can find the plugin by searching for it's name (or description) inside of bamboolib. 85 | 86 | # %% 87 | # Run cell and search for "mean" in the bamboolib search bar. 88 | df_titanic 89 | 90 | # %% [markdown] 91 | # **Do you have any questions or feedback?** 92 | # We're happy to hear it! Please shoot us a message. 93 | --------------------------------------------------------------------------------