1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
|
<!-- Automatically generated by emacsconf-publish-after-page -->
<div class="transcript transcript-mainVideo"><a name="python-mainVideo-transcript"></a><h1>Transcript</h1>
[[!template text="""Okay, so welcome to this session about interactive Python""" start="00:00:00.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""programming. My name is David Vujic and I live and work in""" start="00:00:04.440" video="mainVideo-python" id="subtitle"]]
[[!template text="""Stockholm, Sweden. a developer and today I focus""" start="00:00:09.680" video="mainVideo-python" id="subtitle"]]
[[!template text="""mainly on Python software development. So I do this at work""" start="00:00:15.320" video="mainVideo-python" id="subtitle"]]
[[!template text="""and I also do this on my spare time in my open source projects.""" start="00:00:20.440" video="mainVideo-python" id="subtitle"]]
[[!template text="""Before that, I've been part of the Lisp community. I've""" start="00:00:26.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""been a Clojure developer, and also, like, way back,""" start="00:00:30.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""I was in the Microsoft world and developed C# and .NET stuff.""" start="00:00:33.701" video="mainVideo-python" id="subtitle"]]
[[!template text="""What I've been doing lately is to try to improve the""" start="00:00:40.280" video="mainVideo-python" id="subtitle"]]
[[!template text="""developer experience when you write Python code. So what I""" start="00:00:46.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""want to talk about is this, but also I want to begin with""" start="00:00:52.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""feedback loops because I think it's very related to this""" start="00:00:56.160" video="mainVideo-python" id="subtitle"]]
[[!template text="""interactive programming style, like having this nice""" start="00:01:00.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""feedback when you write code.""" start="00:01:05.360" video="mainVideo-python" id="subtitle"]]
[[!template text="""So I'm going to begin with that.""" start="00:01:07.068" video="mainVideo-python" id="subtitle"]]
<div class="transcript-heading">[[!template new="1" text="""Feedback loops""" start="00:01:10.534" video="mainVideo-python" id="subtitle"]]</div>[[!template text="""So this image, you know, this circle is supposed to be a""" start="00:01:10.534" video="mainVideo-python" id="subtitle"]]
[[!template text="""visualization of a feedback loop. Let's say we write our""" start="00:01:14.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""code and then we deploy it to production. Then when it's""" start="00:01:19.880" video="mainVideo-python" id="subtitle"]]
[[!template text="""running there, we can check if things work, or if maybe someone""" start="00:01:25.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""else will let us know. Maybe our customers will let us know.""" start="00:01:29.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""That's a pretty slow feedback loop with potential risks of""" start="00:01:35.320" video="mainVideo-python" id="subtitle"]]
[[!template text="""damaging your business or whatever.""" start="00:01:39.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""This is obvious, of course.""" start="00:01:41.868" video="mainVideo-python" id="subtitle"]]
[[!template text="""So a faster feedback loop probably is to have""" start="00:01:44.168" video="mainVideo-python" id="subtitle"]]
[[!template text="""some kind of automation when you do commits""" start="00:01:50.001" video="mainVideo-python" id="subtitle"]]
[[!template text="""or maybe you have this pull request things and even reviews.""" start="00:01:54.067" video="mainVideo-python" id="subtitle"]]
[[!template text="""So maybe not always as fast as deploy,""" start="00:01:59.734" video="mainVideo-python" id="subtitle"]]
[[!template text="""don't deploy directly to production, but""" start="00:02:02.934" video="mainVideo-python" id="subtitle"]]
[[!template text="""it's probably safer and often you get this automated""" start="00:02:05.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""feedback faster anyway. But it's still kind of slow. You""" start="00:02:10.540" video="mainVideo-python" id="subtitle"]]
[[!template text="""have to wait. You have to push things to GitHub maybe and""" start="00:02:16.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""wait. So there's faster ways for sure to get feedback.""" start="00:02:20.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""So a much faster way is to write code,""" start="00:02:24.280" video="mainVideo-python" id="subtitle"]]
[[!template text="""and write some unit tests, and run those unit tests.""" start="00:02:27.968" video="mainVideo-python" id="subtitle"]]
[[!template text="""So then you do everything on your local machine""" start="00:02:31.368" video="mainVideo-python" id="subtitle"]]
[[!template text="""and you will fairly quickly learn if your code does""" start="00:02:33.468" video="mainVideo-python" id="subtitle"]]
[[!template text="""what you think it does or if it doesn't. I want to zoom in to""" start="00:02:39.040" video="mainVideo-python" id="subtitle"]]
[[!template text="""this test write code and test flow a bit. Let's do that.""" start="00:02:47.160" video="mainVideo-python" id="subtitle"]]
<div class="transcript-heading">[[!template new="1" text="""Test-driven development""" start="00:02:56.000" video="mainVideo-python" id="subtitle"]]</div>[[!template text="""As a developer, I have used a thing called test-driven""" start="00:02:56.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""development for quite some time. I find that this way of""" start="00:02:59.760" video="mainVideo-python" id="subtitle"]]
[[!template text="""working is very fast when it comes to getting feedback on""" start="00:03:06.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""what your code does and how you should continue the""" start="00:03:11.260" video="mainVideo-python" id="subtitle"]]
[[!template text="""development. So, test-driven development,""" start="00:03:14.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""basically that you start writing a test for""" start="00:03:19.981" video="mainVideo-python" id="subtitle"]]
[[!template text="""something that you want to develop, and then you continue""" start="00:03:24.221" video="mainVideo-python" id="subtitle"]]
[[!template text="""developing that, and then you go back to the test, and modify""" start="00:03:27.021" video="mainVideo-python" id="subtitle"]]
[[!template text="""and modify the code, and you go back and forth between the""" start="00:03:31.020" video="mainVideo-python" id="subtitle"]]
[[!template text="""tests and the code.""" start="00:03:35.080" video="mainVideo-python" id="subtitle"]]
[[!template text="""It's sort of like a ping-pong game. I find this very""" start="00:03:36.960" video="mainVideo-python" id="subtitle"]]
[[!template text="""effective when you want to get feedback and to know how to""" start="00:03:44.420" video="mainVideo-python" id="subtitle"]]
[[!template text="""continue the development. The most important thing""" start="00:03:50.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""that I feel is that you know what the code does.""" start="00:03:57.234" video="mainVideo-python" id="subtitle"]]
[[!template text="""You learn very quickly.""" start="00:04:01.701" video="mainVideo-python" id="subtitle"]]
<div class="transcript-heading">[[!template new="1" text="""REPL-driven development""" start="00:04:05.560" video="mainVideo-python" id="subtitle"]]</div>[[!template text="""Let's zoom into this TDD flow a little bit. The last couple of""" start="00:04:05.560" video="mainVideo-python" id="subtitle"]]
[[!template text="""years, I've been doing a slightly different thing which is""" start="00:04:12.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""called REPL-driven development. REPL-driven""" start="00:04:17.380" video="mainVideo-python" id="subtitle"]]
[[!template text="""development is very similar to test-driven development,""" start="00:04:21.980" video="mainVideo-python" id="subtitle"]]
[[!template text="""but I find it even quicker. You get feedback even quicker""" start="00:04:25.720" video="mainVideo-python" id="subtitle"]]
[[!template text="""than with a regular TDD setup. So REPL-driven development""" start="00:04:31.160" video="mainVideo-python" id="subtitle"]]
[[!template text="""is about writing and evaluating code in a REPL basically.""" start="00:04:34.980" video="mainVideo-python" id="subtitle"]]
[[!template text="""And you can do experiments and you can refactor and""" start="00:04:41.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""re-evaluate and you get instant feedback on what the code""" start="00:04:46.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""does and what you need to change. So I think that's even""" start="00:04:51.700" video="mainVideo-python" id="subtitle"]]
[[!template text="""faster than test-driven development.""" start="00:04:54.800" video="mainVideo-python" id="subtitle"]]
[[!template text="""Okay, REPL driven development. Let's go back. What's the""" start="00:04:59.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""REPL? Most of developers know what a REPL is. The most common""" start="00:05:02.900" video="mainVideo-python" id="subtitle"]]
[[!template text="""setup is you open this shell and you use the REPL for your""" start="00:05:10.760" video="mainVideo-python" id="subtitle"]]
[[!template text="""programming language. In this case I'm using the Python""" start="00:05:16.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""REPL or the IPython REPL which is an enhanced REPL for Python""" start="00:05:19.360" video="mainVideo-python" id="subtitle"]]
[[!template text="""development. So what happens here is that we start a REPL""" start="00:05:25.620" video="mainVideo-python" id="subtitle"]]
[[!template text="""session in isolation. So this session knows about the""" start="00:05:30.680" video="mainVideo-python" id="subtitle"]]
[[!template text="""Python environment. So it knows about the Python language""" start="00:05:34.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""basically. So as soon as we start writing things, adding""" start="00:05:38.120" video="mainVideo-python" id="subtitle"]]
[[!template text="""variables or creating writing functions or even doing""" start="00:05:42.360" video="mainVideo-python" id="subtitle"]]
[[!template text="""imports. Then the session will be more and more aware of the""" start="00:05:47.360" video="mainVideo-python" id="subtitle"]]
[[!template text="""code so we will add things to the to the session and then that""" start="00:05:51.680" video="mainVideo-python" id="subtitle"]]
[[!template text="""means that we can run functions we can print out these""" start="00:05:55.820" video="mainVideo-python" id="subtitle"]]
[[!template text="""variables and things like that. But with REPL driven""" start="00:06:00.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""development it's not really that well at least not what I""" start="00:06:05.860" video="mainVideo-python" id="subtitle"]]
[[!template text="""mean with REPL driven development. So what I'm thinking of""" start="00:06:09.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""is that you are in your code editor where you have your""" start="00:06:14.040" video="mainVideo-python" id="subtitle"]]
[[!template text="""autocomplete, and you have your syntax highlighting and""" start="00:06:19.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""your favorite theme, color theme, and all of those things. But""" start="00:06:22.800" video="mainVideo-python" id="subtitle"]]
[[!template text="""instead, you have this running REPL in the background or in a""" start="00:06:30.460" video="mainVideo-python" id="subtitle"]]
[[!template text="""smaller window or buffer. So that means that you write code""" start="00:06:34.980" video="mainVideo-python" id="subtitle"]]
[[!template text="""and you can send that code to the running REPL, to the REPL""" start="00:06:41.140" video="mainVideo-python" id="subtitle"]]
[[!template text="""session. You write and do everything as you would do when""" start="00:06:45.320" video="mainVideo-python" id="subtitle"]]
[[!template text="""writing your code basically. In this case, in this""" start="00:06:50.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""example, I have evaluated these two functions. I've sent""" start="00:06:55.220" video="mainVideo-python" id="subtitle"]]
[[!template text="""them to the REPL session so it's aware of these functions.""" start="00:07:00.600" video="mainVideo-python" id="subtitle"]]
[[!template text="""Then I switched to a separate different module and""" start="00:07:05.820" video="mainVideo-python" id="subtitle"]]
[[!template text="""evaluated that one. So the REPL session now knows about""" start="00:07:10.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""these two functions and also these two variables. That""" start="00:07:14.040" video="mainVideo-python" id="subtitle"]]
[[!template text="""means that I can evaluate the state of those variables and""" start="00:07:19.040" video="mainVideo-python" id="subtitle"]]
[[!template text="""change code and re-evaluate and things like that. So in this""" start="00:07:24.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""example if you look in the smaller area there you see that I""" start="00:07:29.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""have evaluated this res variable on line 6 and the output was""" start="00:07:33.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""that it's a dictionary with two keys and two values""" start="00:07:39.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""basically. So this setup works in basically any of your""" start="00:07:42.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""favorite code editors. So you can do this in Visual Studio""" start="00:07:51.220" video="mainVideo-python" id="subtitle"]]
[[!template text="""Code, you can do this in PyCharm or Vim. But what I have done is""" start="00:07:54.080" video="mainVideo-python" id="subtitle"]]
[[!template text="""that... More like what I have missed is that when I write code""" start="00:08:01.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""and do this evaluation, this is really cool, but then I need""" start="00:08:07.120" video="mainVideo-python" id="subtitle"]]
[[!template text="""to switch context if I want to see the result. I have to switch""" start="00:08:10.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""context to this other window. I""" start="00:08:15.460" video="mainVideo-python" id="subtitle"]]
[[!template text="""have my focus on the code and then I have to look in a different""" start="00:08:21.980" video="mainVideo-python" id="subtitle"]]
[[!template text="""place to know the results. And if it's a larger output, then""" start="00:08:25.760" video="mainVideo-python" id="subtitle"]]
[[!template text="""maybe I need to scroll. So I wanted to find out if it was""" start="00:08:31.800" video="mainVideo-python" id="subtitle"]]
[[!template text="""possible to make this even smoother and faster, this""" start="00:08:37.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""feedback loop even faster, so I don't have to switch""" start="00:08:43.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""context. What I've done here is that... I can select a row or a""" start="00:08:45.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""region and I can evaluate and then an overlay, a small pop-up""" start="00:08:52.120" video="mainVideo-python" id="subtitle"]]
[[!template text="""shows up with the evaluated result right next to it. So I can""" start="00:08:58.080" video="mainVideo-python" id="subtitle"]]
[[!template text="""change code and re-evaluate and quickly see the result of it""" start="00:09:03.120" video="mainVideo-python" id="subtitle"]]
[[!template text="""without doing this context switching. So the way I've done""" start="00:09:07.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""it is that I wanted to reuse the existing tooling that I""" start="00:09:12.641" video="mainVideo-python" id="subtitle"]]
[[!template text="""already had. I know that my in-editor REPL, the IPython""" start="00:09:20.680" video="mainVideo-python" id="subtitle"]]
[[!template text="""REPL, already does this evaluation. So I figured maybe I can""" start="00:09:27.740" video="mainVideo-python" id="subtitle"]]
[[!template text="""extract the data and do this visualization as a separate""" start="00:09:31.560" video="mainVideo-python" id="subtitle"]]
[[!template text="""thing. That's how I've done it. What I've done is that""" start="00:09:35.360" video="mainVideo-python" id="subtitle"]]
[[!template text="""I've created this overlay and placed it where my cursor""" start="00:09:40.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""currently is, right next to the code. Then I've""" start="00:09:47.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""extracted the evaluated result and put it in this overlay.""" start="00:09:50.860" video="mainVideo-python" id="subtitle"]]
[[!template text="""I also want this overlay to have this nice looking syntax,""" start="00:09:55.720" video="mainVideo-python" id="subtitle"]]
[[!template text="""so I've set it to this Python mode, so we get this syntax""" start="00:10:01.040" video="mainVideo-python" id="subtitle"]]
[[!template text="""highlighting. Make it look very readable. And as a nice""" start="00:10:04.760" video="mainVideo-python" id="subtitle"]]
[[!template text="""developer experience thing,""" start="00:10:10.560" video="mainVideo-python" id="subtitle"]]
[[!template text="""when you move the cursor, of course you don't want the""" start="00:10:16.880" video="mainVideo-python" id="subtitle"]]
[[!template text="""overlay to be there. You want it to disappear. So those kinds""" start="00:10:20.380" video="mainVideo-python" id="subtitle"]]
[[!template text="""of things I've added. So putting the overlay at the right""" start="00:10:25.680" video="mainVideo-python" id="subtitle"]]
[[!template text="""place and feed it with the evaluated data and then make it""" start="00:10:29.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""disappear when it's not interesting to look at anymore.""" start="00:10:33.280" video="mainVideo-python" id="subtitle"]]
[[!template text="""What I've described so far is something that I use on a""" start="00:10:39.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""daily basis, and it covers most of my needs while doing Python""" start="00:10:44.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""development. But one thing I still miss, and I miss it from my""" start="00:10:50.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""days as a Clojure developer, because over there we could""" start="00:10:56.120" video="mainVideo-python" id="subtitle"]]
[[!template text="""have a running app on our local machine and we can have our""" start="00:11:03.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""editor, and the app and the editor were connected. So when I""" start="00:11:07.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""did some changes in the code, the app would change without""" start="00:11:12.720" video="mainVideo-python" id="subtitle"]]
[[!template text="""any restarts or anything like that. And the same if I would""" start="00:11:17.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""change the state of the app, I can inspect the state from the""" start="00:11:20.560" video="mainVideo-python" id="subtitle"]]
[[!template text="""code. So they were connected. They are connected. So I was""" start="00:11:24.680" video="mainVideo-python" id="subtitle"]]
[[!template text="""thinking, hey, this would be really cool if we could have""" start="00:11:28.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""something like this in Python. And that reminded me of""" start="00:11:32.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""Jupyter and Jupyter notebooks because I think notebooks,""" start="00:11:39.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""the way you do things there, is very similar to what I was""" start="00:11:43.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""trying to achieve. So I was reading up a little bit on how this""" start="00:11:49.660" video="mainVideo-python" id="subtitle"]]
[[!template text="""notebook thing works. It turns out that a notebook is a""" start="00:11:56.880" video="mainVideo-python" id="subtitle"]]
[[!template text="""client that talks to a server, that communicates with a""" start="00:12:00.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""server. It's on the server that all this Python""" start="00:12:05.280" video="mainVideo-python" id="subtitle"]]
[[!template text="""evaluation and all this thing happens. Then what I've""" start="00:12:08.800" video="mainVideo-python" id="subtitle"]]
[[!template text="""done is that instead of starting up IPython in my editor, I""" start="00:12:14.160" video="mainVideo-python" id="subtitle"]]
[[!template text="""start the Jupyter console instead. And then I can give it""" start="00:12:19.660" video="mainVideo-python" id="subtitle"]]
[[!template text="""that unique ID and it will be connected to that running""" start="00:12:23.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""kernel.""" start="00:12:27.160" video="mainVideo-python" id="subtitle"]]
<div class="transcript-heading">[[!template new="1" text="""FastAPI CRUD""" start="00:12:30.920" video="mainVideo-python" id="subtitle"]]</div>[[!template text="""In this example, I've created this FastAPI CRUD app that""" start="00:12:30.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""has this create, read, update, and delete endpoints. It""" start="00:12:37.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""has this, it's locally running, it has this database where""" start="00:12:41.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""you can do all these things. I'm running this FastAPI app""" start="00:12:46.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""in the kernel and then I've connected to, I've connected to""" start="00:12:51.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""the kernel in my editor too. Both of them are connected to""" start="00:12:58.060" video="mainVideo-python" id="subtitle"]]
[[!template text="""the kernel. What I do now is that I want to initially create""" start="00:13:03.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""some data. I'm going to add this, creating this message.""" start="00:13:09.720" video="mainVideo-python" id="subtitle"]]
[[!template text="""What I get back is a message ID. I want to experiment in""" start="00:13:15.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""my browser. What do I get with that message ID? I'm""" start="00:13:19.900" video="mainVideo-python" id="subtitle"]]
[[!template text="""evaluating the read function. I instantly get this""" start="00:13:24.360" video="mainVideo-python" id="subtitle"]]
[[!template text="""evaluated result, which was this hello world text. So what""" start="00:13:30.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""happens if I do some changes in this app? I'm going to grab""" start="00:13:34.780" video="mainVideo-python" id="subtitle"]]
[[!template text="""this message ID and write something else.""" start="00:13:39.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""Now I can evaluate the same thing again, and you can see that""" start="00:13:49.660" video="mainVideo-python" id="subtitle"]]
[[!template text="""the content has changed to this new value. My editor isn't""" start="00:13:53.760" video="mainVideo-python" id="subtitle"]]
[[!template text="""in any debug mode or something like that. It doesn't know""" start="00:14:02.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""what database it is. It doesn't have any environment""" start="00:14:07.720" video="mainVideo-python" id="subtitle"]]
[[!template text="""variables set up or something like that. It is only""" start="00:14:11.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""connected to the kernel, and the kernel is aware of that. It's""" start="00:14:14.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""running the app. It has the connection strings and""" start="00:14:17.600" video="mainVideo-python" id="subtitle"]]
[[!template text="""everything that is needed. So that's how this thing works.""" start="00:14:20.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""Now I want to do some inline hacking because I want to store""" start="00:14:28.800" video="mainVideo-python" id="subtitle"]]
[[!template text="""this input that is sent from this app because I want to work""" start="00:14:34.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""with it afterwards. I can add this dictionary that stores""" start="00:14:37.800" video="mainVideo-python" id="subtitle"]]
[[!template text="""this message. I'm updating the source code of this app, and""" start="00:14:42.040" video="mainVideo-python" id="subtitle"]]
[[!template text="""when I run any of these endpoints again, you will see that""" start="00:14:48.760" video="mainVideo-python" id="subtitle"]]
[[!template text="""the state changes, and the new inputs, I can grab and I can use""" start="00:15:03.080" video="mainVideo-python" id="subtitle"]]
[[!template text="""them for quick evaluation or testing. This example is""" start="00:15:08.760" video="mainVideo-python" id="subtitle"]]
[[!template text="""really simple. It was just an integer. For example, if you""" start="00:15:14.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""are sending a more complex object, maybe a pydantic schema""" start="00:15:18.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""or something, and you want to inspect what's coming in, and if""" start="00:15:23.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""you have some sort of validation that you want to test out.""" start="00:15:28.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""The configuration or the code that I wrote to make this work""" start="00:15:34.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""is a little bit different than just adding an overlay. I'm""" start="00:15:38.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""using this overlay just like with the IPython example, but in""" start="00:15:44.160" video="mainVideo-python" id="subtitle"]]
[[!template text="""this case, when I change code, I have to think about where that""" start="00:15:51.000" video="mainVideo-python" id="subtitle"]]
[[!template text="""code lives, because it's the app that runs the code. So it's""" start="00:15:57.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""in the app context I need to manipulate with the data. If you""" start="00:16:02.160" video="mainVideo-python" id="subtitle"]]
[[!template text="""have started the app from maybe a main function and that""" start="00:16:07.040" video="mainVideo-python" id="subtitle"]]
[[!template text="""module imports namespaces, then you need to, if you want to""" start="00:16:11.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""update a function or something like that, you need to update""" start="00:16:17.880" video="mainVideo-python" id="subtitle"]]
[[!template text="""it in the correct namespace. What I did before in IPython""" start="00:16:22.360" video="mainVideo-python" id="subtitle"]]
[[!template text="""by adding and changing things, everything ends up in the""" start="00:16:26.680" video="mainVideo-python" id="subtitle"]]
[[!template text="""global namespace. But here, if you want the app to actually""" start="00:16:29.920" video="mainVideo-python" id="subtitle"]]
[[!template text="""react to the changes, you need to put it in the right""" start="00:16:34.440" video="mainVideo-python" id="subtitle"]]
[[!template text="""namespace. So that's what I do here. I do some lookups, where""" start="00:16:38.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""is this function, and then I do this reload of this function or""" start="00:16:43.480" video="mainVideo-python" id="subtitle"]]
[[!template text="""module. And when I was developing this, I was thinking, hey,""" start="00:16:49.140" video="mainVideo-python" id="subtitle"]]
[[!template text="""this is really ugly. I'm in this REPL and do some""" start="00:16:54.800" video="mainVideo-python" id="subtitle"]]
[[!template text="""manipulation of the imports and things like that. That""" start="00:16:59.320" video="mainVideo-python" id="subtitle"]]
[[!template text="""didn't feel good. Then I was reminded of the IPython. And""" start="00:17:03.560" video="mainVideo-python" id="subtitle"]]
[[!template text="""IPython has this feature to reload any updated""" start="00:17:09.760" video="mainVideo-python" id="subtitle"]]
[[!template text="""submodules. I was curious how do they do it. I looked in the""" start="00:17:15.520" video="mainVideo-python" id="subtitle"]]
[[!template text="""IPython source code and saw that they also use importlib and""" start="00:17:19.120" video="mainVideo-python" id="subtitle"]]
[[!template text="""reloading of this module. Once I've learned that, then I""" start="00:17:24.080" video="mainVideo-python" id="subtitle"]]
[[!template text="""stopped thinking that my code was hacky. I thought it was""" start="00:17:28.360" video="mainVideo-python" id="subtitle"]]
[[!template text="""good enough at least.""" start="00:17:32.600" video="mainVideo-python" id="subtitle"]]
<div class="transcript-heading">[[!template new="1" text="""Testing with an LLM""" start="00:17:37.160" video="mainVideo-python" id="subtitle"]]</div>[[!template text="""But one thing that has bothered me for a long time is I quite""" start="00:17:37.160" video="mainVideo-python" id="subtitle"]]
[[!template text="""often want to test out and evaluate individual rows that""" start="00:17:45.060" video="mainVideo-python" id="subtitle"]]
[[!template text="""lives in a function. Quite often, this code uses the input""" start="00:17:50.200" video="mainVideo-python" id="subtitle"]]
[[!template text="""to that function like the input parameters. To be able to""" start="00:17:58.560" video="mainVideo-python" id="subtitle"]]
[[!template text="""do that, I need to manually type some fake data and set it to""" start="00:18:02.640" video="mainVideo-python" id="subtitle"]]
[[!template text="""this variable, and then I can evaluate the code. But I think""" start="00:18:07.720" video="mainVideo-python" id="subtitle"]]
[[!template text="""that takes... That slows me down. I was thinking, maybe I can""" start="00:18:12.280" video="mainVideo-python" id="subtitle"]]
[[!template text="""do this in a quicker way, so I have this quicker feedback, so I""" start="00:18:17.780" video="mainVideo-python" id="subtitle"]]
[[!template text="""can run this or evaluate this code much quicker.""" start="00:18:23.440" video="mainVideo-python" id="subtitle"]]
[[!template text="""So my idea was maybe I""" start="00:18:27.934" video="mainVideo-python" id="subtitle"]]
[[!template text="""can use an LLM for this. If I give it the parameters, maybe it""" start="00:18:29.440" video="mainVideo-python" id="subtitle"]]
[[!template text="""can return some random data so I don't have to write it""" start="00:18:35.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""myself. I ended up doing that. I have this source code.""" start="00:18:41.120" video="mainVideo-python" id="subtitle"]]
[[!template text="""I'm loading the REPL with the code. Then I select this""" start="00:18:44.120" video="mainVideo-python" id="subtitle"]]
[[!template text="""function name and the parameters with its data type. I""" start="00:18:50.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""have this prompt that instructs the LLM to come up with fake""" start="00:18:56.720" video="mainVideo-python" id="subtitle"]]
[[!template text="""data based on the tag name and on the data type. And then I can""" start="00:19:02.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""send that to the REPL. I do that with a key command. Then""" start="00:19:06.240" video="mainVideo-python" id="subtitle"]]
[[!template text="""I can proceed by running the code within the function that""" start="00:19:10.100" video="mainVideo-python" id="subtitle"]]
[[!template text="""uses these inputs. This works for all the data types. If""" start="00:19:16.020" video="mainVideo-python" id="subtitle"]]
[[!template text="""there's a custom data type, you need to give the LLM extra""" start="00:19:21.720" video="mainVideo-python" id="subtitle"]]
[[!template text="""context. So that's something to think about. Once it knows""" start="00:19:26.280" video="mainVideo-python" id="subtitle"]]
[[!template text="""the context, it can generate this fake data that very often is""" start="00:19:30.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""good enough just to test out, you know, like I've done here, like""" start="00:19:35.680" video="mainVideo-python" id="subtitle"]]
[[!template text="""string... sorry, list destructuring and parsing and things""" start="00:19:39.840" video="mainVideo-python" id="subtitle"]]
[[!template text="""like that. I think that was all I had, and thank you for""" start="00:19:45.400" video="mainVideo-python" id="subtitle"]]
[[!template text="""listening!""" start="00:19:51.880" video="mainVideo-python" id="subtitle"]]
</div>
Captioner: sachac
Questions or comments? Please e-mail [emacsconf-org-private@gnu.org](mailto:emacsconf-org-private@gnu.org?subject=Comment%20for%20EmacsConf%202023%20python%3A%20Interactive%20Python%20programming%20in%20Emacs)
<!-- End of emacsconf-publish-after-page -->
|