/* * Project Name : Visual Python * Description : GUI-based Python code generator * File Name : com_Config.js * Author : Black Logic * Note : Configuration and settings control * License : GNU GPLv3 with Visual Python special exception * Date : 2021. 09. 16 * Change Date : */ //============================================================================ // [CLASS] Configuration //============================================================================ define([ './com_Const', './com_util', './com_interface', 'text!vp_base/python/userCommand.py', ], function(com_Const, com_util, com_interface, userCommandFile) { 'use strict'; //======================================================================== // Define Inner Variable //======================================================================== /** * Type of mode */ const _MODE_TYPE = { DEVELOP : 0, RELEASE : 1 } //======================================================================== // Declare Class //======================================================================== /** * Configuration and settings */ class Config { //======================================================================== // Constructor //======================================================================== constructor(initialData) { // initial configuration this.data = { // Configuration 'vpcfg': { }, // User defined code for Snippets 'vpudf': { 'default import': [ 'import numpy as np', 'import pandas as pd', 'import matplotlib.pyplot as plt', '%matplotlib inline', 'import seaborn as sns', 'import plotly.express as px' ], 'matplotlib customizing': [ 'import matplotlib.pyplot as plt', '%matplotlib inline', '', "plt.rc('figure', figsize=(12, 8))", '', 'from matplotlib import rcParams', "rcParams['font.family'] = 'New Gulim'", "rcParams['font.size'] = 10", "rcParams['axes.unicode_minus'] = False" ], 'as_float': [ 'def as_float(x):', ' """', " usage: df['col'] = df['col'].apply(as_float)", ' """', ' if not isinstance(x, str):', ' return 0.0', ' else:', ' try:', ' result = float(x)', ' return result', ' except ValueError:', ' return 0.0' ], 'as_int': [ 'def as_int(x):', ' """', " usage: df['col'] = df['col'].apply(as_int)", ' """', ' if not isinstance(x, str):', ' return 0', ' else:', ' try:', ' result = int(x)', ' return result', ' except ValueError:', ' return 0.0' ] }, 'vpimport': [ { library: 'numpy', alias:'np' }, { library: 'pandas', alias:'pd' }, { library: 'matplotlib.pyplot', alias:'plt', include: [ '%matplotlib inline' ] }, { library: 'seaborn', alias:'sns' }, { library: 'plotly.express', alias: 'px', include: [ 'from plotly.offline import init_notebook_mode', 'init_notebook_mode(connected=True)' ] } ] } this.data = { ...this.data, ...initialData } this.defaultConfig = {}; this.metadataSettings = {}; this.moduleDict = { 'np': { code: 'import numpy as np', type: 'package' }, 'pd': { code: 'import pandas as pd', type: 'package' }, 'plt': { code: 'import matplotlib.pyplot as plt\n%matplotlib inline', type: 'package' }, 'sns': { code: 'import seaborn as sns', type: 'package' }, 'metrics': { code: 'from sklearn import metrics', type: 'package' }, 'ProfileReport': { code: 'from pandas_profiling import ProfileReport', type: 'package' }, 'px': { code: 'import plotly.express as px\nfrom plotly.offline import init_notebook_mode\ninit_notebook_mode(connected=True)', type: 'package' }, 'WordCloud': { code: 'from wordcloud import WordCloud', type: 'package' }, 'fitz': { code: 'import fitz', type: 'package' }, 'nltk': { code: "import nltk\nnltk.download('punkt')", type: 'package' }, 'Counter': { code: 'from collections import Counter', type: 'package' } } this._readDefaultConfig(); this._readUserCommandList(); } /** * Read dejault config */ _readDefaultConfig() { // default values for system-wide configurable parameters this.defaultConfig = { indent: 4 }; // default values for per-notebook configurable parameters this.metadataSettings = { vp_config_version: '1.0.0', vp_signature: 'VisualPython', vp_position: {}, vp_section_display: false, vp_note_display: false, vp_menu_width: Config.MENU_MIN_WIDTH, vp_note_width: Config.BOARD_MIN_WIDTH }; let vp_width = Config.MENU_MIN_WIDTH + (this.metadataSettings.vp_note_display? Config.BOARD_MIN_WIDTH: 0) + Config.MENU_BOARD_SPACING; this.metadataSettings['vp_position'] = { // height: 'calc(100% - 110px)', // width: vp_width + 'px', // right: '0px', // top: '110px', width: vp_width } // merge default config $.extend(true, this.defaultConfig, this.metadataSettings); } _readUserCommandList() { let divider = '#'.repeat(6); // get list of codes (ignore first 2 items) let tmpList = userCommandFile.split(divider).slice(2); // match key-codes-description // { 'func_name': { code: '', description: '' } } let funcDict = {}; let reg = /^def (.+)\(/; let name = ''; let code = ''; let desc = ''; let packageAlias = { '_vp_np': 'np', '_vp_pd': 'pd', '_vp_plt': 'plt' } for (let i = 0; i < tmpList.length; i += 2) { desc = tmpList[i].trim(); code = tmpList[i + 1].trim(); let regResult = reg.exec(code); if (regResult !== null) { name = regResult[1]; // convert code's package alias Object.keys(packageAlias).forEach(key => { let desAlias = packageAlias[key]; code = code.replaceAll(key + '.', desAlias + '.'); }); // list up funcDict[name] = { code: code, type: 'function', description: desc }; } } this.moduleDict = { ...this.moduleDict, ...funcDict } } /** * Read kernel functions for using visualpython * - manually click restart menu (MenuFrame.js) * - automatically restart on jupyter kernel restart (loadVisualpython.js) */ readKernelFunction() { var libraryList = [ 'printCommand.py', 'fileNaviCommand.py', 'pandasCommand.py', 'variableCommand.py', 'visualizationCommand.py', // 'userCommand.py' ]; let promiseList = []; libraryList.forEach(libName => { var libPath = com_Const.PYTHON_PATH + libName $.get(libPath).done(function(data) { var code_init = data; promiseList.push(vpKernel.execute(code_init)); }).fail(function() { console.log('visualpython - failed to read library file', libName); }); }); // run all promises let failed = false; Promise.all(promiseList).then(function(resultObj) { }).catch(function(resultObj) { failed = true; console.log('visualpython - failed to load library', resultObj); }).finally(function() { if (!failed) { console.log('visualpython - loaded libraries', libraryList); } else { console.log('visualpython - failed to load libraries'); } }); } getMode() { return Config.serverMode; } loadData(configKey = 'vpudf') { return new Promise(function(resolve, reject) { Jupyter.notebook.config.load(); Jupyter.notebook.config.loaded.then(function() { var data = Jupyter.notebook.config.data[configKey]; if (data == undefined) { data = {}; } resolve(data); }); }); }; /** * Get configuration data (on server) * @param {String} dataKey * @param {String} configKey * @returns */ getData(dataKey='', configKey='vpudf') { return new Promise(function(resolve, reject) { Jupyter.notebook.config.load(); Jupyter.notebook.config.loaded.then(function() { var data = Jupyter.notebook.config.data[configKey]; if (data == undefined) { resolve(data); return; } if (dataKey == '') { resolve(data); return; } if (Object.keys(data).length > 0) { resolve(data[dataKey]); return; } reject('No data available.'); }); }); } getDataSimple(dataKey='', configKey='vpudf') { Jupyter.notebook.config.load(); var data = Jupyter.notebook.config.data[configKey]; if (data == undefined) { return undefined; } if (dataKey == '') { return data; } if (Object.keys(data).length > 0) { return data[dataKey]; } return undefined; } /** * Set configuration data (on server) * @param {Object} dataObj * @param {String} configKey */ setData(dataObj, configKey='vpudf') { // set data using key Jupyter.notebook.config.loaded.then(function() { Jupyter.notebook.config.update({[configKey]: dataObj}); }); } removeData(key, configKey = 'vpudf') { // if set value to null, it removes from config data Jupyter.notebook.config.loaded.then(function() { Jupyter.notebook.config.update({[configKey]: {[key]: null}}); }); } /** * Get metadata (on jupyter file) * @param {String} dataKey * @param {String} configKey */ getMetadata(dataKey='', configKey='vp') { let metadata = Jupyter.notebook.metadata[configKey]; if (metadata) { // update this metadataSetting this.metadataSettings = { ...this.metadataSettings, ...metadata }; // no datakey, return all metadata if (dataKey == '') { return metadata; } return metadata[dataKey]; } return {}; } /** * Set metadata (on jupyter file) * @param {Object} dataObj * @param {String} configKey */ setMetadata(dataObj, configKey='vp') { let oldData = Jupyter.notebook.metadata[configKey]; Jupyter.notebook.metadata[configKey] = { ...oldData, ...dataObj }; Jupyter.notebook.set_dirty(); // update this metadataSetting this.metadataSettings = { ...this.metadataSettings, ...dataObj }; } /** * Reset metadata (on jupyter file) * @param {String} configKey */ resetMetadata(configKey='vp') { Jupyter.notebook.metadata[configKey] = {}; } /** * Check vp pypi package version (Promise) * usage: * vpConfig.getPackageVersion('visualpython').then(function(version) { * // do something after loading version * ... * }).catch(function(err) { * // error handling * ... * }) */ getPackageVersion(packName='visualpython') { let url = `https://pypi.org/pypi/${packName}/json`; // using the Fetch API return new Promise(function(resolve, reject) { try { fetch(url).then(function (response) { // if (response.statusCode === 200) { // return response.json(); // } else if (response.statusCode === 204) { // throw new Error('No Contents', response); // } else if (response.statusCode === 404) { // throw new Error('Page Not Found', response); // } else if (response.statusCode === 500) { // throw new Error('Internal Server Error', response); // } else { // throw new Error('Unexpected Http Status Code', response); // } if (response.ok) { return response.json(); } else { throw new Error('Error', response); } }).then(function (data) { resolve(data.info.version); }).catch(function(err) { let errMsg = err.message; if (errMsg.includes('Failed to fetch')) { errMsg = 'Network connection error'; } reject(errMsg); }); } catch (err) { reject(err); } }); } getVpInstalledVersion() { return Config.version; } checkVpVersion(background=false) { let that = this; let nowVersion = this.getVpInstalledVersion(); this.getPackageVersion().then(function(latestVersion) { if (nowVersion === latestVersion) { // if it's already up to date // hide version update icon $('#vp_versionUpdater').hide(); if (background) { ; } else { let msg = com_util.formatString('Visual Python is up to date. ({0})', latestVersion); com_util.renderInfoModal(msg); } // update version_timestamp that.setData({ 'version_timestamp': new Date().getTime() }, 'vpcfg'); } else { let msg = com_util.formatString('Visual Python updates are available.
(Latest version: {0} / Your version: {1})', latestVersion, nowVersion); // show version update icon $('#vp_versionUpdater').attr('title', msg.replace('
', '')); $('#vp_versionUpdater').data('version', latestVersion); $('#vp_versionUpdater').show(); // render update modal com_util.renderModal({ title: 'Update version', message: msg, buttons: ['Cancel', 'Update'], defaultButtonIdx: 0, buttonClass: ['cancel', 'activated'], finish: function(clickedBtnIdx) { switch (clickedBtnIdx) { case 0: // cancel break; case 1: // update let info = [ '## Visual Python Upgrade', 'NOTE: ', '- Refresh your web browser to start a new version.', '- Save VP Note before refreshing the page.' ]; com_interface.insertCell('markdown', info.join('\n')); com_interface.insertCell('code', '!pip install visualpython --upgrade'); com_interface.insertCell('code', '!visualpy install'); // update version_timestamp that.setData({ 'version_timestamp': new Date().getTime() }, 'vpcfg'); // hide updater $('#vp_versionUpdater').hide(); break; } } }); } }).catch(function(err) { if (background) { vpLog.display(VP_LOG_TYPE.ERROR, 'Version Checker - ' + err); } else { com_util.renderAlertModal(err); } }) } getMenuGroupLabel(key = '') { return Config.MENU_GROUP_DICT[key]; } getMenuGroupDict() { return Config.MENU_GROUP_DICT; } getDataTypes() { return Config.DATA_TYPES; } getMLDataDict(key = '') { if (key == '') { return Config.ML_DATA_DICT; } return Config.ML_DATA_DICT[key]; } getMLDataTypes() { return Config.ML_DATA_TYPES; } getMLCategories() { return Object.keys(Config.ML_DATA_DICT); } getModuleCode(modName='') { if (modName == '') { return this.moduleDict; } try { return this.moduleDict[modName]; } catch { return null; } } } //======================================================================== // Define static variable //======================================================================== /** * FIXME: before release, change it to _MODE_TYPE.RELEASE */ // Config.serverMode = _MODE_TYPE.DEVELOP; Config.serverMode = _MODE_TYPE.RELEASE; /** * Version */ Config.version = "2.2.8"; /** * Type of mode */ Config.MODE_TYPE = _MODE_TYPE; /** * Frame size settings */ Config.JUPYTER_HEADER_SPACING = 110; Config.MENU_MIN_WIDTH = 273; Config.BOARD_MIN_WIDTH = 263; Config.MENU_BOARD_SPACING = 5; Config.VP_MIN_WIDTH = Config.MENU_MIN_WIDTH + Config.BOARD_MIN_WIDTH + Config.MENU_BOARD_SPACING; // = MENU_MIN_WIDTH + BOARD_MIN_WIDTH + MENU_BOARD_SPACING /** * Menu group codes */ Config.MENU_GROUP_DICT = { '': '', 'logic': 'Logic', 'library': 'Library', 'apps': 'Data Analysis', 'visualization': 'Visualization', 'machine_learning': 'Machine Learning' } /** * Data types */ Config.DATA_TYPES = [ // pandas object 'DataFrame', 'Series', 'Index', 'Period', 'GroupBy', 'Timestamp' // Index type object , 'RangeIndex', 'CategoricalIndex', 'MultiIndex', 'IntervalIndex', 'DatetimeIndex', 'TimedeltaIndex', 'PeriodIndex', 'Int64Index', 'UInt64Index', 'Float64Index' // GroupBy type object , 'DataFrameGroupBy', 'SeriesGroupBy' // Plot type , 'Figure', 'AxesSubplot' // Numpy , 'ndarray' // Python variable , 'str', 'int', 'float', 'bool', 'dict', 'list', 'tuple' ] /** * Data types using for searching model variables */ Config.ML_DATA_DICT = { 'Data Preparation': [ /** Encoding */ 'OneHotEncoder', 'LabelEncoder', 'OrdinalEncoder', 'TargetEncoder', 'SMOTE', /** Scaling */ 'StandardScaler', 'RobustScaler', 'MinMaxScaler', 'Normalizer', 'FunctionTransformer', 'PolynomialFeatures', 'KBinsDiscretizer', /** ETC */ 'ColumnTransformer' ], 'Regression': [ 'LinearRegression', 'Ridge', 'Lasso', 'ElasticNet', 'SVR', 'DecisionTreeRegressor', 'RandomForestRegressor', 'GradientBoostingRegressor', 'XGBRegressor', 'LGBMRegressor', 'CatBoostRegressor', ], 'Classification': [ 'LogisticRegression', 'BernoulliNB', 'MultinomialNB', 'GaussianNB', 'SVC', 'DecisionTreeClassifier', 'RandomForestClassifier', 'GradientBoostingClassifier', 'XGBClassifier', 'LGBMClassifier', 'CatBoostClassifier', ], 'Clustering': [ 'KMeans', 'AgglomerativeClustering', 'GaussianMixture', 'DBSCAN', ], 'Dimension Reduction': [ 'PCA', 'LinearDiscriminantAnalysis', 'TruncatedSVD', 'NMF', 'TSNE' ], 'Auto ML': [ 'AutoSklearnRegressor', 'AutoSklearnClassifier', 'TPOTRegressor', 'TPOTClassifier' ] }; Config.ML_DATA_TYPES = [ ...Config.ML_DATA_DICT['Data Preparation'], ...Config.ML_DATA_DICT['Regression'], ...Config.ML_DATA_DICT['Classification'], ...Config.ML_DATA_DICT['Clustering'], ...Config.ML_DATA_DICT['Dimension Reduction'], ...Config.ML_DATA_DICT['Auto ML'] ]; return Config; }); /* End of file */