{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Podjetje, varianta 1" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from sqlalchemy import Column, DateTime, String, Integer, ForeignKey, func, select, create_engine\n", "from sqlalchemy.orm import declarative_base, relationship, backref, sessionmaker\n", "from datetime import datetime" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "Base = declarative_base()\n", "\n", "\n", "class Oddelek(Base):\n", " __tablename__ = 'oddelek'\n", "\n", " id = Column(Integer, primary_key=True)\n", " naziv = Column(String)\n", "\n", " def __repr__(self):\n", " return f\"Oddelek[{self.id}, {self.naziv}, {self.seznamZaposlenih}]\"\n", "\n", "\n", "class Zaposleni(Base):\n", " __tablename__ = 'zaposleni'\n", "\n", " id = Column(Integer, primary_key=True)\n", " ime = Column(String)\n", "\n", " # uporabimo razred func za dostop do funkcij na bazi, npr. func.now()\n", " datum_zaposlitve = Column(DateTime, default=func.now())\n", " oddelek_id = Column(Integer, ForeignKey('oddelek.id'))\n", "\n", " # cascade='delete,all' bo povzročil brisanje vseh zaposlenih v oddelku\n", " oddelek = relationship(Oddelek,\n", " backref=backref('seznamZaposlenih', uselist=True, cascade='delete,all'))\n", "\n", " def __repr__(self):\n", " return f\"Zaposleni[{self.id}, {self.ime}, {self.datum_zaposlitve}, {self.oddelek_id}]\"" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:33:37,765 INFO sqlalchemy.engine.Engine BEGIN (implicit)\n", "2024-05-13 17:33:37,766 INFO sqlalchemy.engine.Engine PRAGMA main.table_info(\"oddelek\")\n", "2024-05-13 17:33:37,766 INFO sqlalchemy.engine.Engine [raw sql] ()\n", "2024-05-13 17:33:37,767 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info(\"oddelek\")\n", "2024-05-13 17:33:37,767 INFO sqlalchemy.engine.Engine [raw sql] ()\n", "2024-05-13 17:33:37,768 INFO sqlalchemy.engine.Engine PRAGMA main.table_info(\"zaposleni\")\n", "2024-05-13 17:33:37,768 INFO sqlalchemy.engine.Engine [raw sql] ()\n", "2024-05-13 17:33:37,769 INFO sqlalchemy.engine.Engine PRAGMA temp.table_info(\"zaposleni\")\n", "2024-05-13 17:33:37,769 INFO sqlalchemy.engine.Engine [raw sql] ()\n", "2024-05-13 17:33:37,771 INFO sqlalchemy.engine.Engine \n", "CREATE TABLE oddelek (\n", "\tid INTEGER NOT NULL, \n", "\tnaziv VARCHAR, \n", "\tPRIMARY KEY (id)\n", ")\n", "\n", "\n", "2024-05-13 17:33:37,771 INFO sqlalchemy.engine.Engine [no key 0.00055s] ()\n", "2024-05-13 17:33:37,780 INFO sqlalchemy.engine.Engine \n", "CREATE TABLE zaposleni (\n", "\tid INTEGER NOT NULL, \n", "\time VARCHAR, \n", "\tdatum_zaposlitve DATETIME, \n", "\toddelek_id INTEGER, \n", "\tPRIMARY KEY (id), \n", "\tFOREIGN KEY(oddelek_id) REFERENCES oddelek (id)\n", ")\n", "\n", "\n", "2024-05-13 17:33:37,781 INFO sqlalchemy.engine.Engine [no key 0.00066s] ()\n", "2024-05-13 17:33:37,788 INFO sqlalchemy.engine.Engine COMMIT\n" ] } ], "source": [ "engine = create_engine('sqlite:///podjetje1.db', echo=True)\n", "Base.metadata.bind = engine\n", "Base.metadata.create_all(engine)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "DBSessionMaker = sessionmaker(bind=engine)\n", "session = DBSessionMaker()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ustvarimo oddelek." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Oddelek[None, IT, []]" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(oddelek1 := Oddelek(naziv=\"IT\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ustvarimo zaposlenega." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Zaposleni[None, Janez, None, None]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(zaposleni1 := Zaposleni(ime=\"Janez\", oddelek=oddelek1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Dodajmo ustvarjena objekta v bazo." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:35:19,188 INFO sqlalchemy.engine.Engine BEGIN (implicit)\n", "2024-05-13 17:35:19,189 INFO sqlalchemy.engine.Engine INSERT INTO oddelek (naziv) VALUES (?)\n", "2024-05-13 17:35:19,190 INFO sqlalchemy.engine.Engine [generated in 0.00081s] ('IT',)\n", "2024-05-13 17:35:19,193 INFO sqlalchemy.engine.Engine INSERT INTO zaposleni (ime, datum_zaposlitve, oddelek_id) VALUES (?, CURRENT_TIMESTAMP, ?)\n", "2024-05-13 17:35:19,193 INFO sqlalchemy.engine.Engine [generated in 0.00069s] ('Janez', 1)\n", "2024-05-13 17:35:19,194 INFO sqlalchemy.engine.Engine COMMIT\n" ] } ], "source": [ "session.add(oddelek1)\n", "session.add(zaposleni1)\n", "session.commit()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Izpišimo trenutno vsebino baze." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:35:46,443 INFO sqlalchemy.engine.Engine BEGIN (implicit)\n", "2024-05-13 17:35:46,446 INFO sqlalchemy.engine.Engine SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni\n", "2024-05-13 17:35:46,447 INFO sqlalchemy.engine.Engine [generated in 0.00095s] ()\n" ] }, { "data": { "text/plain": [ "[Zaposleni[1, Janez, 2024-05-13 15:35:19, 1]]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Zaposleni).all()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:36:02,117 INFO sqlalchemy.engine.Engine SELECT oddelek.id AS oddelek_id, oddelek.naziv AS oddelek_naziv \n", "FROM oddelek\n", "2024-05-13 17:36:02,118 INFO sqlalchemy.engine.Engine [generated in 0.00075s] ()\n", "2024-05-13 17:36:02,122 INFO sqlalchemy.engine.Engine SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni \n", "WHERE ? = zaposleni.oddelek_id\n", "2024-05-13 17:36:02,122 INFO sqlalchemy.engine.Engine [generated in 0.00059s] (1,)\n" ] }, { "data": { "text/plain": [ "[Oddelek[1, IT, [Zaposleni[1, Janez, 2024-05-13 15:35:19, 1]]]]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Oddelek).all()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Izbrišimo `oddelek1`." ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:37:36,855 INFO sqlalchemy.engine.Engine DELETE FROM zaposleni WHERE zaposleni.id = ?\n", "2024-05-13 17:37:36,855 INFO sqlalchemy.engine.Engine [generated in 0.00075s] (1,)\n", "2024-05-13 17:37:36,857 INFO sqlalchemy.engine.Engine DELETE FROM oddelek WHERE oddelek.id = ?\n", "2024-05-13 17:37:36,857 INFO sqlalchemy.engine.Engine [generated in 0.00057s] (1,)\n", "2024-05-13 17:37:36,858 INFO sqlalchemy.engine.Engine COMMIT\n" ] } ], "source": [ "session.delete(oddelek1)\n", "session.commit()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Spet izpišimo trenutno vsebino baze." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:38:27,880 INFO sqlalchemy.engine.Engine BEGIN (implicit)\n", "2024-05-13 17:38:27,881 INFO sqlalchemy.engine.Engine SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni\n", "2024-05-13 17:38:27,882 INFO sqlalchemy.engine.Engine [cached since 161.4s ago] ()\n" ] }, { "data": { "text/plain": [ "[]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Zaposleni).all()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:38:30,534 INFO sqlalchemy.engine.Engine SELECT oddelek.id AS oddelek_id, oddelek.naziv AS oddelek_naziv \n", "FROM oddelek\n", "2024-05-13 17:38:30,535 INFO sqlalchemy.engine.Engine [cached since 148.4s ago] ()\n" ] }, { "data": { "text/plain": [ "[]" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Oddelek).all()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ustvarimo naslednjega zaposlenega in izpišimo datum zaposlitve." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n" ] } ], "source": [ "zaposleni2 = Zaposleni(ime=\"Francka\")\n", "session.add(zaposleni2)\n", "print(zaposleni2.datum_zaposlitve)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Privzeta vrednost se nastavi šele, ko kličemo `commit`." ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:39:04,056 INFO sqlalchemy.engine.Engine INSERT INTO zaposleni (ime, datum_zaposlitve, oddelek_id) VALUES (?, CURRENT_TIMESTAMP, ?)\n", "2024-05-13 17:39:04,058 INFO sqlalchemy.engine.Engine [cached since 224.9s ago] ('Francka', None)\n", "2024-05-13 17:39:04,059 INFO sqlalchemy.engine.Engine COMMIT\n", "2024-05-13 17:39:04,074 INFO sqlalchemy.engine.Engine BEGIN (implicit)\n", "2024-05-13 17:39:04,075 INFO sqlalchemy.engine.Engine SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni \n", "WHERE zaposleni.id = ?\n", "2024-05-13 17:39:04,076 INFO sqlalchemy.engine.Engine [generated in 0.00051s] (1,)\n", "2024-05-13 15:39:04\n" ] } ], "source": [ "session.commit()\n", "print(zaposleni2.datum_zaposlitve)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Za privzeto vrednost smo uporabili `func.now()`. Izpišimo njeno vrednost pred in po interakciji z bazo." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "func.now()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:41:05,066 INFO sqlalchemy.engine.Engine SELECT CURRENT_TIMESTAMP AS now_1\n", "2024-05-13 17:41:05,068 INFO sqlalchemy.engine.Engine [generated in 0.00138s] ()\n" ] }, { "data": { "text/plain": [ "(datetime.datetime(2024, 5, 13, 15, 41, 5),)" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rs = session.execute(select(func.now()))\n", "rs.fetchone()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pobrišimo vse oddelke in uporabnike v njih." ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:41:40,109 INFO sqlalchemy.engine.Engine SELECT oddelek.id AS oddelek_id, oddelek.naziv AS oddelek_naziv \n", "FROM oddelek\n", "2024-05-13 17:41:40,110 INFO sqlalchemy.engine.Engine [cached since 338s ago] ()\n", "2024-05-13 17:41:40,111 INFO sqlalchemy.engine.Engine COMMIT\n" ] } ], "source": [ "for oddelek in session.query(Oddelek).all():\n", " session.delete(oddelek)\n", "session.commit()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Še enkrat preglejmo zaposlene." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:41:50,949 INFO sqlalchemy.engine.Engine BEGIN (implicit)\n", "2024-05-13 17:41:50,949 INFO sqlalchemy.engine.Engine SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni\n", "2024-05-13 17:41:50,950 INFO sqlalchemy.engine.Engine [cached since 364.5s ago] ()\n" ] }, { "data": { "text/plain": [ "[Zaposleni[1, Francka, 2024-05-13 15:39:04, None]]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Zaposleni).all()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Ustvarimo dva oddelka in tri zaposlene, ki jih vstavimo v oddelke." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:42:57,388 INFO sqlalchemy.engine.Engine INSERT INTO oddelek (naziv) VALUES (?)\n", "2024-05-13 17:42:57,389 INFO sqlalchemy.engine.Engine [cached since 458.2s ago] ('IT',)\n", "2024-05-13 17:42:57,390 INFO sqlalchemy.engine.Engine INSERT INTO oddelek (naziv) VALUES (?)\n", "2024-05-13 17:42:57,391 INFO sqlalchemy.engine.Engine [cached since 458.2s ago] ('Finance',)\n", "2024-05-13 17:42:57,392 INFO sqlalchemy.engine.Engine INSERT INTO zaposleni (ime, datum_zaposlitve, oddelek_id) VALUES (?, CURRENT_TIMESTAMP, ?)\n", "2024-05-13 17:42:57,392 INFO sqlalchemy.engine.Engine [cached since 458.2s ago] ('Janez', 1)\n", "2024-05-13 17:42:57,394 INFO sqlalchemy.engine.Engine INSERT INTO zaposleni (ime, datum_zaposlitve, oddelek_id) VALUES (?, CURRENT_TIMESTAMP, ?)\n", "2024-05-13 17:42:57,394 INFO sqlalchemy.engine.Engine [cached since 458.2s ago] ('Metka', 2)\n", "2024-05-13 17:42:57,395 INFO sqlalchemy.engine.Engine COMMIT\n" ] } ], "source": [ "IT = Oddelek(naziv=\"IT\")\n", "finance = Oddelek(naziv=\"Finance\")\n", "janez = Zaposleni(ime=\"Janez\", oddelek=IT)\n", "metka = Zaposleni(ime=\"Metka\", oddelek=finance)\n", "session.add(IT)\n", "session.add(finance)\n", "session.add(janez)\n", "session.add(metka)\n", "session.commit()" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:43:47,675 INFO sqlalchemy.engine.Engine SELECT oddelek.id AS oddelek_id, oddelek.naziv AS oddelek_naziv \n", "FROM oddelek \n", "WHERE oddelek.id = ?\n", "2024-05-13 17:43:47,676 INFO sqlalchemy.engine.Engine [generated in 0.00090s] (2,)\n", "2024-05-13 17:43:47,678 INFO sqlalchemy.engine.Engine INSERT INTO zaposleni (ime, datum_zaposlitve, oddelek_id) VALUES (?, CURRENT_TIMESTAMP, ?)\n", "2024-05-13 17:43:47,678 INFO sqlalchemy.engine.Engine [cached since 508.5s ago] ('Katka', 2)\n", "2024-05-13 17:43:47,680 INFO sqlalchemy.engine.Engine COMMIT\n" ] } ], "source": [ "katka = Zaposleni(ime=\"Katka\", oddelek=finance)\n", "session.add(katka)\n", "session.commit()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Preštejmo zaposlene." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:43:50,014 INFO sqlalchemy.engine.Engine BEGIN (implicit)\n", "2024-05-13 17:43:50,015 INFO sqlalchemy.engine.Engine SELECT count(*) AS count_1 \n", "FROM (SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni) AS anon_1\n", "2024-05-13 17:43:50,016 INFO sqlalchemy.engine.Engine [cached since 9.968s ago] ()\n" ] }, { "data": { "text/plain": [ "4" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Zaposleni).count()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Izpišimo ime enega zaposlenega, ki se začne na črko K." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:44:21,984 INFO sqlalchemy.engine.Engine SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni \n", "WHERE (zaposleni.ime LIKE ? || '%')\n", "2024-05-13 17:44:21,985 INFO sqlalchemy.engine.Engine [generated in 0.00079s] ('K',)\n" ] }, { "data": { "text/plain": [ "'Katka'" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Zaposleni).filter(Zaposleni.ime.startswith(\"K\")).one().ime" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Izpišimo ime enega zaposlenega, ki je hkrati v oddelku Finance in se njegovo ime začne na črko K." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:45:46,134 INFO sqlalchemy.engine.Engine SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni JOIN oddelek ON oddelek.id = zaposleni.oddelek_id \n", "WHERE (zaposleni.ime LIKE ? || '%') AND oddelek.naziv = ?\n", "2024-05-13 17:45:46,135 INFO sqlalchemy.engine.Engine [cached since 18.97s ago] ('K', 'Finance')\n" ] }, { "data": { "text/plain": [ "[Zaposleni[4, Katka, 2024-05-13 15:43:47, 2]]" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Zaposleni).join(Zaposleni.oddelek).filter(Zaposleni.ime.startswith('K'), Oddelek.naziv == 'Finance').all()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Izpišimo število zaposlenih, ki so bili zaposleni v preteklosti." ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2024-05-13 17:46:01,270 INFO sqlalchemy.engine.Engine SELECT count(*) AS count_1 \n", "FROM (SELECT zaposleni.id AS zaposleni_id, zaposleni.ime AS zaposleni_ime, zaposleni.datum_zaposlitve AS zaposleni_datum_zaposlitve, zaposleni.oddelek_id AS zaposleni_oddelek_id \n", "FROM zaposleni \n", "WHERE zaposleni.datum_zaposlitve < CURRENT_TIMESTAMP) AS anon_1\n", "2024-05-13 17:46:01,271 INFO sqlalchemy.engine.Engine [generated in 0.00101s] ()\n" ] }, { "data": { "text/plain": [ "4" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "session.query(Zaposleni).filter(Zaposleni.datum_zaposlitve < func.now()).count()" ] } ], "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.8.10" } }, "nbformat": 4, "nbformat_minor": 4 }