├── .gitignore ├── LICENSE ├── README.md ├── data ├── builtins.dat ├── faker.dat ├── numpy_np.dat └── pandas_pd.dat ├── images ├── example-frame.png └── faker_example.png └── python-experiment.el /.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 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Wanderson Ferreira 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # python-experiment 2 | 3 | **Package to make Experiments in Python way lot easier.** 4 | 5 | 6 | *How many times you desired to have a dummy dictionary or dataframe just available to verify if that obscure operation you developed works or not?* 7 | 8 | *Well, these issues are addressed by this package.* 9 | 10 | 11 | **OBS>>> This package was renamed from Python Experiment Mode to Python Experiment. I am sorry, but it makes more sense now. 12 | 13 | 14 | # Installation 15 | For now, there is only one way to install this package. 16 | 17 | First clone the repo in the right folder: 18 | 19 | ``` shell 20 | cd ~/.emacs.d/site-packages 21 | git submodule add https://github.com/wandersoncferreira/python-experiment 22 | ``` 23 | 24 | Then add these lines to your **init.el** file. 25 | 26 | 27 | ``` emacs-lisp 28 | (add-to-list 'load-path "~/.emacs.d/site-packages/python-experiment") 29 | (require 'python-experiment) 30 | ``` 31 | 32 | If you desire to see this package in MELPA let me know in Issues. 33 | 34 | 35 | 36 | # Usage 37 | 38 | There are 4 recommended bindings in this package: 39 | 40 | ``` emacs-lisp 41 | (global-set-key (kbd "") 'python-experiment) 42 | (global-set-key (kbd "") 'python-experiment-lived-too-long) 43 | (global-set-key (kbd "") 'python-experiment-reload) 44 | (global-set-key (kbd "") 'python-experiment-buffer-to-file) 45 | ``` 46 | 47 | 48 | F9 will open a frame like this one below: 49 | 50 | ![Example of the Frame that will be opened.](images/example-frame.png) 51 | 52 | 53 | The Python Experiment Buffer is not attached to any file and you can easily edit it. 54 | 55 | 56 | F10 will shut everything down! 57 | 58 | 59 | 60 | F11 If you edit the Python Experiment Buffer to include any additional datatype, you can press **F11** to reload the Inferior Python Process with the new additions. 61 | 62 | 63 | 64 | F12 After a whole day of work you might have added several custom additions to your specific situation. Press **F12** to save the Python Experiment Buffer to a custom file that will be loaded in the next time. 65 | 66 | 67 | # Settings 68 | 69 | There are a few builtin modules loaded by default: os and sys. 70 | However you can customize this variable using the **list-of-builtins** variable as follows: 71 | 72 | 73 | ```eshell 74 | (setq python-experiment-builtins '((functools . nil) (os . nil) (collections . cl))) 75 | ``` 76 | 77 | This variable holds an alist which first member is the name of your module and the second member is its alias. 78 | 79 | The collection module would be imported as: 80 | 81 | ``` python 82 | import collections as cl 83 | ``` 84 | 85 | 86 | OBS: Every default data or module is only loaded if you have the module installed in your Python Environment. The package already checks it. 87 | 88 | 89 | # Faker library 90 | 91 | I just started using the [Faker](https://github.com/joke2k/faker) library. It will suit very nicely what is the purpose of this package. Additional custom default provides might be: 92 | 93 | + Fake CSV files. 94 | 95 | However, faker already have a lot of nice builtins options. Example: 96 | 97 | ![Example of the Faker library in action.](images/faker_example.png) 98 | 99 | You need to install the library to be able to load automatically. 100 | 101 | ``` shell 102 | pip install Faker 103 | ``` 104 | 105 | 106 | # Contributions 107 | 108 | I would love to extend this package. Open a Issue and let me know of your ideas! 109 | Not need to any programming skiils: Problems still to be addressed: Naming conventions!! 110 | 111 | 112 | 113 | If you want to contribute adding more standard datatypes at the "data" folder, submit a Pull Request right away. o/ 114 | 115 | 116 | 117 | # Possible future features 118 | 119 | I have been looking through the [Factory Boy](https://factoryboy.readthedocs.io/en/latest/) library. Might be using this to make the package more robust and scalable. Would be possible to make fake copies of your custom entities from your own projects easily. The possibilities are endless. 120 | 121 | 122 | However, adds a dependancy to this library's usage. (partially!) 123 | -------------------------------------------------------------------------------- /data/builtins.dat: -------------------------------------------------------------------------------- 1 | # list with integers 2 | ilist = [el for el in range(20)] 3 | 4 | 5 | # datetime 6 | dt_base = dt.datetime.today() 7 | dt_list = [(dt_base - dt.timedelta(days=el)).date() for el in range(20)] 8 | 9 | 10 | 11 | # dictionary with integers 12 | dict_int = {key: value for key, value in zip(range(0, 20), range(10, 30))} 13 | 14 | 15 | 16 | # dictionary with dates in keys 17 | dict_dates = {key: value for key, value in zip(dt_list, ilist)} 18 | 19 | 20 | 21 | # regular class 22 | class NormalClass: 23 | 24 | def foo(self): 25 | NotImplemented 26 | 27 | 28 | def bar(self): 29 | raise NotImplementedError 30 | -------------------------------------------------------------------------------- /data/faker.dat: -------------------------------------------------------------------------------- 1 | # fake factory of data 2 | fake = faker.Faker() 3 | 4 | 5 | # examples: 6 | # fake.name() 7 | # fake.address() 8 | # fake.text() 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/numpy_np.dat: -------------------------------------------------------------------------------- 1 | # matrix with zeros 2 | mzeros = np.zeros((20, 20)) 3 | 4 | 5 | # column matrix with random values 6 | mc_random = np.random.random((1, 20)) 7 | 8 | 9 | # line matrix with random values 10 | ml_random = np.random.random((20, 1)) 11 | 12 | 13 | # full matrix with random values 14 | m_random = np.random.random((20, 20)) 15 | -------------------------------------------------------------------------------- /data/pandas_pd.dat: -------------------------------------------------------------------------------- 1 | # integer dataframe 2 | df_int = pd.DataFrame({"col1": [el for el in range(10, 40)], 3 | "col2": [el for el in range(55, 85)], 4 | "col3": [el for el in range(30)]}) 5 | 6 | # date dataframe 7 | df_dates = pd.DataFrame({"col_index": [(dt.datetime.today() + dt.timedelta(weeks=el)).date() for el in range(20)], 8 | "col1": [el for el in range(100, 120)], 9 | "col2": [el for el in range(1, 21)]}) 10 | df_dates.set_index("col_index", inplace=True) 11 | 12 | 13 | 14 | # pandas datetime dataframe 15 | df_pandas_dates = df_dates.copy() 16 | df_pandas_dates.index = pd.to_datetime(df_pandas_dates.index) 17 | 18 | 19 | -------------------------------------------------------------------------------- /images/example-frame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wandersoncferreira/python-experiment/ea1860a901074bee2af63b231a864ef943c86cea/images/example-frame.png -------------------------------------------------------------------------------- /images/faker_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wandersoncferreira/python-experiment/ea1860a901074bee2af63b231a864ef943c86cea/images/faker_example.png -------------------------------------------------------------------------------- /python-experiment.el: -------------------------------------------------------------------------------- 1 | ;;; python-experiment.el --- Python Experiment setup. 2 | 3 | ;; Copyright (C) 4 | ;; Author: Wanderson Ferreira 5 | ;; Package: python-experiment 6 | ;; Version: 0.1 7 | ;; Package-Requires: ((emacs "24.3")) 8 | 9 | ;; This file is not part of GNU Emacs. 10 | 11 | ;; This program is free software: you can redistribute it and/or modify 12 | ;; it under the terms of the GNU General Public License as published by 13 | ;; the Free Software Foundation, either version 3 of the License, or 14 | ;; (at your option) any later version. 15 | 16 | ;; This program is distributed in the hope that it will be useful, 17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | ;; GNU General Public License for more details. 20 | 21 | ;; You should have received a copy of the GNU General Public License 22 | ;; along with this program. If not, see . 23 | 24 | ;;; Commentary: 25 | 26 | ;; Python Experiment creates a new frame with Python objects (dict, list, dataframe) 27 | ;; filled with dummy values to be used in any ways. 28 | 29 | ;; Example: 30 | ;; Imagine you want to verify if the method pop works for dictionary and for lists. 31 | ;; You would need to create a dictionary and then create a list filled with dummy values 32 | ;; This package have already created those!! Just use it. 33 | 34 | ;;; Code: 35 | 36 | (require 'python) 37 | 38 | 39 | (defvar python-experiment-name ".python-experiment" 40 | "The name of the buffer that will be opened.") 41 | 42 | (defun python-experiment-new-frame () 43 | "Create a new frame in Python Experiment." 44 | (interactive) 45 | (switch-to-buffer-other-frame python-experiment-name) 46 | (python-mode)) 47 | 48 | (defun python-experiment-inferior-shell () 49 | "Function to open an inferior Python Process inside the new frame." 50 | (run-python (python-shell-parse-command) nil nil) 51 | (python-shell-send-buffer) 52 | (python-shell-switch-to-shell)) 53 | 54 | 55 | (defun python-experiment-insert-datatypes () 56 | "Function to insert the desired datatypes in folder /data/." 57 | (let 58 | ((datatype-files (file-expand-wildcards (concat user-emacs-directory "site-packages/python-experiment/data/*.dat")))) 59 | (dolist (file-name-full datatype-files) 60 | (let* 61 | ((file-name (car (last (split-string file-name-full "/")))) 62 | (module-nickname-p (car (split-string file-name ".dat"))) 63 | (list-module-nickname (split-string module-nickname-p "_")) 64 | (module-name (car list-module-nickname)) 65 | (module-nickname (car (cdr list-module-nickname)))) 66 | (if (or (python-experiment-check-import module-name) (string-equal module-name "builtins")) 67 | (progn 68 | (open-line 2) 69 | (insert-file-contents file-name-full) 70 | (newline) 71 | (if (not (string-equal module-name "builtins")) 72 | (progn 73 | (save-excursion 74 | (goto-char (point-min)) 75 | (if module-nickname 76 | (progn 77 | (insert (format "import %s as %s" module-name module-nickname)) 78 | (newline)) 79 | (insert (format "import %s" module-name)) 80 | (newline))))))))))) 81 | 82 | 83 | ;; name of the python packages should be placed as alist objects 84 | ;; desired format (numpy . np) for aliased imports 85 | ;; desired format (numpy . nil) for non-aliased imports 86 | (defvar python-experiment-builtins '((os . nil) (sys . nil) (datetime . dt) (abc . nil)) 87 | "Alist of modules to be imported during the call of the program.") 88 | 89 | (defun python-experiment-insert-imports () 90 | "Function to insert the desired python imports." 91 | (dolist (module-pair python-experiment-builtins) 92 | (let ((module-name (car module-pair)) 93 | (module-nickname (cdr module-pair))) 94 | (if (python-experiment-check-import (car module-pair)) 95 | (if module-nickname 96 | (progn 97 | (insert (format "import %s as %s" module-name module-nickname)) 98 | (newline)) 99 | (insert (format "import %s" module-name)) 100 | (newline)))))) 101 | 102 | 103 | (defun python-experiment-check-import (module-name) 104 | "Function to check if a MODULE-NAME exists in the users's system." 105 | (let 106 | ((output-command (shell-command-to-string (format "python -c 'import %s'" module-name)))) 107 | (not (string-match "^Traceback*" output-command)))) 108 | 109 | 110 | (defun python-experiment-is-running () 111 | "Function to check if there is already an instance of the Python Experiment opened." 112 | (get-buffer python-experiment-name)) 113 | 114 | 115 | ;; better to bind it later to something better to you. 116 | (defun python-experiment-lived-too-long () 117 | "Meeseeks!" 118 | (interactive) 119 | (when (get-buffer-process "*Python*") 120 | (set-process-query-on-exit-flag (get-buffer-process "*Python*") nil) 121 | (kill-process (get-buffer-process "*Python*")) 122 | (kill-buffer "*Python*")) 123 | (when (get-buffer python-experiment-name) 124 | (if (string-equal (buffer-name) python-experiment-name) 125 | (kill-buffer-and-window) 126 | (switch-to-buffer-other-frame python-experiment-name) 127 | (kill-buffer-and-window)) 128 | (delete-frame))) 129 | 130 | (defun python-experiment-reload () 131 | "If you want to type new things at Python Experiment buffer." 132 | (interactive) 133 | (with-current-buffer python-experiment-name 134 | (python-shell-send-buffer))) 135 | 136 | 137 | (defun python-experiment-buffer-to-file () 138 | "If you desired to save your Python Experiment buffer to a file to be loaded the next time." 139 | (interactive) 140 | (with-current-buffer python-experiment-name 141 | (let ((pfile (concat user-emacs-directory python-experiment-name))) 142 | (if (file-exists-p pfile) 143 | (progn 144 | (if (vc-backend pfile) 145 | (vc-delete-file pfile) 146 | (delete-file pfile)))) 147 | (write-file pfile))) 148 | (message (format "Your Python Experiment buffer was written to %s" python-experiment-name))) 149 | 150 | (defun python-experiment-delete-custom-file () 151 | "Function to remove the custom file. This will make the package load the default experiment in the next run." 152 | (interactive) 153 | (let ((pfile (concat user-emacs-directory python-experiment-name))) 154 | (if (file-exists-p pfile) 155 | (progn 156 | (delete-file pfile) 157 | (message "Custom file deleted with success!")) 158 | (message "I can't remove a custom file that doesn't exist! Ni!")))) 159 | 160 | 161 | ;;;###autoload 162 | (defun python-experiment () 163 | "Main function to start the Python Experiment Mode." 164 | (interactive) 165 | (if (python-experiment-is-running) 166 | (progn 167 | (if (not (string-equal (buffer-name) python-experiment-name)) 168 | (switch-to-buffer-other-frame python-experiment-name)) 169 | (python-experiment-inferior-shell)) 170 | (python-experiment-new-frame) 171 | (if (file-exists-p (concat user-emacs-directory python-experiment-name)) 172 | (insert-file-contents (concat user-emacs-directory python-experiment-name)) 173 | (python-experiment-insert-imports) 174 | (python-experiment-insert-datatypes)) 175 | (python-experiment-inferior-shell)) 176 | (message "Python Experiment is now running!")) 177 | 178 | 179 | ;; global suggested bindings 180 | (defun python-experiment-pkeys () 181 | "Function to add local keys to a python major mode." 182 | 183 | ;; python mode 184 | (define-key python-mode-map (kbd "") 'python-experiment) 185 | (define-key python-mode-map (kbd "") 'python-experiment-lived-too-long) 186 | (define-key python-mode-map (kbd "") 'python-experiment-reload) 187 | (define-key python-mode-map (kbd "") 'python-experiment-buffer-to-file)) 188 | 189 | (add-hook 'python-mode-hook 'python-experiment-pkeys) 190 | 191 | (defun python-experiment-ipkeys () 192 | "Function to add local keys to an inferior python mode." 193 | ;; inferior python mode 194 | (define-key inferior-python-mode-map (kbd "") 'python-experiment) 195 | (define-key inferior-python-mode-map (kbd "") 'python-experiment-lived-too-long) 196 | (define-key inferior-python-mode-map (kbd "") 'python-experiment-reload) 197 | (define-key inferior-python-mode-map (kbd "") 'python-experiment-buffer-to-file)) 198 | (add-hook 'inferior-python-mode-hook 'python-experiment-ipkeys) 199 | 200 | (provide 'python-experiment) 201 | ;;; python-experiment.el ends here 202 | --------------------------------------------------------------------------------