diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..a52f3c1e --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,6 @@ +repos: +- repo: https://github.com/kynan/nbstripout + rev: master + hooks: + - id: nbstripout + files: ".ipynb" \ No newline at end of file diff --git a/docs/source/Examples/example_3J_with_DA_solver.rst b/docs/source/Examples/example_3J_with_DA_solver.rst index 00fb637a..22ec7bee 100755 --- a/docs/source/Examples/example_3J_with_DA_solver.rst +++ b/docs/source/Examples/example_3J_with_DA_solver.rst @@ -84,7 +84,7 @@ Example of a 2J solar cell calculated with the PDD solver mat.electron_mobility = 3.4e-3 mat.hole_mobility = 3.4e-3 mat.electron_mobility = 5e-2 - mat.permittivity = 9 + mat.relative_permittivity = 9 # And, finally, we put everything together, adding also the surface recombination velocities. We also add some shading # due to the metallisation of the cell = 8%, and indicate it has an area of 0.7x0.7 mm2 (converted to m2) diff --git a/examples/coherency_example_2.py b/examples/coherency_example_2.py index 4c45d595..87fd8264 100644 --- a/examples/coherency_example_2.py +++ b/examples/coherency_example_2.py @@ -39,11 +39,11 @@ def this_dir_file(f): # this is just Python stuff, so it can find external file top_cell_p_material = GaInP(In=0.51,Na=siUnits(1.5e17, "cm-3"), electron_diffusion_length=si("2um")) top_cell_TJ_material = Al08Ga02As(Al=0.8) -#for mat in [top_cell_n_material, top_cell_p_material]: - #mat.band_gap = material('GaInP')(In=0.51).band_gap - #mat.eff_mass_hh_z = material('GaInP')(In=0.51).eff_mass_hh_z - #mat.eff_mass_electron = material('GaInP')(In=0.51).eff_mass_electron - #mat.permittivity = 11.75 +for mat in [top_cell_n_material, top_cell_p_material]: + mat.band_gap = material('GaInP')(In=0.51).band_gap + mat.eff_mass_hh_z = material('GaInP')(In=0.51).eff_mass_hh_z + mat.eff_mass_electron = material('GaInP')(In=0.51).eff_mass_electron + mat.relative_permittivity = 11.75 all_materials.append(ARC1) all_materials.append(ARC2) @@ -59,11 +59,11 @@ def this_dir_file(f): # this is just Python stuff, so it can find external file mid_BSF_material = GaInP(In=0.51) mid_cell_TJ_material = Al08Ga02As(Al=0.8) -#for mat in [mid_cell_n_material, mid_cell_p_material]: -# mat.band_gap = material('GaAs')(In=0.01).band_gap -# mat.eff_mass_hh_z = material('GaAs')(In=0.01).eff_mass_hh_z -# mat.eff_mass_electron = material('GaAs')(In=0.01).eff_mass_electron -# mat.permittivity = 13.1 +for mat in [mid_cell_n_material, mid_cell_p_material]: + mat.band_gap = material('GaAs')(In=0.01).band_gap + mat.eff_mass_hh_z = material('GaAs')(In=0.01).eff_mass_hh_z + mat.eff_mass_electron = material('GaAs')(In=0.01).eff_mass_electron + mat.relative_permittivity = 13.1 all_materials.append(mid_window_material) all_materials.append(mid_cell_n_material) @@ -84,11 +84,11 @@ def this_dir_file(f): # this is just Python stuff, so it can find external file bot_cell_n_material = Ge(Nd=siUnits(2e18, "cm-3"), hole_diffusion_length=si("800nm")) bot_cell_p_material = Ge(Na=siUnits(1e17, "cm-3"), electron_diffusion_length=si("50um")) -#for mat in [bot_cell_n_material, bot_cell_p_material]: -# mat.band_gap = material('Ge')().band_gap -# mat.eff_mass_hh_z = material('Ge')().eff_mass_hh_z -# mat.eff_mass_electron = material('Ge')().eff_mass_electron -# mat.permittivity = 16 +for mat in [bot_cell_n_material, bot_cell_p_material]: + mat.band_gap = material('Ge')().band_gap + mat.eff_mass_hh_z = material('Ge')().eff_mass_hh_z + mat.eff_mass_electron = material('Ge')().eff_mass_electron + mat.relative_permittivity = 16 all_materials.append(bot_buffer_material) all_materials.append(bot_nucleation_material) @@ -144,9 +144,9 @@ def this_dir_file(f): # this is just Python stuff, so it can find external file options.BL_correction = True options.coherency_list = 111*['c'] options.theta = 30 -solar_cell_solver(optical_struct, 'optics', options) +solar_cell_solver(optical_struct, 'qe', options) -plt.figure(3) +plt.figure() plt.plot(wl*1e9, optical_struct[0].layer_absorption+optical_struct[1].layer_absorption) plt.plot(wl*1e9, optical_struct[2].layer_absorption) plt.plot(wl*1e9, optical_struct[3].layer_absorption) @@ -156,6 +156,18 @@ def this_dir_file(f): # this is just Python stuff, so it can find external file plt.plot(wl*1e9, optical_struct.reflected, '--') plt.legend(['ARC', 'top', 'middle', 'bottom', 'A', 'T', 'R']) plt.ylim(0,1) +plt.ylabel('Absorption/Transmission/Reflection') +plt.xlabel('Wavelength (nm)') +plt.show() + +plt.figure() +plt.plot(wl*1e9, 100*optical_struct[2].eqe(wl)) +plt.plot(wl*1e9, 100*optical_struct[3].eqe(wl)) +plt.plot(wl*1e9, 100*optical_struct[100].eqe(wl)) +plt.plot(wl*1e9, 100*optical_struct.absorbed, '--') +plt.legend(['top', 'middle', 'bottom', 'A']) +plt.ylim(0,100) +plt.ylabel('EQE (%)') plt.xlabel('Wavelength (nm)') plt.show() diff --git a/examples/notebooks/Absorption_profile_AlGaAs_GaAs_structure.ipynb b/examples/notebooks/Absorption_profile_AlGaAs_GaAs_structure.ipynb new file mode 100644 index 00000000..7e27dd60 --- /dev/null +++ b/examples/notebooks/Absorption_profile_AlGaAs_GaAs_structure.ipynb @@ -0,0 +1,190 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "name": "Absorption_profile_AlGaAs_GaAs_structure.ipynb", + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + } + }, + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "id": "-1Z1-d4C47YK", + "colab_type": "text" + }, + "source": [ + "# Absorption Profile AlGaAs GaAs Structure Example" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "9282DOR42thA", + "colab_type": "code", + "colab": {} + }, + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "from solcore.absorption_calculator import calculate_absorption_profile\n", + "from solcore import material, si\n", + "from solcore.structure import Structure, Layer" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "U9-mFKNO22IZ", + "colab_type": "text" + }, + "source": [ + "First we defined a couple of materials, for example, GaAs and AlGAs" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "dHoZMpKB25ZY", + "colab_type": "code", + "colab": {} + }, + "source": [ + "GaAs = material('GaAs')(T=300)\n", + "AlGaAs = material('AlGaAs')(T=300, Al=0.3)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "qmA8l1ja272Y", + "colab_type": "text" + }, + "source": [ + "Now, let's build the structure" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "d5DpfgwH2-rp", + "colab_type": "code", + "colab": {} + }, + "source": [ + "my_structure = Structure([\n", + " Layer(si(30, 'nm'), material=AlGaAs),\n", + " Layer(si(3000, 'nm'), material=GaAs),\n", + " Layer(si(300, 'um'), material=GaAs),\n", + "])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "q-p7bGCM3BAJ", + "colab_type": "text" + }, + "source": [ + "We want to calculate the absorption profile of this structure as a function of the position and wavelength" + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "ihObNLeu3C4p", + "colab_type": "code", + "colab": {} + }, + "source": [ + "wl = np.linspace(400, 1000, 200)\n", + "out = calculate_absorption_profile(my_structure, wl, steps_size=1, z_limit=3000)" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "rq_rk3S13Enp", + "colab_type": "text" + }, + "source": [ + "Finally, we plot the absorption profile. Note that absorption at short wavelengths take place near the surface of the structure, in the AlGaAs layer and top of the GaAs layer, while longer wavelengths penetrate more. Wavelengths beyond the GaAs band edge are not absorbed." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "WAfmwPn_3dYh", + "colab_type": "code", + "colab": {} + }, + "source": [ + "plt.figure(1)\n", + "ax = plt.contourf(out['position'], wl, out['absorption'], 200)\n", + "plt.xlabel('Position (nm)')\n", + "plt.ylabel('Wavelength (nm)')\n", + "cbar = plt.colorbar()\n", + "cbar.set_label('Absorption (1/nm)')" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "ta2lqN483fQI", + "colab_type": "text" + }, + "source": [ + "We can also check what is the overall light absorption in the AlGaAs and GaAs epilayers as that represents the total light absorption in our solar cell and therefore the maximum EQE (light absorbed in the thick substrate lost). The absorption is mostly limited by the reflexion in the front surface. Clearly, this solar cell needs an AR coating." + ] + }, + { + "cell_type": "code", + "metadata": { + "id": "MFBsE2UG2SLc", + "colab_type": "code", + "colab": {} + }, + "source": [ + "A = np.zeros_like(wl)\n", + "\n", + "for i, absorption in enumerate(out['absorption'][:]):\n", + " A[i] = np.trapz(absorption, out['position'])" + ], + "execution_count": 0, + "outputs": [] + }, + { + "cell_type": "code", + "metadata": { + "id": "zGdyOW4H3oig", + "colab_type": "code", + "colab": {} + }, + "source": [ + "plt.figure(2)\n", + "plt.plot(wl, A)\n", + "plt.xlabel('Wavelength (nm)')\n", + "plt.ylabel('Absorption')\n", + "\n", + "plt.show()" + ], + "execution_count": 0, + "outputs": [] + } + ] +} diff --git a/examples/notebooks/Light_sources_example.ipynb b/examples/notebooks/Light_sources_example.ipynb new file mode 100644 index 00000000..7f98014d --- /dev/null +++ b/examples/notebooks/Light_sources_example.ipynb @@ -0,0 +1,152 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Solcore - Light sources examples\n", + "***\n", + "Import libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "import datetime \n", + "\n", + "from solcore.light_source import LightSource" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Define the wavelength `wl` range of the spectra" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "wl = np.linspace(300, 3000, 200)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now different types of light sources can be defined\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "gauss = LightSource(source_type='laser', x=wl, center=800, linewidth=50, power=200)\n", + "bb = LightSource(source_type='black body', x=wl, T=5800, entendue='Sun')\n", + "am15g = LightSource(source_type='standard', x=wl, version='AM1.5g')\n", + "spectral = LightSource(source_type='SPECTRAL2', x=wl)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot comparing the different light sources" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.figure(1)\n", + "plt.plot(*gauss.spectrum(), label='Gauss')\n", + "plt.plot(*bb.spectrum(), label='Black body')\n", + "plt.plot(*am15g.spectrum(), label='AM1.5G')\n", + "plt.plot(*spectral.spectrum(), label='SPECTRAL2')\n", + "\n", + "plt.xlim(300, 3000)\n", + "plt.xlabel('Wavelength (nm)')\n", + "plt.ylabel('Power density (Wm$^{-2}$nm$^{-1}$)')\n", + "plt.tight_layout()\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot comparing the spectra calculated with GAUSS at different hours of the day" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.figure(2)\n", + "for h in range(8, 20):\n", + " plt.plot(*spectral.spectrum(dateAndTime=datetime.datetime(2011, 6, 30, h)), label=f"{h} h")\n", + "\n", + "plt.xlim(300, 3000)\n", + "plt.xlabel('Wavelength (nm)')\n", + "plt.ylabel('Power density (Wm$^{-2}$nm$^{-1}$)')\n", + "plt.tight_layout()\n", + "plt.legend()\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.3" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/notebooks/Schrodinger_QW_absorption.ipynb b/examples/notebooks/Schrodinger_QW_absorption.ipynb new file mode 100644 index 00000000..4e47ae96 --- /dev/null +++ b/examples/notebooks/Schrodinger_QW_absorption.ipynb @@ -0,0 +1,207 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Solcore - Schrodinger_QW_absorption\n", + "\n", + "***\n", + "\n", + "Import libraries" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "from solcore import si, material\n", + "from solcore.structure import Layer, Structure\n", + "import solcore.quantum_mechanics as QM\n", + "from solcore.constants import vacuum_permittivity, q" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "First we create the materials we need" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "bulk = material(\"GaAs\")(T=293, strained=False)\n", + "barrier = material(\"GaAsP\")(T=293, P=0.1, strained=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As well as some of the layers" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "top_layer = Layer(width=si(\"30nm\"), material=bulk)\n", + "inter = Layer(width=si(\"3nm\"), material=bulk)\n", + "barrier_layer = Layer(width=si(\"15nm\"), material=barrier)\n", + "bottom_layer = top_layer" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We are going to calculate the absorption coefficient of InGaAs QWs of fixed thickness but different compositions" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "num_comp = 5\n", + "comp = np.linspace(0.05, 0.25, num_comp)\n", + "colors = plt.cm.jet(np.linspace(0, 1, num_comp))\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The absorption coefficients will be calculated at these energies and stored in alfas" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "num_energy = 300\n", + "E = np.linspace(1.15, 1.5, num_energy) * q" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We define some parameters need to calculate the shape of the excitonic absorption" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "alpha_params = {\n", + " \"well_width\": si(\"7.2nm\"),\n", + " \"theta\": 0,\n", + " \"eps\": 12.9 * vacuum_permittivity,\n", + " \"espace\": E,\n", + " \"hwhm\": si(\"6meV\"),\n", + " \"dimensionality\": 0.16,\n", + " \"line_shape\": \"Gauss\"\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Plot results:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "\n", + "# plt.figure(figsize=(4, 4.5))\n", + "for j, i in enumerate(comp):\n", + " # We create the QW material at the given composition\n", + " QW = material(\"InGaAs\")(T=293, In=i, strained=True)\n", + "\n", + " # And the layer\n", + " well_layer = Layer(width=si(\"7.2nm\"), material=QW)\n", + "\n", + " # The following lines create the QW structure, with different number of QWs and interlayers\n", + " test_structure = Structure([barrier_layer, inter, well_layer, inter, barrier_layer], substrate=bulk)\n", + "\n", + " # Finally, the quantum properties are claculated here\n", + " output = QM.schrodinger(test_structure, quasiconfined=0, num_eigenvalues=20, alpha_params=alpha_params,\n", + " calculate_absorption=True)\n", + "\n", + " alfa = output[0]['alphaE'](E)\n", + " plt.plot(1240 / (E / q), alfa / 100, label='{}%'.format(int(i * 100)))\n", + "\n", + "plt.xlim(826, 1100)\n", + "plt.ylim(0, 23000)\n", + "plt.xlabel('Wavelength (nm)')\n", + "plt.ylabel('$\\\\alpha$ cm$^{-1}$')\n", + "plt.legend(loc='upper right', frameon=False)\n", + "plt.tight_layout()\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.3" + }, + "latex_envs": { + "LaTeX_envs_menu_present": true, + "autoclose": false, + "autocomplete": true, + "bibliofile": "biblio.bib", + "cite_by": "apalike", + "current_citInitial": 1, + "eqLabelWithNumbers": true, + "eqNumInitial": 1, + "hotkeys": { + "equation": "Ctrl-E", + "itemize": "Ctrl-I" + }, + "labels_anchors": false, + "latex_user_defs": false, + "report_style_numbering": false, + "user_envs_cfg": false + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/notebooks/kp_fit_effective_masses.ipynb b/examples/notebooks/kp_fit_effective_masses.ipynb new file mode 100644 index 00000000..bbe1c65e --- /dev/null +++ b/examples/notebooks/kp_fit_effective_masses.ipynb @@ -0,0 +1,128 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "from solcore import material\n", + "from solcore.constants import electron_mass\n", + "from solcore.quantum_mechanics import kp_bands" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Material parameters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "GaAs = material(\"GaAs\")(T=300)\n", + "InGaAs = material(\"InGaAs\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "InGaAs2 = InGaAs(In=0.15, T=300)\n", + "masses = kp_bands(InGaAs2, GaAs, graph=True, fit_effective_mass=True, effective_mass_direction=\"L\", return_so=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As a test, we solve the problem for an intermediate indium composition" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "comp = np.linspace(0.01, 0.25, 15)\n", + "me = []\n", + "mhh = []\n", + "mlh = []\n", + "mso = []\n", + "for i in comp:\n", + " InGaAs2 = InGaAs(In=i, T=300)\n", + "\n", + " # Set graph = True to see the fitting of the bands\n", + " c, hh, lh, so, m_eff_c, m_eff_hh, m_eff_lh, m_eff_so = kp_bands(InGaAs2, GaAs, graph=False, fit_effective_mass=True,\n", + " effective_mass_direction=\"L\", return_so=True)\n", + "\n", + " me.append(m_eff_c / electron_mass)\n", + " mhh.append(m_eff_hh / electron_mass)\n", + " mlh.append(m_eff_lh / electron_mass)\n", + " mso.append(m_eff_so / electron_mass)\n", + "\n", + " print('Effective masses for In = {:2.3}%:'.format(i * 100))\n", + " print('- m_e = {:1.3f} m0'.format(me[-1]))\n", + " print('- m_hh = {:1.3f} m0'.format(mhh[-1]))\n", + " print('- m_lh = {:1.3f} m0'.format(mlh[-1]))\n", + " print('- m_so = {:1.3f} m0'.format(mso[-1]))\n", + " print()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot(comp * 100, me, 'b-o', label='e')\n", + "plt.plot(comp * 100, mhh, 'r-o', label='hh')\n", + "plt.plot(comp * 100, mlh, 'g-o', label='lh')\n", + "plt.plot(comp * 100, mso, 'k-o', label='so')\n", + "\n", + "plt.xlabel(\"Indium content (%)\")\n", + "plt.ylabel(\"Effective mass (m$_0$)\")\n", + "plt.legend()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "venv", + "language": "python", + "name": "venv" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.8" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/requirements.txt b/requirements.txt index da91cd7f..168a9f01 100755 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ natsort regex cycler pyyaml +pre-commit \ No newline at end of file