<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>thewadegreen</title>
    <link>https://write.as/thewadegreen/</link>
    <description></description>
    <pubDate>Mon, 31 Aug 2026 09:46:46 +0000</pubDate>
    <item>
      <title>Experimenting with Webservers in Golang</title>
      <link>https://write.as/thewadegreen/experimenting-with-webservers-in-golang?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Recently I started a new golang project focused around testing out the developer experience of building a web application in golang. I have some minimal experience with cli tools and simple utilities in golang, but I wanted to see what it was like to build a robust web application from top to bottom using golang. I have experienc working in Django and Flask, so I&#39;m familiar with some of the benefits and struggles that come from python-based web application development frameworks, and I wanted to see what it would be like if I were to make something similar in golang.&#xA;&#xA;If you&#39;d like to follow along with the code, you can find the repo as it existed at the time of publishing this blog here.&#xA;&#xA;What was the project about?&#xA;&#xA;The application is focused around a chore reminder app; essentially, you can create chores, and then set up reminders, so that you have a running list of what chores need to be done and when. Overall it&#39;s a pretty simple concept, which I felt like would be great for my first foray into learning about the tools available and testing out different ways of implementing things. I knew I would have to set up authentication and authorization, configure a database connection, set up environment variables, and make sure I had a good handle on the build process and learn about any extra stuff that my app would need outside of the compiled binary. My initial goal was to learn about the various pieces I would need and pick a sensible collection of tools and frameworks that would help me to make what I considered to be a reasonable set of building blocks that I could expect myself to be able to continue to build on later and add more features as I get more requests. Because i&#39;m still learning golang, I wanted to try my best to stick with as much as I could get from the standard library; but I also didn&#39;t want to try and build too much by hand, because if I were building this app in a professional setting, I would want to make sure that I am leveraging the right amount of prebuilt tools and frameworks to make the development process easier. From my initial project estimates, I believe I could handle everyhting that this initial project required just from using the standard library, which is awesome; but realistically, I knew that eventually I would become overwhelmed by the tech debt of having to maintain my sub-par implementations of complicated things like middleware and request contexts, and I would eventually want to use some more high-level frameworks. So for this project, I decided to skip over doing everything by hand and look into what tools and frameworks are available in the golang ecosystem.&#xA;&#xA;What tools did you pick?&#xA;&#xA;Coming from python, I have learned to expect to have to use a few different tools. Namely, I knew I would want: a templating engine, for making html templates that can be dynamically generated; some sort of routing backend, to route requests to different request handlers and gracefully handle things like missing routes or authentication walls; and a database connection layer, to manage setting up and connecting to my database. In terms of Python frameworks, I wanted to find one that was more like Flask than Django; I wanted something that was more customizable and had less magic and required me to build more manually, but still handled a lot of the boilerplate and was extensible. I did some initial google searches around frameworks and tools available, and eventually picked a starting stack of tools to use that I ended up being pretty happy with. I&#39;ll give a brief overview of the tools that I chose, and then will discuss how the process went and my overall thoughts and feelings about the project.&#xA;&#xA;I started off by choosing to use Go Chi as the router library. I had found some reddit threads talking about how the overall core functionality of Chi had been rolled into the standard library, and that it wasn&#39;t necessary unless you needed some of the more advanced functionality. I did play around with some of the routing concepts in the standard library, but I had trouble getting them to work initially and I overall liked the ergonomics of how different http methods used different handlers, and so I ended up starting with Chi. I also liked that there was an easy JWT solution that integrated easily with Chi, and since I planned on using OAuth down the road, I figured having a simple pathway to implementing JWTs for authentication was a bonus.&#xA;&#xA;From there, I looked into templating, to make sure that rendering html templates would play nicely with Chi. Again, I found that there are some basic packages built into the standard library for templating, not only for html but also more generally for any kind of text templating. I read about how the html templates worked, but as I was reading some opinions online, I found that Templ was a good choice for html templating because it had better support for template composition. One of my favorite parts of things like React and Vue as frontend frameworks are their focus on building individual components and then putting them together to make more complicated higher order components, and how they have different approaches for things like props and looping. Templ took a bit of getting used to, but I really appreciated that the templ files compile down to go code so that I could easily understand how importing components worked, how building higher order components worked, and the compiler did a great job of letting me know when my templates weren&#39;t being passed the right arguments or if I had misspelled anything.&#xA;&#xA;The last piece of the puzzle that I wanted to start off with was the database connection layer. I had previous experience with writing raw sql into the sql package in the standard library, so I wanted to see what else was out there. When it comes to Python database connection layers, i&#39;m much more of a fan of SQLAlchemy than Django&#39;s ORM; I feel like Django abstracts too much and makes you re-learn a lot about how to compose queries and join tables. I feel like it does add on a lot of convenience methods, but I overall prefer the feeling of building my queries by hand and I like that SQLAlchemy sticks a lot closer to the underlying SQL syntax, whereas Django feels like much more of a layer of abstraction on top of the underlying queries. I settled on trying out GORM for this project, to see where on the spectrum it fell. At first, it felt a lot like Django, where the methods were clunky and building queries felt far removed from the underlying sql. But once I started to wrap my head around the syntax, and I found that there were often a lot of ways to build queries based on what your focus was, it started to feel more and more like SQLAlchemy. I also appreciated the fact that writing raw sql didn&#39;t feel like it was taking me far out of ORM land, and it could still parse my results into a target data type once the query was ran. I also appreciated that the output datatype didn&#39;t have to map to one of the model types that I had previously defined, so I could write a new struct that represented Chores with Chore Reminder information columns joined onto it and use it the same way that I used regular models that I used to define the database tables. In essence, it made me feel like the objects returned from queries that spanned across tables were first-class citizens, which was a refreshing new experience after dealing with the weak types of Python and how much it can be a struggle to enforce types on joined queries.&#xA;&#xA;How did the project go?&#xA;&#xA;Altogether, with Go Chi, Templ, and GORM, there definitely was a bit of a learning curve for understanding how all the pieces fit together. But very quickly it became apparent that all of these libraries prioritized integrating seamlessly with golang and standard library utils, so nothing felt super foreign or super magicky; rather, it felt like I was just building on top of the underlying golang syntax and skipping boilerplate without taking too much away from the experience. Each step of the way, I felt like I was still in complete control of everything, like managing database connections, determining which http methods were allowed, structuring urls, grouping similar views together, and structuring database models. It felt nice that I could separate out all the views so that I knew where handlers would live, but I could still group all the routes together and build my own URLFor function so that I could see the entire URL tree at a glance. It was also nice that all of my helper functions were available inside my templates, my endpoints, and my middleware, and all worked exactly the same so there was a lot less code duplication. There were plenty of opportunities where I felt like I was in complete control and could make my own decisions. For example, I remember thinking, &#34;Oh, I could handle database connections on every endpoint and pass the db object into the request context; or I could handle it in the views; or, if I was really feeling wild, my template components could do their own database calls and render the objects directly, outside of the views&#34;. In frameworks like Django, it&#39;s possible to do all three, but there&#39;s one choice that&#39;s the obvious answer and the other two are made significantly harder; but here, it felt like I was free to mold the application to fit my requirements.&#xA;&#xA;After I got the general models set up and the inital implementation of all the features, I decided to take on authentication and authorization. In frameworks like Django and Flask, there are packages that handle authentication from start to finish; but with my stack, there wasn&#39;t a clear parallel to flasklogin or django&#39;s loginrequired decorators and mixins. As discussed before, I decided to go with the jwt package that integrates with Chi, because it seemed like the smoothest integration based on my previous choices. At first, it seemed like it would be difficult, but after reading through the documentation and testing some things out, I found it to actually be very straightforward. First, you have to set up middleware to check for the JWT in the request. Go Chi doesn&#39;t provide a one-size-fits-all answer, but instead shows you some examples of middleware and then lets you build out what you need. In the documentation for the chi jwt integration, they take over and show you how to implement a simple jwt workflow on top of the sample Chi middleware examples. So although it did require me to know what I wanted the middleware to look like, the overall middleware API was easy to hook into and set up my own checks. Moreover, it gave me the tools I needed to implement more features that I would want, like being able to pass the current user&#39;s ID into the request context automatically so that I can pull it up and use it to filter down any queries. Moreover, it gave me a good understanding of how the middleware worked so that if I wanted to set up further checks, such as limiting some routes to admin-only, implementing email verification before a user can use the portal, or redirecting away from list views if a user doesn&#39;t have anything to display, I could easily set that up myself. So although the barrier to entry was a bit higher than the simple &#34;add one decorator and you&#39;re done&#34; approach of Flask and Django, it meant that I was better equipped to upgrade the middleware later and localize all of those checks to one place instead of using third party libraries for some authentication and authorization but then having to hand-roll some of the other middleware logic.&#xA;&#xA;Once I got a handle on authentication, I explored the process of refactoring the way that I grouped views and structured the code. Up until this point, I had just piled all of my views and templates in one large folder to make it easier to manage imports. However, it made it harder to sort out which routes went with which templates, and which routes still needed to be used or implemented. So I took a stab at breaking up the different groups of routes, and using go packages to contain each logical grouping of routes. One of the unexpected challenges that I ran into was that each go file declares the package that it belongs to at the top of the file, so when breaking the views into new packages, I needed to update the package name; but that also applied to the template files as well, since they compile down to go files when you run templ generate. This challenge did cause a few hiccups for me along the way, but that was mainly reflective of my lack of golang knowledge, not anything related to the tooling. Moreover, because templ files declare their package, and because you can define the names of the template functions using lowercase letters for private functions and uppercase letters for public functions, just like in standard golang, it made it very easy to tell when I had the name of a template wrong or when I failed to update the name of the package, either through my linter or when I tried to run the project for debugging. Overall, this felt like a much safer way to develop; I knew that if my code compiled and ran, it meant that all my go code existed and was being imported properly, but also that all of my template files existed and were being called properly, so I didn&#39;t have any fear that I was misspelling the name of a template or that I had forgotten to put the templates in the right place; the compiler was double-checking my work along the way. Because Python doesn&#39;t have this sort of type and file checking, the only time I have had a similar feeling of safety was with the professional edition of PyCharm that has support for verifying that django templates exist, but even then it&#39;s not perfect and often times a simple config issue can break the whole tooling; whereas here, because it&#39;s based on the core fundamentals of go as a strongly typed language, it&#39;s impossible for my editor to get wrong because the compiler will catch everything.&#xA;&#xA;After that, I added a few Bootstrap modals and put a cap on my initial MVP, and decided to wait for feedback from my one user before circling back to building out more features. When running tests and creating users, I found it a bit tedious to create new users manually in the database, so I did end up adding Cobra for cli commands so that I could run an interactive user create process if I passed an argument to the binary, but with no arguments it just ran the server. I felt like Cobra was a bit overkill when creating one cli command, but as the number of commands would grow, it felt like a good way to keep the commands well organized and document the interfaces with built-in help text as well.&#xA;&#xA;What are your final thoughts on the project and tools?&#xA;&#xA;Overall, I&#39;d say that this initial implementation has been a success, and that I was happy with the choices that I made along the way. Chi felt like it was really simple to learn and understand, and it really encouraged me to think through the steps of what I really wanted when building out features. I appreciated the concepts like route groups and middleware, and the plugins for handling authentication. I also like that the request objects that came through into my handler functions were standard http.Request objects from the standard library, so all the methods of the request like ParseForm() and PostFormValue() that I used when handling post data were helpful to learn and could be used with other frameworks as I learn the landscape. With templ, the transparency of compiling down the templ files into actual go files really helped me to understand how my templates would be processed and used for rendering a response, which was really nice. In Jinja and Django, they try to do things that mimic concepts from the Python standard library, like checking whether something is in a collection or looping over iterables, but there&#39;s always been a layer of haze between the templates you write and the python code that gets executed when rendering the template, so templ was a nice change of pace. I won&#39;t venture to say that I understood all of the go code in the compiled templates, but it was helpful to look into them to see what the output function names were and how the imports were being rendered and the package declarations so that I could get an overall understanding of how the templates should be called by my view functions.&#xA;&#xA;GORM was the one piece that I wasn&#39;t blown away by; although it was relatively easy to use, I did find myself needing to break out of the query building methods and write raw sql once or twice just to get it to work how I wanted. I would imagine that if I were dealing with a large codebase and had to manage migration of multiple models, GORM would feel great because of the built-in migration tools and the fact that the queries evaluate to go structs; however, in a simple toy example like what I have here, it was very tempting to dip back into just using the built in sql module and write and evaluate the queries myself. I think using an ORM to manage data types and db migrations in the long run is a good choice, and I feel like GORM wasn&#39;t bad, but I would want to try some other ORMs before declaring that GORM is a solid choice, as there may be others out there that I prefer. If I were to start a new web server project, I would definitely use Go Chi and Templ again, as I felt like they really made sense as I got the standard patterns, but I would think twice about the database solution that I choose and probably do more research before coming to a final decision on that piece.&#xA;&#xA;If you haven&#39;t tried to build a web server in golang, I highly recommend it! Overall the process was very smooth, and I loved the explicit and typed nature of golang and the fact that it truly forces you to think about all outcomes before telling you that you have something that&#39;s ready to ship. The performance was outstanding, with server response times measured in microseconds with simple get requests and single to double-digit milliseconds when doing db lookups on a sqlite database. Going forward, i&#39;m looking forward to building more complex tools in golang and I don&#39;t think i&#39;d go back to using flask unless there was a specific python library I needed. I could see myself using Django, but only to the point that I decide on a good golang orm; once I pick one I like, I would ditch Django in a heartbeat.&#xA;&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>Recently I started a new golang project focused around testing out the developer experience of building a web application in golang. I have some minimal experience with cli tools and simple utilities in golang, but I wanted to see what it was like to build a robust web application from top to bottom using golang. I have experienc working in Django and Flask, so I&#39;m familiar with some of the benefits and struggles that come from python-based web application development frameworks, and I wanted to see what it would be like if I were to make something similar in golang.</p>

<p>If you&#39;d like to follow along with the code, you can find the repo as it existed at the time of publishing this blog <a href="https://github.com/TrialAndErrror/goDoChores/tree/baa4b4bca718f766b524aa53524e8289049341a5" rel="nofollow">here</a>.</p>

<h2 id="what-was-the-project-about">What was the project about?</h2>

<p>The application is focused around a chore reminder app; essentially, you can create chores, and then set up reminders, so that you have a running list of what chores need to be done and when. Overall it&#39;s a pretty simple concept, which I felt like would be great for my first foray into learning about the tools available and testing out different ways of implementing things. I knew I would have to set up authentication and authorization, configure a database connection, set up environment variables, and make sure I had a good handle on the build process and learn about any extra stuff that my app would need outside of the compiled binary. My initial goal was to learn about the various pieces I would need and pick a sensible collection of tools and frameworks that would help me to make what I considered to be a reasonable set of building blocks that I could expect myself to be able to continue to build on later and add more features as I get more requests. Because i&#39;m still learning golang, I wanted to try my best to stick with as much as I could get from the standard library; but I also didn&#39;t want to try and build too much by hand, because if I were building this app in a professional setting, I would want to make sure that I am leveraging the right amount of prebuilt tools and frameworks to make the development process easier. From my initial project estimates, I believe I could handle everyhting that this initial project required just from using the standard library, which is awesome; but realistically, I knew that eventually I would become overwhelmed by the tech debt of having to maintain my sub-par implementations of complicated things like middleware and request contexts, and I would eventually want to use some more high-level frameworks. So for this project, I decided to skip over doing everything by hand and look into what tools and frameworks are available in the golang ecosystem.</p>

<h2 id="what-tools-did-you-pick">What tools did you pick?</h2>

<p>Coming from python, I have learned to expect to have to use a few different tools. Namely, I knew I would want: a templating engine, for making html templates that can be dynamically generated; some sort of routing backend, to route requests to different request handlers and gracefully handle things like missing routes or authentication walls; and a database connection layer, to manage setting up and connecting to my database. In terms of Python frameworks, I wanted to find one that was more like Flask than Django; I wanted something that was more customizable and had less magic and required me to build more manually, but still handled a lot of the boilerplate and was extensible. I did some initial google searches around frameworks and tools available, and eventually picked a starting stack of tools to use that I ended up being pretty happy with. I&#39;ll give a brief overview of the tools that I chose, and then will discuss how the process went and my overall thoughts and feelings about the project.</p>

<p>I started off by choosing to use Go Chi as the router library. I had found some reddit threads talking about how the overall core functionality of Chi had been rolled into the standard library, and that it wasn&#39;t necessary unless you needed some of the more advanced functionality. I did play around with some of the routing concepts in the standard library, but I had trouble getting them to work initially and I overall liked the ergonomics of how different http methods used different handlers, and so I ended up starting with Chi. I also liked that there was an easy JWT solution that integrated easily with Chi, and since I planned on using OAuth down the road, I figured having a simple pathway to implementing JWTs for authentication was a bonus.</p>

<p>From there, I looked into templating, to make sure that rendering html templates would play nicely with Chi. Again, I found that there are some basic packages built into the standard library for templating, not only for html but also more generally for any kind of text templating. I read about how the html templates worked, but as I was reading some opinions online, I found that Templ was a good choice for html templating because it had better support for template composition. One of my favorite parts of things like React and Vue as frontend frameworks are their focus on building individual components and then putting them together to make more complicated higher order components, and how they have different approaches for things like props and looping. Templ took a bit of getting used to, but I really appreciated that the templ files compile down to go code so that I could easily understand how importing components worked, how building higher order components worked, and the compiler did a great job of letting me know when my templates weren&#39;t being passed the right arguments or if I had misspelled anything.</p>

<p>The last piece of the puzzle that I wanted to start off with was the database connection layer. I had previous experience with writing raw sql into the sql package in the standard library, so I wanted to see what else was out there. When it comes to Python database connection layers, i&#39;m much more of a fan of SQLAlchemy than Django&#39;s ORM; I feel like Django abstracts too much and makes you re-learn a lot about how to compose queries and join tables. I feel like it does add on a lot of convenience methods, but I overall prefer the feeling of building my queries by hand and I like that SQLAlchemy sticks a lot closer to the underlying SQL syntax, whereas Django feels like much more of a layer of abstraction on top of the underlying queries. I settled on trying out GORM for this project, to see where on the spectrum it fell. At first, it felt a lot like Django, where the methods were clunky and building queries felt far removed from the underlying sql. But once I started to wrap my head around the syntax, and I found that there were often a lot of ways to build queries based on what your focus was, it started to feel more and more like SQLAlchemy. I also appreciated the fact that writing raw sql didn&#39;t feel like it was taking me far out of ORM land, and it could still parse my results into a target data type once the query was ran. I also appreciated that the output datatype didn&#39;t have to map to one of the model types that I had previously defined, so I could write a new struct that represented Chores with Chore Reminder information columns joined onto it and use it the same way that I used regular models that I used to define the database tables. In essence, it made me feel like the objects returned from queries that spanned across tables were first-class citizens, which was a refreshing new experience after dealing with the weak types of Python and how much it can be a struggle to enforce types on joined queries.</p>

<h2 id="how-did-the-project-go">How did the project go?</h2>

<p>Altogether, with Go Chi, Templ, and GORM, there definitely was a bit of a learning curve for understanding how all the pieces fit together. But very quickly it became apparent that all of these libraries prioritized integrating seamlessly with golang and standard library utils, so nothing felt super foreign or super magicky; rather, it felt like I was just building on top of the underlying golang syntax and skipping boilerplate without taking too much away from the experience. Each step of the way, I felt like I was still in complete control of everything, like managing database connections, determining which http methods were allowed, structuring urls, grouping similar views together, and structuring database models. It felt nice that I could separate out all the views so that I knew where handlers would live, but I could still group all the routes together and build my own URLFor function so that I could see the entire URL tree at a glance. It was also nice that all of my helper functions were available inside my templates, my endpoints, and my middleware, and all worked exactly the same so there was a lot less code duplication. There were plenty of opportunities where I felt like I was in complete control and could make my own decisions. For example, I remember thinking, “Oh, I could handle database connections on every endpoint and pass the db object into the request context; or I could handle it in the views; or, if I was really feeling wild, my template components could do their own database calls and render the objects directly, outside of the views”. In frameworks like Django, it&#39;s possible to do all three, but there&#39;s one choice that&#39;s the obvious answer and the other two are made significantly harder; but here, it felt like I was free to mold the application to fit my requirements.</p>

<p>After I got the general models set up and the inital implementation of all the features, I decided to take on authentication and authorization. In frameworks like Django and Flask, there are packages that handle authentication from start to finish; but with my stack, there wasn&#39;t a clear parallel to flask<em>login or django&#39;s login</em>required decorators and mixins. As discussed before, I decided to go with the jwt package that integrates with Chi, because it seemed like the smoothest integration based on my previous choices. At first, it seemed like it would be difficult, but after reading through the documentation and testing some things out, I found it to actually be very straightforward. First, you have to set up middleware to check for the JWT in the request. Go Chi doesn&#39;t provide a one-size-fits-all answer, but instead shows you some examples of middleware and then lets you build out what you need. In the documentation for the chi jwt integration, they take over and show you how to implement a simple jwt workflow on top of the sample Chi middleware examples. So although it did require me to know what I wanted the middleware to look like, the overall middleware API was easy to hook into and set up my own checks. Moreover, it gave me the tools I needed to implement more features that I would want, like being able to pass the current user&#39;s ID into the request context automatically so that I can pull it up and use it to filter down any queries. Moreover, it gave me a good understanding of how the middleware worked so that if I wanted to set up further checks, such as limiting some routes to admin-only, implementing email verification before a user can use the portal, or redirecting away from list views if a user doesn&#39;t have anything to display, I could easily set that up myself. So although the barrier to entry was a bit higher than the simple “add one decorator and you&#39;re done” approach of Flask and Django, it meant that I was better equipped to upgrade the middleware later and localize all of those checks to one place instead of using third party libraries for some authentication and authorization but then having to hand-roll some of the other middleware logic.</p>

<p>Once I got a handle on authentication, I explored the process of refactoring the way that I grouped views and structured the code. Up until this point, I had just piled all of my views and templates in one large folder to make it easier to manage imports. However, it made it harder to sort out which routes went with which templates, and which routes still needed to be used or implemented. So I took a stab at breaking up the different groups of routes, and using go packages to contain each logical grouping of routes. One of the unexpected challenges that I ran into was that each go file declares the package that it belongs to at the top of the file, so when breaking the views into new packages, I needed to update the package name; but that also applied to the template files as well, since they compile down to go files when you run templ generate. This challenge did cause a few hiccups for me along the way, but that was mainly reflective of my lack of golang knowledge, not anything related to the tooling. Moreover, because templ files declare their package, and because you can define the names of the template functions using lowercase letters for private functions and uppercase letters for public functions, just like in standard golang, it made it very easy to tell when I had the name of a template wrong or when I failed to update the name of the package, either through my linter or when I tried to run the project for debugging. Overall, this felt like a much safer way to develop; I knew that if my code compiled and ran, it meant that all my go code existed and was being imported properly, but also that all of my template files existed and were being called properly, so I didn&#39;t have any fear that I was misspelling the name of a template or that I had forgotten to put the templates in the right place; the compiler was double-checking my work along the way. Because Python doesn&#39;t have this sort of type and file checking, the only time I have had a similar feeling of safety was with the professional edition of PyCharm that has support for verifying that django templates exist, but even then it&#39;s not perfect and often times a simple config issue can break the whole tooling; whereas here, because it&#39;s based on the core fundamentals of go as a strongly typed language, it&#39;s impossible for my editor to get wrong because the compiler will catch everything.</p>

<p>After that, I added a few Bootstrap modals and put a cap on my initial MVP, and decided to wait for feedback from my one user before circling back to building out more features. When running tests and creating users, I found it a bit tedious to create new users manually in the database, so I did end up adding Cobra for cli commands so that I could run an interactive user create process if I passed an argument to the binary, but with no arguments it just ran the server. I felt like Cobra was a bit overkill when creating one cli command, but as the number of commands would grow, it felt like a good way to keep the commands well organized and document the interfaces with built-in help text as well.</p>

<h2 id="what-are-your-final-thoughts-on-the-project-and-tools">What are your final thoughts on the project and tools?</h2>

<p>Overall, I&#39;d say that this initial implementation has been a success, and that I was happy with the choices that I made along the way. Chi felt like it was really simple to learn and understand, and it really encouraged me to think through the steps of what I really wanted when building out features. I appreciated the concepts like route groups and middleware, and the plugins for handling authentication. I also like that the request objects that came through into my handler functions were standard http.Request objects from the standard library, so all the methods of the request like ParseForm() and PostFormValue() that I used when handling post data were helpful to learn and could be used with other frameworks as I learn the landscape. With templ, the transparency of compiling down the templ files into actual go files really helped me to understand how my templates would be processed and used for rendering a response, which was really nice. In Jinja and Django, they try to do things that mimic concepts from the Python standard library, like checking whether something is in a collection or looping over iterables, but there&#39;s always been a layer of haze between the templates you write and the python code that gets executed when rendering the template, so templ was a nice change of pace. I won&#39;t venture to say that I understood all of the go code in the compiled templates, but it was helpful to look into them to see what the output function names were and how the imports were being rendered and the package declarations so that I could get an overall understanding of how the templates should be called by my view functions.</p>

<p>GORM was the one piece that I wasn&#39;t blown away by; although it was relatively easy to use, I did find myself needing to break out of the query building methods and write raw sql once or twice just to get it to work how I wanted. I would imagine that if I were dealing with a large codebase and had to manage migration of multiple models, GORM would feel great because of the built-in migration tools and the fact that the queries evaluate to go structs; however, in a simple toy example like what I have here, it was very tempting to dip back into just using the built in sql module and write and evaluate the queries myself. I think using an ORM to manage data types and db migrations in the long run is a good choice, and I feel like GORM wasn&#39;t bad, but I would want to try some other ORMs before declaring that GORM is a solid choice, as there may be others out there that I prefer. If I were to start a new web server project, I would definitely use Go Chi and Templ again, as I felt like they really made sense as I got the standard patterns, but I would think twice about the database solution that I choose and probably do more research before coming to a final decision on that piece.</p>

<p>If you haven&#39;t tried to build a web server in golang, I highly recommend it! Overall the process was very smooth, and I loved the explicit and typed nature of golang and the fact that it truly forces you to think about all outcomes before telling you that you have something that&#39;s ready to ship. The performance was outstanding, with server response times measured in microseconds with simple get requests and single to double-digit milliseconds when doing db lookups on a sqlite database. Going forward, i&#39;m looking forward to building more complex tools in golang and I don&#39;t think i&#39;d go back to using flask unless there was a specific python library I needed. I could see myself using Django, but only to the point that I decide on a good golang orm; once I pick one I like, I would ditch Django in a heartbeat.</p>
]]></content:encoded>
      <guid>https://write.as/thewadegreen/experimenting-with-webservers-in-golang</guid>
      <pubDate>Tue, 25 Feb 2025 02:13:35 +0000</pubDate>
    </item>
    <item>
      <title>Choosing a Language</title>
      <link>https://write.as/thewadegreen/choosing-a-language?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[One of the most frequent questions that I find myself asking when starting a new project is which language or framework should I use to make the new project in. This question could probably fill hundreds of books trying to write a complete answer, so this post will be solely focused on some common aspects that I have thought about across multiple projects, and providing some examples of answers that I have come across that worked for me for the projects that I was working on. It&#39;s very likely that you will come to different answers when asking the same questions, due to differences in projects, preferences, and prior experience, so I would encourage you to think back to projects that you have worked on and how you might answer some of these prompts in response to projects you are either planning or have worked on in the past.&#xA;&#xA;With that out of the way, I want to spend time talking about different parts of the following question: which language should I choose for my project?&#xA;&#xA;Note: To help simplify my examples, I will be referencing a Blackjack game project that I worked on in Python, where a user can play Blackjack against the computer and wager credits. I will include links to a YouTube series that I made discussing how the project is implemented; but knowledge of the project details isn&#39;t necessary to read through this post; all you need to know is that it&#39;s a game where you play Blackjack in a terminal and it&#39;s written in Python.&#xA;&#xA;What is the primary functionality of the project that you&#39;re working on?&#xA;&#xA;Often times, a project will start focused around one feature or a core set of features. These core features will often have implementation details that might make the overall project better suited for one language or another. If your project is designed around interactivity within a web browser, it&#39;s likely that JavaScript might be a viable option for a starting point for your project. In comparison, if your project is designed around thousands of parallelized calculations per second, like a graphically rendered physics simulation, you&#39;re likely going to be looking for a language that can give you high performance and with as much bare metal optimization that you can get, which is better accomplished by a lower level language like something in the C family or Rust.&#xA;&#xA;When I was working on my initial implementation of a blackjack game, the core feature was the actual interactive game loop where a player would make decisions based on the game state, and then the application would perform actions based on those choices and simulate the progression of the game state. I chose Python because the overall core logic was very simple and performance was not a top priority; a user would be more than happy waiting up to a second between actions, which meant there was plenty of time for Python to be slow and still achieve the requirements of the project. Python was a good choice for me because it has a very beginner-friendly syntax and would make it very easy for me to develop an initial prototype, and then modify it as I learned more. When the speed of development is more important than the speed of your application at runtime, it tends to be a good choice to pick something with easier syntax to manage even when it comes at a cost of performance. Python is garbage-collected, so it runs slower when running the application, but I was much happier with the speed at which I could write the code, and that far outweighed the performance loss. However, if you were more familiar with a different language, the overall fundamentals were so simple that any language would serve the purpose of running the main game loop, so there&#39;s not much of a strong&#xA;&#xA;What supporting features do you need to support your application?&#xA;&#xA;Once you identify the type of language that suits the core functionality of the project, it can also be helpful to consider the other pieces to the puzzle. Although the overall game loop is very simple and could be written in anything, there were definitely some supporting features that would complement the game loop that are worth keeping in mind when planning out the project. Some languages have a wide ecosystem of libraries that enable them to be more general purpose, where you can write your entire application in one language; whereas others may be hyper-specialized and do one thing well, but require other languages to implement supporting features.&#xA;&#xA;With the Blackjack game, I knew that I would need to implement a feature for storing the amount of credits that a player had, and be able to modify that value between games. I only got as far as implementing a Bank object that would keep track of money, but my plan was to save the money values as a json file that could be saved and read from at will. In the long run, this would be better off managed as a database, which means that I would need to plan on some way to interact with that database and possibly manage it. With Python, I could easily include SQLAlchemy or PyODBC or some other database bridge, which makes this pretty trivial to overcome. However, if I wanted to implement something more complicated, like simultaneous multiplayer against another opponent over the web, I would need to plan ahead for either direct socket connections and management or a webserver to have both players connect to. Both of these things exist in the python ecosystem, as one could use Twisted to manage sockets or Flask to set up a webserver or something like Django with Django Channels to do both at once, but it adds a significant layer of complexity. Moreover, if the plan is to scale to thousands of users, or to have many people sitting at one table from across the world, and the connections get more complicated to manage, it might be worthwhile to consider whether those features might encourage you to start with a different language. With Python, it&#39;s relatively easy to build a client in Python and connect to a server that may be running a different language, which would solve that problem; but then it&#39;s worth deciding whether having two languages to manage is more worthwhile than just doing everything in Python and taking the performance hit. In general, I would say that most modern general-purpose languages will all be able to handle simple projects, but it&#39;s worth it to spend some time considering which supporting features are important and see if there are any features that will be important enough to dictate the choice of language.&#xA;&#xA;What languages are you comfortable with?&#xA;&#xA;I can&#39;t stress enough how much of a benefit it can be to work in a language that you&#39;re comfortable in and have experience working in. Most competent developers can learn while they work on a project, and diving in head-first can be a great way to learn; but the challenge is being able to predict the footguns that you will come across in advance and plan for building your project in a way that prepares you to avoid them. To me, there&#39;s nothing more frustrating than getting halfway to an MVP only to find out that the fundamental database structure just won&#39;t work and the way that I&#39;m implementing business logic is too tightly coupled with the framework code, and now I&#39;m running into circular import errors and I have to rip out half the project and refactor so that I can resolve that issue before I can even tackle one more feature.&#xA;&#xA;One example I&#39;ve run into many times is setting up a database connection reference object when making a Flask project. When initiating the Flask app, you need to initialize the database connection with the app, but you also need to import the models and the routes so that the database is aware of the db models and knows what routes you have in order to know how to redirect traffic. However, your routes usually have some logic that will touch the database, which means you need to import the db object inside your routes; but most simple flask tutorials create the db object in the file where they&#39;re defining the flask app object, and since you need to import your routes when instantiating the flask app, you end up with a circular import error. For simple one-file apps, this isn&#39;t much of a problem, because you can define the db, the app, and the routes all in one file; but when it gets complicated (as all apps do), you&#39;re going to want to break up the routes and the app into separate files, and if you&#39;re using a database then you will inevitably have to deal with the circular imports that these three things create. I personally handle this issue by using the extensions file pattern; create a file called extensions.py, and set up an object in that file that can initialize my db with the app, and then import from that file when I define my app and when I define my routes; that way, my routes and my main file are both importing from extensions and there&#39;s no circular imports because extensions doesn&#39;t import from those files. It took me a while to get this pattern down, but now that i&#39;m aware of it, I always set up new applications with this pattern in mind, and I never run into this fundamental issue anymore; but if I were new to flask, this circular import issue could set me back hours, or even days.&#xA;&#xA;These pivot points can be frustrating and the impact to momentum that they can cause can really bring down the enjoyment I find in a project and the motivation that I have to keep working on it; in my hobby projects, this usually marks a time where I put them to the side and start working on something else. If it&#39;s a work project, it can be very disheartening to go to the boss and tell them you need a few weeks just to untangle the mess that you&#39;re in, and for some projects that can be the end of the road. So overall, if you&#39;re familiar with a language or a framework, it could weigh heavily in the decision of which language to use.&#xA;&#xA;Is there anything already built in a particular language?&#xA;&#xA;One of the most important lessons that I have learned along the way is that less code is usually better; the less code you have to write, the less you have to maintain, the easier the project is. If you have a really performant application, the best way to optimize performance would be to write it in Assembly; but if you choose C instead, you can benefit from all the functionality and convenience features that C provides that you might otherwise have to write yourself. Better yet, if you choose a language like Rust, and you get a good handle on lifetimes and the types involved, you can save a whole lot of time by relying on the borrow checker and only manually manage memory in unsafe rust when you have to, which would exponentially save time. But this isn&#39;t just a factor for managing memory and dealing with performance concerns; if you want to write something that will require a web server and a database, languages like Python and Golang have a rich ecosystem of libraries to perform those tasks; Golang even has everything you might need built into the standard library. If you&#39;re looking to do something with game development, you can get away with using PyGame in Python, but you&#39;re likely going to be better suited working in a different language like C++ or C# to get access to Unity, or something like Godot where it is primarily focused around game development. Looking for specific aspects that you don&#39;t have to recreate or reimplement can get you a long way down the process of getting off the ground with a new project, and take a lot of the task off your shoulders if you can learn to use it.&#xA;&#xA;What are other people using to build this sort of project?&#xA;&#xA;Looking for other examples of projects that are along the same lines as your project can also help inform the language you choose. Most projects could, theoretically, be written in any language; but usually, on average, people tend to gravitate towards working in the right language for the job. If a language is not suited well for a task, then on average, a higher percentage of people who attempt the project will fail before they have anything to share or show for their work; therefore, looking for a language where a large number of projects were finished in that language can give some indicator to which languages are better suited for your project. Also, if you are able to find examples where someone else attempted something similar to what you are doing, it can give you a good starting point or example of implementation that can help jump-start your work and give you something to work from. Most project ideas are not entirely new, and end up being either an improvement on something that already exists or a combination of multiple tools into a new combined tool that can be useful in different situations or just more helpful than the existing tools. You can leverage that fact by finding the work that already exists that you can use to build off of in order to make something even better.&#xA;&#xA;Overall, the question about what language to use can be very complicated, and I&#39;ve only scratched the surface of the question by sharing some common thoughts that go through my head when considering this question. However, I also want to stress that it&#39;s much more important to start working on the project than to get too caught up planning and preparing for the project. It&#39;s very likely that the best tool for the job is something that you haven&#39;t discovered yet, or that doesn&#39;t exist yet, and you will always have to settle for a sub-optimal tool based on knowledge and time constraints; so don&#39;t get too caught up trying to pick the &#34;best&#34; or &#34;correct&#34; language. I hope this discussion just gives you some food for thought when embarking on your next new project, to help speed up the process of deciding what language to use so that you can get to working on the project faster and get to finishing faster. Best of luck!&#xA;&#xA;Link to Blackjack game videos]]&gt;</description>
      <content:encoded><![CDATA[<p>One of the most frequent questions that I find myself asking when starting a new project is which language or framework should I use to make the new project in. This question could probably fill hundreds of books trying to write a complete answer, so this post will be solely focused on some common aspects that I have thought about across multiple projects, and providing some examples of answers that I have come across that worked for me for the projects that I was working on. It&#39;s very likely that you will come to different answers when asking the same questions, due to differences in projects, preferences, and prior experience, so I would encourage you to think back to projects that you have worked on and how you might answer some of these prompts in response to projects you are either planning or have worked on in the past.</p>

<p>With that out of the way, I want to spend time talking about different parts of the following question: which language should I choose for my project?</p>

<p>Note: To help simplify my examples, I will be referencing a Blackjack game project that I worked on in Python, where a user can play Blackjack against the computer and wager credits. I will include links to a YouTube series that I made discussing how the project is implemented; but knowledge of the project details isn&#39;t necessary to read through this post; all you need to know is that it&#39;s a game where you play Blackjack in a terminal and it&#39;s written in Python.</p>

<h2 id="what-is-the-primary-functionality-of-the-project-that-you-re-working-on">What is the primary functionality of the project that you&#39;re working on?</h2>

<p>Often times, a project will start focused around one feature or a core set of features. These core features will often have implementation details that might make the overall project better suited for one language or another. If your project is designed around interactivity within a web browser, it&#39;s likely that JavaScript might be a viable option for a starting point for your project. In comparison, if your project is designed around thousands of parallelized calculations per second, like a graphically rendered physics simulation, you&#39;re likely going to be looking for a language that can give you high performance and with as much bare metal optimization that you can get, which is better accomplished by a lower level language like something in the C family or Rust.</p>

<p>When I was working on my initial implementation of a blackjack game, the core feature was the actual interactive game loop where a player would make decisions based on the game state, and then the application would perform actions based on those choices and simulate the progression of the game state. I chose Python because the overall core logic was very simple and performance was not a top priority; a user would be more than happy waiting up to a second between actions, which meant there was plenty of time for Python to be slow and still achieve the requirements of the project. Python was a good choice for me because it has a very beginner-friendly syntax and would make it very easy for me to develop an initial prototype, and then modify it as I learned more. When the speed of development is more important than the speed of your application at runtime, it tends to be a good choice to pick something with easier syntax to manage even when it comes at a cost of performance. Python is garbage-collected, so it runs slower when running the application, but I was much happier with the speed at which I could write the code, and that far outweighed the performance loss. However, if you were more familiar with a different language, the overall fundamentals were so simple that any language would serve the purpose of running the main game loop, so there&#39;s not much of a strong</p>

<h2 id="what-supporting-features-do-you-need-to-support-your-application">What supporting features do you need to support your application?</h2>

<p>Once you identify the type of language that suits the core functionality of the project, it can also be helpful to consider the other pieces to the puzzle. Although the overall game loop is very simple and could be written in anything, there were definitely some supporting features that would complement the game loop that are worth keeping in mind when planning out the project. Some languages have a wide ecosystem of libraries that enable them to be more general purpose, where you can write your entire application in one language; whereas others may be hyper-specialized and do one thing well, but require other languages to implement supporting features.</p>

<p>With the Blackjack game, I knew that I would need to implement a feature for storing the amount of credits that a player had, and be able to modify that value between games. I only got as far as implementing a Bank object that would keep track of money, but my plan was to save the money values as a json file that could be saved and read from at will. In the long run, this would be better off managed as a database, which means that I would need to plan on some way to interact with that database and possibly manage it. With Python, I could easily include SQLAlchemy or PyODBC or some other database bridge, which makes this pretty trivial to overcome. However, if I wanted to implement something more complicated, like simultaneous multiplayer against another opponent over the web, I would need to plan ahead for either direct socket connections and management or a webserver to have both players connect to. Both of these things exist in the python ecosystem, as one could use Twisted to manage sockets or Flask to set up a webserver or something like Django with Django Channels to do both at once, but it adds a significant layer of complexity. Moreover, if the plan is to scale to thousands of users, or to have many people sitting at one table from across the world, and the connections get more complicated to manage, it might be worthwhile to consider whether those features might encourage you to start with a different language. With Python, it&#39;s relatively easy to build a client in Python and connect to a server that may be running a different language, which would solve that problem; but then it&#39;s worth deciding whether having two languages to manage is more worthwhile than just doing everything in Python and taking the performance hit. In general, I would say that most modern general-purpose languages will all be able to handle simple projects, but it&#39;s worth it to spend some time considering which supporting features are important and see if there are any features that will be important enough to dictate the choice of language.</p>

<h2 id="what-languages-are-you-comfortable-with">What languages are you comfortable with?</h2>

<p>I can&#39;t stress enough how much of a benefit it can be to work in a language that you&#39;re comfortable in and have experience working in. Most competent developers can learn while they work on a project, and diving in head-first can be a great way to learn; but the challenge is being able to predict the footguns that you will come across in advance and plan for building your project in a way that prepares you to avoid them. To me, there&#39;s nothing more frustrating than getting halfway to an MVP only to find out that the fundamental database structure just won&#39;t work and the way that I&#39;m implementing business logic is too tightly coupled with the framework code, and now I&#39;m running into circular import errors and I have to rip out half the project and refactor so that I can resolve that issue before I can even tackle one more feature.</p>

<p>One example I&#39;ve run into many times is setting up a database connection reference object when making a Flask project. When initiating the Flask app, you need to initialize the database connection with the app, but you also need to import the models and the routes so that the database is aware of the db models and knows what routes you have in order to know how to redirect traffic. However, your routes usually have some logic that will touch the database, which means you need to import the db object inside your routes; but most simple flask tutorials create the db object in the file where they&#39;re defining the flask app object, and since you need to import your routes when instantiating the flask app, you end up with a circular import error. For simple one-file apps, this isn&#39;t much of a problem, because you can define the db, the app, and the routes all in one file; but when it gets complicated (as all apps do), you&#39;re going to want to break up the routes and the app into separate files, and if you&#39;re using a database then you will inevitably have to deal with the circular imports that these three things create. I personally handle this issue by using the extensions file pattern; create a file called extensions.py, and set up an object in that file that can initialize my db with the app, and then import from that file when I define my app and when I define my routes; that way, my routes and my main file are both importing from extensions and there&#39;s no circular imports because extensions doesn&#39;t import from those files. It took me a while to get this pattern down, but now that i&#39;m aware of it, I always set up new applications with this pattern in mind, and I never run into this fundamental issue anymore; but if I were new to flask, this circular import issue could set me back hours, or even days.</p>

<p>These pivot points can be frustrating and the impact to momentum that they can cause can really bring down the enjoyment I find in a project and the motivation that I have to keep working on it; in my hobby projects, this usually marks a time where I put them to the side and start working on something else. If it&#39;s a work project, it can be very disheartening to go to the boss and tell them you need a few weeks just to untangle the mess that you&#39;re in, and for some projects that can be the end of the road. So overall, if you&#39;re familiar with a language or a framework, it could weigh heavily in the decision of which language to use.</p>

<h2 id="is-there-anything-already-built-in-a-particular-language">Is there anything already built in a particular language?</h2>

<p>One of the most important lessons that I have learned along the way is that less code is usually better; the less code you have to write, the less you have to maintain, the easier the project is. If you have a really performant application, the best way to optimize performance would be to write it in Assembly; but if you choose C instead, you can benefit from all the functionality and convenience features that C provides that you might otherwise have to write yourself. Better yet, if you choose a language like Rust, and you get a good handle on lifetimes and the types involved, you can save a whole lot of time by relying on the borrow checker and only manually manage memory in unsafe rust when you have to, which would exponentially save time. But this isn&#39;t just a factor for managing memory and dealing with performance concerns; if you want to write something that will require a web server and a database, languages like Python and Golang have a rich ecosystem of libraries to perform those tasks; Golang even has everything you might need built into the standard library. If you&#39;re looking to do something with game development, you can get away with using PyGame in Python, but you&#39;re likely going to be better suited working in a different language like C++ or C# to get access to Unity, or something like Godot where it is primarily focused around game development. Looking for specific aspects that you don&#39;t have to recreate or reimplement can get you a long way down the process of getting off the ground with a new project, and take a lot of the task off your shoulders if you can learn to use it.</p>

<h2 id="what-are-other-people-using-to-build-this-sort-of-project">What are other people using to build this sort of project?</h2>

<p>Looking for other examples of projects that are along the same lines as your project can also help inform the language you choose. Most projects could, theoretically, be written in any language; but usually, on average, people tend to gravitate towards working in the right language for the job. If a language is not suited well for a task, then on average, a higher percentage of people who attempt the project will fail before they have anything to share or show for their work; therefore, looking for a language where a large number of projects were finished in that language can give some indicator to which languages are better suited for your project. Also, if you are able to find examples where someone else attempted something similar to what you are doing, it can give you a good starting point or example of implementation that can help jump-start your work and give you something to work from. Most project ideas are not entirely new, and end up being either an improvement on something that already exists or a combination of multiple tools into a new combined tool that can be useful in different situations or just more helpful than the existing tools. You can leverage that fact by finding the work that already exists that you can use to build off of in order to make something even better.</p>

<p>Overall, the question about what language to use can be very complicated, and I&#39;ve only scratched the surface of the question by sharing some common thoughts that go through my head when considering this question. However, I also want to stress that it&#39;s much more important to start working on the project than to get too caught up planning and preparing for the project. It&#39;s very likely that the best tool for the job is something that you haven&#39;t discovered yet, or that doesn&#39;t exist yet, and you will always have to settle for a sub-optimal tool based on knowledge and time constraints; so don&#39;t get too caught up trying to pick the “best” or “correct” language. I hope this discussion just gives you some food for thought when embarking on your next new project, to help speed up the process of deciding what language to use so that you can get to working on the project faster and get to finishing faster. Best of luck!</p>

<p><a href="https://www.youtube.com/playlist?list=PLKq1ewaKjz1cGcdS42AaObyPJInEZ8CUB" rel="nofollow">Link to Blackjack game videos</a></p>
]]></content:encoded>
      <guid>https://write.as/thewadegreen/choosing-a-language</guid>
      <pubDate>Thu, 16 Jan 2025 05:12:56 +0000</pubDate>
    </item>
    <item>
      <title>Every Journey Begins with a Single Step</title>
      <link>https://write.as/thewadegreen/dont-quit-your-day-job?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[One of the biggest factors in finding success in my career has been finding a job where I get to do something that I care about and something that I enjoy at work every day. It was very challenging for me to find the career that I am in today, and it took a lot of trial and errror to figure out what I was interested in and the types of jobs that suited me.&#xA;&#xA;The key to finding a career that I was satisfied with was figuring out what it was that I enjoyed, and then finding a way to make money doing the thing that I enjoyed. Fortunately for me, these days programming and web development are careers that are in demand and there are a lot of companies that are actively hiring for roles in the industry. However, it&#39;s can be a challenge getting into a profession or a field that you have no experience in. For me, before working as a software engineer, I had worked as an associate teacher, a doordash delivery driver, an externship coordinator, and a paralegal, but I had no experience with technology or programming. I was fortunate enough to get a contract job working at Facebook on a policy team, but that was more of a role in the legal field and didn&#39;t give me any practical experience in the tech sector. So once I decided that I wanted to pursue a career in technology, I had to figure out how I was going to get experience in the field without having any qualifications to actually work in the field.&#xA;&#xA;As I discussed in my previous post, it is a lot easier in the present day to find learning resources and ways to try out learning programming and technology now than it ever has been in the past; the barrier to entry to start learning programming and web development has never been lower. While I was working as a paralegal, I purchased an online course, and I was working on that course for a few hours during the week and on the weekends, whenever I had free time. This course taught me the fundamentals of Python development, which helped to walk me through the basics of programming and problem solving using computers along the way. Finding access to a good basic introductory course can go a long way in teaching you not only the language-specific information, but also great context around the problems you will be solving and general problem solving skills. Once I made it through my course, and knew that I had a solid interest in programming and technology, I knew the next step would be to try and apply my knowledge and find ways to get experience and demonstrate my knowledge to others.&#xA;&#xA;At first, I was drawn to coding challenges and exercises. I found a few online resources that had individual puzzles and tests where I could spend some time on the problems provided, and gain a certificate or proof that I had solved these problems. I feel like I was initially drawn to these because they were short and gave me pretty instantaneous feedback; either I solved the puzzle, and I would feel proud of my accomplishment and had something to show for it, or I would fail to solve the puzzle, and I would look to more resources and try to learn more about the tools that I should be familiar with and patterns to solve similar problems in the future. I found a few courses and platforms where I could answer some general questions about Python and programming in general, and in exchange I would get a certificate that I could put on my LinkedIn that made me feel like I had accomplished something. But after a few months of having these certifications, I expected that employers would come flocking to me with job offers and wanting me to apply my basic python competency to their problems. Fortunately for me, they didn&#39;t, because I was woefully unprepared to actually take a job at that point.&#xA;&#xA;The time that I spent doing exercises, puzzles, and certifications wasn&#39;t wasted, as it gave me a way to benchmark my specific python knowledge and know whether I was truly absorbing and memorizing the concepts that I was learning. But exercises, puzzles, and certifications don&#39;t tend to have much actual bearing on one&#39;s ability to perform a job and to be responsible for creating and maintaining long-lasting code out in the wild. Being able to write algorithms or unlock the key to a puzzle in a controlled environment can help sharpen your problem-solving tools, but it will not enable one to solve problems that real clients are actually facing in their day-to-day lives. For example, I have experienced in the past an issue where a client came to me and said that they wanted to implement an autocomplete functionality instead of a dropdown menu for a field on a form. Puzzles can help with knowing the syntax of javascript and python to know how to build the particular ui component on the frontend and the endpoint on the backend, and how to make those things talk to each other. But along the way, there will be many choices that have to be made, and it is through those choices that your abilities as a developer will be tested. Should we use a javascript framework on the frontend for this? Will jQuery be sufficient? Or does this require a custom-built component that you create and maintain yourself through raw HTML or WebComponents? Will you need live updates through WebSockets or live polling, to capture new options as they come in? Will we need authentication in this round trip to get autocomplete suggestions? Can we handle this through just basic HTTP Auth, or do we need something like a JWT? Can we include relative links in the content we send back, or is it being rendered locally in the browser where we need absolute links? What happens if a choice is valid when it&#39;s provided, but becomes invalid before the form is submitted? What if the choices need to be dynamically determined based on other form fields on the page, how can we handle that? And given all of these concerns, how do we build this UI component and endpoint in a way that is modular and future-proof so that we can continue to work on it a year from now when the requirements have completely changed? Working on puzzles can help with small pieces in the puzzle, but in order to be a professional developer, you have to be able to identify all of these issues, discuss the pros and cons of various approaches, and make a decision on what to do for each of these when you&#39;re either on your own or your team members cannot provide answers. If you spend all of your time solving self-contained puzzles, then you will find it very challenging when you actually have to face these sorts of situations.&#xA;&#xA;So after getting some practice with puzzles, I was fortunate enough to realize that they weren&#39;t enough to prepare me for real work, and that I would have to start building things myself and learn by doing. Some developers may be intimidated by the thought of taking on projects themselves, or may not have ideas on what to work on. For me, it was easy, because I had a whole laundry list of projects that I wanted to work on; a card game simulator for a fun card game I was working on, a blackjack game, a finance app for tracking monthly bills, and a bible reader app for my wife to do her reading on. I had plenty of other ideas that I never started on, because I tend to love the process of brainstorming but fall short when it comes to execution. But when I had my first set of ideas, I started to just build them from the ground up. Initially, they were terrible; I recall a few months into my card game simulator telling my friends about this 8000 line monstrosity that I was maintaining and how impressive it was. Spoiler alert: it wasn&#39;t impressive, it was a jumbled pile of spaghetti that even I couldn&#39;t understand. But after a few months of developing and reaching a spot where I couldn&#39;t tell where one class ended and another one began, and my middle finger was getting fatigued from scrolling through files that were more than 1000 lines long, I learned a lot of valuable lessons. The first lesson was really just that less code is usually better than more code; fewer lines written means fewer lines you have to maintain, and fewer lines to read when you completely forget what a component does. After that, I learned that spending a whole bunch of time writing something from scratch was more likely to be more of a hinderance than a help. Not only is it duplicitous to remake something that already exists, the person who spent time building it probably has considered a lot of problems and edge cases that you might miss, and has likely already accounted for those. When attempting to learn how something works, the best way to do so is to rebuild it from scracth; but when trying to build something that you want to work, and work well, the best way is to find somehting that already does what you want safely and efficiently, or find multiple things that you can just be responsible for tying together in a way that makes sense and achieves your goal.&#xA;&#xA;So after about 6 months of fighting with this initial implementation, I abandoned ship with a completely unfinished project and moved on to another way of implementing it altogether. I had learned so much about the project and what I wanted to do with it along the way, and realized that I was not likely to end up with a finished product that I was happy with if I kept going down this route. I ended up stopping with that project and moving on to another project that I was more confident on; I would later try 3 or 4 different implementations of that same card game project, and am still working on a new version of it to this day. But I learned so much about how to manage complexity and how to visualize a project from start to finish and how to avoid some of the circular rabbit holes that I fell down along the way. I then moved on to my finance app, starting with learning Django so that I could experience a bit of learning web development and working in a different framework. Previously, I had been working mostly in PyQt5 desktop apps, because I personally was not a fan of web applications; but experiencing how Django worked opened my eyes to the world of web development. I had not previously understood that web applications are just a way to distribute an application quickly and more efficiently to a wider audience. One of the challenges I had faced with trying to build the finance app in PyQt5 before was that, when I had a working version of the software, it was hard to distribute. I didn&#39;t know anyone else who used linux like I did, and so I had to compile windows executables in my dual-booted Windows installation. But because I made my own binaries, they were either not signed or self-signed, and so when I shared it with my friends and family, their computer would either treat it like a virus or refuse to run it. My father asked me how he could run it on his iPad, and my mother asked how to run it on her macbook, and I had to tell both of them that I simply could not make a working copy for them because I didn&#39;t have apple hardware to compile it on. This was a major frustration for me, and it motivated me to learn more about distribution of python applications, which drove me to learning more and more about web development. Initially, I had been hesitant to get into web development because I had imagined that there wasn&#39;t much to it except for ui design and pixel pushing, but after learning about how it can be a great option for cross-compatibility across devices, I was eager to learn more. I had never really given web applications much credit and had always assumed desktop applications were better, but I was finally learning the hard way that it can be so much easier to build an audience and a large userbase if your application is easy to access, and nothing is easier to access than the web.&#xA;&#xA;My research drove me to learning about Flask and Django, and after a bit of experimentation, I started working on reimplementing the finance app in Django. Finally, I was able to make an application that would be easy to access for anyone, and I could still use python to do it so that it was less of a barrier to entry. But the challenges were now twofold; I needed to learn about the Django framework and how it worked while also learning about general web development and how the internet actually works. And with web development, there exists a lot more risk of failure; security concerns can lead to massive data leaks and hostile takeovers of servers, and the threat of unauthorized access is always present if your service is always exposed to the internet. The challenge initially seemed daunting, but I was confident from working on my previous projects and felt prepared to try and tackle the learning curve. It took a while to adapt to a whole new framework, and although the opinionated nature of Django helped guide some of my decisions, there was a lot of magic and things that happened behind the scenes that I was unaware of and had no idea how to fix or change. I managed to get a very basic implementation of the finance app created; it didn&#39;t look pretty, but it worked, and I was super proud of it. It came with all sorts of new challenges and road bumps that I had to work through, and I ended up making some terrible choices. I couldn&#39;t figure out how to make charts in javascript, so I rendered them using plotly on the backend and converted them to base64 encoding before shoving them into my templates to render. I couldn&#39;t figure out how to connect in third party libraries, so I set up a form to fill out for manually entering in every single transaction you make. I couldn&#39;t figure out bootstrap, so I ended up styling things manually, guessing and checking by loading it up on different screen sizes and just moving on when things weren&#39;t mangled or falling off the page. There were all sorts of usability issues and inconveniences, but it worked, and I learned so much about taking a project from start to finish and actually completing something for once. One of the hardest things to do with a project is decide when it&#39;s done, and I learned about the value of making tickets and saving notes for the future but setting hard limits on the features I would implement so that there would be a clear end to the project.&#xA;&#xA;Once the project was complete, the next step was showing it to people and being ready for open and honest feedback. Some people complained that they couldn&#39;t log in, or they couldn&#39;t get it to work, or they didn&#39;t understand it. Some people would make feature requests that I already had in my backlog, and I had to contain the frustration that I had for not implementing it already and impressing them, and just remain patient. But one of my friends was so impressed by that project, he asked if I would be able to build something for his company, and that was how I was able to secure my first freelance contract. It took a few months of discussion, and I had to train a lot to get my skills up to par where I felt they needed to be to securely and reliably deploy an app again, but it was that experience of going from start to finish all by myself on that application that gave me the confidence to say that I could do it for someone else. I had worked on other projects along the way, and had other experience with python and django, but it was the act of completing something from start to finish with no guidance that was able to teach me enough about the skills required and enable me to know when I would be ready to start working on a project for someone else. I negotiated a price that reflected my lower skill level, and it still took me at least double the time estimate that I had initially proposed, but I was able to take the skills that I learned on that first finance app and put them to use on this new freelance project. I definitely still wasn&#39;t skilled enough to feel like a professional developer after completing that freelance project, but it gave me a great experience of having to go through another project from start to finish, but this time one where someone else made the requirements and my work was subject to the approval of someone else. This was a wholly new experience, and it taught me the value of writing tests and taking care with the code that I was writing, as well as being ready to ditch anything at a moment&#39;s notice and being prepared for the real world of changing requirements. I was completely overwhelmed during this project, and so I was very thankful that the project was for a friend and that they were forgiving of the mistakes that I made and that they were prepared to be patient with me. By the end of the process, I felt a lot more prepared for my next task and was eager to take on more projects from outsiders.&#xA;&#xA;I ended up finding another freelance client through another friend, but the client was not a friend and they had a very limited budget and a very pressing need for the project. From my experience with how much the first project dragged on, I learned the value of using pre-established frameworks and keeping the code as simple and flexible as possible to keep up with changes in requirements. I made sure to scope the second project very clearly and I learned how to communicate with the client better so that I could get a better handle on time estimates and set better expectations about what features would and would not be included in the final product. This project went a lot smoother and I was able to get it done a lot faster than the first, and although the tail end of the development process still took a while to go from basic implementation to finished product, there were a lot less meetings required and a lot fewer roadblocks along the way. My bold choice to work in a whole new framework, Wagtail, did mean that the development process was smoother, but it did mean there was a lot more learning to do on my end to bridge the gap of my knowledge between basic Django development and the Page-Model based approach of Wagtail. In hindsight, it probably hindered my development process unnecessarily to be trying to learn a new framework while I was still early on in my development experience, but I wouldn&#39;t have learned that if I hadn&#39;t chosen to take that risk and use the framework for this project. I did expect that it could get challenging, so I estimated my hours and billed a flat rate based on the expected number of hours, so the client didn&#39;t have to pay for the time that I spent learning the framework, but it was me who paid the cost for the extra time investment that was required to get the app to where it needed to be to call it finished. Nevertheless, I didn&#39;t take the project for the money; instead, I was still seeking more experience and the value of learning through the development process far outweighed the monetary value of the contract. I was still deeply in the initial stages of my development experience, and there was no real substitute for real-world experience, so I would have likely taken these clients on for free if they couldn&#39;t afford to compensate me for my time. Luckily for me, they were willing to pay, and they both ended up very satisfied with the work that I did.&#xA;&#xA;Around the time that I was deep in working on the second client project, I was attending a Django convention online for the first time. I had never been to any convention, much less a software one, but I thought it would be a great way to learn more about Django and web development and keep up with the trends, as well as maybe meet some friends to work on projects together with. The format of an online conference was a bit of a challenge, but I managed to get through it and meet some people. I was thankful for the time that I had spent working on those projects, because it gave me a lot to talk about and to relate to people over while at the conference. I even unknowingly ranted and raved about a library I had found, Django Simple History, to someone who later revealed to me that he was a core maintainer on the project, only for me to be embarrassed to not recognize him. Being surrounded by people who all shared the interest of Django and web development was such a great experience, and having my work be validated by people who had been doing this sort of thing for years really made me feel like my work was meaningful and that I was on the right path. To make a long story short, one person I met at that conference would eventually end up connecting me with an interview that, about 9 months after the conference, would lead to me getting my first job as a software engineer. I didn&#39;t go to the conference to find a job, but I had some idea that it was possible that making connections in the field would eventually give me a leg up into the job market, and it just so happened that I was in the right place at the right time and met the right person to kick start my career.&#xA;&#xA;So what&#39;s the point of telling this long and convoluted story about how I got my first job? Well, it&#39;s the story of how I made it from nothing to get to the point of starting my career off in a field that I love and where I am happy to work every day. I didn&#39;t know that the conference would help me get the job; I didn&#39;t know that the second freelance client would make me confident enough to attend the conference; I didn&#39;t know that the first freelance client would make me confident enough to seek out another project; I didn&#39;t know that my Django finance app would impress someone enough for them to become my first client; I didn&#39;t know that my card game app would leave me so frustrated that I would try out web development; I didn&#39;t know that puzzles and coding challenges would leave me hungry for more serious experience; and I didn&#39;t know that completing my online python course would get me interested in online Python puzzles. We don&#39;t know what path we will be led down until we start our journey. But what I did know is that, after my python course and playing around with some scripts, I was interested in python and wanted to learn more, and so I kept trying to find the next step and the next thing to work on and spent all my effort and time that I could afford pursing that interest, which turned into a hobby, which turned into a passion, which turned into a career.&#xA;&#xA;So for anyone reading this who thinks they may be somewhat interested in programming, web development, tech, or anything, I would encourage you to try and find the next small step that you can take and put as much effort you can towards that one step, because although each phase along the way may just seem convenient, or like a simple small thing that you can do now, you never know where it may lead. And if you&#39;re fortunate enough, it might lead you in the direction that you want to be going.&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>One of the biggest factors in finding success in my career has been finding a job where I get to do something that I care about and something that I enjoy at work every day. It was very challenging for me to find the career that I am in today, and it took a lot of trial and errror to figure out what I was interested in and the types of jobs that suited me.</p>

<p>The key to finding a career that I was satisfied with was figuring out what it was that I enjoyed, and then finding a way to make money doing the thing that I enjoyed. Fortunately for me, these days programming and web development are careers that are in demand and there are a lot of companies that are actively hiring for roles in the industry. However, it&#39;s can be a challenge getting into a profession or a field that you have no experience in. For me, before working as a software engineer, I had worked as an associate teacher, a doordash delivery driver, an externship coordinator, and a paralegal, but I had no experience with technology or programming. I was fortunate enough to get a contract job working at Facebook on a policy team, but that was more of a role in the legal field and didn&#39;t give me any practical experience in the tech sector. So once I decided that I wanted to pursue a career in technology, I had to figure out how I was going to get experience in the field without having any qualifications to actually work in the field.</p>

<p>As I discussed in my previous post, it is a lot easier in the present day to find learning resources and ways to try out learning programming and technology now than it ever has been in the past; the barrier to entry to start learning programming and web development has never been lower. While I was working as a paralegal, I purchased an online course, and I was working on that course for a few hours during the week and on the weekends, whenever I had free time. This course taught me the fundamentals of Python development, which helped to walk me through the basics of programming and problem solving using computers along the way. Finding access to a good basic introductory course can go a long way in teaching you not only the language-specific information, but also great context around the problems you will be solving and general problem solving skills. Once I made it through my course, and knew that I had a solid interest in programming and technology, I knew the next step would be to try and apply my knowledge and find ways to get experience and demonstrate my knowledge to others.</p>

<p>At first, I was drawn to coding challenges and exercises. I found a few online resources that had individual puzzles and tests where I could spend some time on the problems provided, and gain a certificate or proof that I had solved these problems. I feel like I was initially drawn to these because they were short and gave me pretty instantaneous feedback; either I solved the puzzle, and I would feel proud of my accomplishment and had something to show for it, or I would fail to solve the puzzle, and I would look to more resources and try to learn more about the tools that I should be familiar with and patterns to solve similar problems in the future. I found a few courses and platforms where I could answer some general questions about Python and programming in general, and in exchange I would get a certificate that I could put on my LinkedIn that made me feel like I had accomplished something. But after a few months of having these certifications, I expected that employers would come flocking to me with job offers and wanting me to apply my basic python competency to their problems. Fortunately for me, they didn&#39;t, because I was woefully unprepared to actually take a job at that point.</p>

<p>The time that I spent doing exercises, puzzles, and certifications wasn&#39;t wasted, as it gave me a way to benchmark my specific python knowledge and know whether I was truly absorbing and memorizing the concepts that I was learning. But exercises, puzzles, and certifications don&#39;t tend to have much actual bearing on one&#39;s ability to perform a job and to be responsible for creating and maintaining long-lasting code out in the wild. Being able to write algorithms or unlock the key to a puzzle in a controlled environment can help sharpen your problem-solving tools, but it will not enable one to solve problems that real clients are actually facing in their day-to-day lives. For example, I have experienced in the past an issue where a client came to me and said that they wanted to implement an autocomplete functionality instead of a dropdown menu for a field on a form. Puzzles can help with knowing the syntax of javascript and python to know how to build the particular ui component on the frontend and the endpoint on the backend, and how to make those things talk to each other. But along the way, there will be many choices that have to be made, and it is through those choices that your abilities as a developer will be tested. Should we use a javascript framework on the frontend for this? Will jQuery be sufficient? Or does this require a custom-built component that you create and maintain yourself through raw HTML or WebComponents? Will you need live updates through WebSockets or live polling, to capture new options as they come in? Will we need authentication in this round trip to get autocomplete suggestions? Can we handle this through just basic HTTP Auth, or do we need something like a JWT? Can we include relative links in the content we send back, or is it being rendered locally in the browser where we need absolute links? What happens if a choice is valid when it&#39;s provided, but becomes invalid before the form is submitted? What if the choices need to be dynamically determined based on other form fields on the page, how can we handle that? And given all of these concerns, how do we build this UI component and endpoint in a way that is modular and future-proof so that we can continue to work on it a year from now when the requirements have completely changed? Working on puzzles can help with small pieces in the puzzle, but in order to be a professional developer, you have to be able to identify all of these issues, discuss the pros and cons of various approaches, and make a decision on what to do for each of these when you&#39;re either on your own or your team members cannot provide answers. If you spend all of your time solving self-contained puzzles, then you will find it very challenging when you actually have to face these sorts of situations.</p>

<p>So after getting some practice with puzzles, I was fortunate enough to realize that they weren&#39;t enough to prepare me for real work, and that I would have to start building things myself and learn by doing. Some developers may be intimidated by the thought of taking on projects themselves, or may not have ideas on what to work on. For me, it was easy, because I had a whole laundry list of projects that I wanted to work on; a card game simulator for a fun card game I was working on, a blackjack game, a finance app for tracking monthly bills, and a bible reader app for my wife to do her reading on. I had plenty of other ideas that I never started on, because I tend to love the process of brainstorming but fall short when it comes to execution. But when I had my first set of ideas, I started to just build them from the ground up. Initially, they were terrible; I recall a few months into my card game simulator telling my friends about this 8000 line monstrosity that I was maintaining and how impressive it was. Spoiler alert: it wasn&#39;t impressive, it was a jumbled pile of spaghetti that even I couldn&#39;t understand. But after a few months of developing and reaching a spot where I couldn&#39;t tell where one class ended and another one began, and my middle finger was getting fatigued from scrolling through files that were more than 1000 lines long, I learned a lot of valuable lessons. The first lesson was really just that less code is usually better than more code; fewer lines written means fewer lines you have to maintain, and fewer lines to read when you completely forget what a component does. After that, I learned that spending a whole bunch of time writing something from scratch was more likely to be more of a hinderance than a help. Not only is it duplicitous to remake something that already exists, the person who spent time building it probably has considered a lot of problems and edge cases that you might miss, and has likely already accounted for those. When attempting to learn how something works, the best way to do so is to rebuild it from scracth; but when trying to build something that you want to work, and work well, the best way is to find somehting that already does what you want safely and efficiently, or find multiple things that you can just be responsible for tying together in a way that makes sense and achieves your goal.</p>

<p>So after about 6 months of fighting with this initial implementation, I abandoned ship with a completely unfinished project and moved on to another way of implementing it altogether. I had learned so much about the project and what I wanted to do with it along the way, and realized that I was not likely to end up with a finished product that I was happy with if I kept going down this route. I ended up stopping with that project and moving on to another project that I was more confident on; I would later try 3 or 4 different implementations of that same card game project, and am still working on a new version of it to this day. But I learned so much about how to manage complexity and how to visualize a project from start to finish and how to avoid some of the circular rabbit holes that I fell down along the way. I then moved on to my finance app, starting with learning Django so that I could experience a bit of learning web development and working in a different framework. Previously, I had been working mostly in PyQt5 desktop apps, because I personally was not a fan of web applications; but experiencing how Django worked opened my eyes to the world of web development. I had not previously understood that web applications are just a way to distribute an application quickly and more efficiently to a wider audience. One of the challenges I had faced with trying to build the finance app in PyQt5 before was that, when I had a working version of the software, it was hard to distribute. I didn&#39;t know anyone else who used linux like I did, and so I had to compile windows executables in my dual-booted Windows installation. But because I made my own binaries, they were either not signed or self-signed, and so when I shared it with my friends and family, their computer would either treat it like a virus or refuse to run it. My father asked me how he could run it on his iPad, and my mother asked how to run it on her macbook, and I had to tell both of them that I simply could not make a working copy for them because I didn&#39;t have apple hardware to compile it on. This was a major frustration for me, and it motivated me to learn more about distribution of python applications, which drove me to learning more and more about web development. Initially, I had been hesitant to get into web development because I had imagined that there wasn&#39;t much to it except for ui design and pixel pushing, but after learning about how it can be a great option for cross-compatibility across devices, I was eager to learn more. I had never really given web applications much credit and had always assumed desktop applications were better, but I was finally learning the hard way that it can be so much easier to build an audience and a large userbase if your application is easy to access, and nothing is easier to access than the web.</p>

<p>My research drove me to learning about Flask and Django, and after a bit of experimentation, I started working on reimplementing the finance app in Django. Finally, I was able to make an application that would be easy to access for anyone, and I could still use python to do it so that it was less of a barrier to entry. But the challenges were now twofold; I needed to learn about the Django framework and how it worked while also learning about general web development and how the internet actually works. And with web development, there exists a lot more risk of failure; security concerns can lead to massive data leaks and hostile takeovers of servers, and the threat of unauthorized access is always present if your service is always exposed to the internet. The challenge initially seemed daunting, but I was confident from working on my previous projects and felt prepared to try and tackle the learning curve. It took a while to adapt to a whole new framework, and although the opinionated nature of Django helped guide some of my decisions, there was a lot of magic and things that happened behind the scenes that I was unaware of and had no idea how to fix or change. I managed to get a very basic implementation of the finance app created; it didn&#39;t look pretty, but it worked, and I was super proud of it. It came with all sorts of new challenges and road bumps that I had to work through, and I ended up making some terrible choices. I couldn&#39;t figure out how to make charts in javascript, so I rendered them using plotly on the backend and converted them to base64 encoding before shoving them into my templates to render. I couldn&#39;t figure out how to connect in third party libraries, so I set up a form to fill out for manually entering in every single transaction you make. I couldn&#39;t figure out bootstrap, so I ended up styling things manually, guessing and checking by loading it up on different screen sizes and just moving on when things weren&#39;t mangled or falling off the page. There were all sorts of usability issues and inconveniences, but it worked, and I learned so much about taking a project from start to finish and actually completing something for once. One of the hardest things to do with a project is decide when it&#39;s done, and I learned about the value of making tickets and saving notes for the future but setting hard limits on the features I would implement so that there would be a clear end to the project.</p>

<p>Once the project was complete, the next step was showing it to people and being ready for open and honest feedback. Some people complained that they couldn&#39;t log in, or they couldn&#39;t get it to work, or they didn&#39;t understand it. Some people would make feature requests that I already had in my backlog, and I had to contain the frustration that I had for not implementing it already and impressing them, and just remain patient. But one of my friends was so impressed by that project, he asked if I would be able to build something for his company, and that was how I was able to secure my first freelance contract. It took a few months of discussion, and I had to train a lot to get my skills up to par where I felt they needed to be to securely and reliably deploy an app again, but it was that experience of going from start to finish all by myself on that application that gave me the confidence to say that I could do it for someone else. I had worked on other projects along the way, and had other experience with python and django, but it was the act of completing something from start to finish with no guidance that was able to teach me enough about the skills required and enable me to know when I would be ready to start working on a project for someone else. I negotiated a price that reflected my lower skill level, and it still took me at least double the time estimate that I had initially proposed, but I was able to take the skills that I learned on that first finance app and put them to use on this new freelance project. I definitely still wasn&#39;t skilled enough to feel like a professional developer after completing that freelance project, but it gave me a great experience of having to go through another project from start to finish, but this time one where someone else made the requirements and my work was subject to the approval of someone else. This was a wholly new experience, and it taught me the value of writing tests and taking care with the code that I was writing, as well as being ready to ditch anything at a moment&#39;s notice and being prepared for the real world of changing requirements. I was completely overwhelmed during this project, and so I was very thankful that the project was for a friend and that they were forgiving of the mistakes that I made and that they were prepared to be patient with me. By the end of the process, I felt a lot more prepared for my next task and was eager to take on more projects from outsiders.</p>

<p>I ended up finding another freelance client through another friend, but the client was not a friend and they had a very limited budget and a very pressing need for the project. From my experience with how much the first project dragged on, I learned the value of using pre-established frameworks and keeping the code as simple and flexible as possible to keep up with changes in requirements. I made sure to scope the second project very clearly and I learned how to communicate with the client better so that I could get a better handle on time estimates and set better expectations about what features would and would not be included in the final product. This project went a lot smoother and I was able to get it done a lot faster than the first, and although the tail end of the development process still took a while to go from basic implementation to finished product, there were a lot less meetings required and a lot fewer roadblocks along the way. My bold choice to work in a whole new framework, Wagtail, did mean that the development process was smoother, but it did mean there was a lot more learning to do on my end to bridge the gap of my knowledge between basic Django development and the Page-Model based approach of Wagtail. In hindsight, it probably hindered my development process unnecessarily to be trying to learn a new framework while I was still early on in my development experience, but I wouldn&#39;t have learned that if I hadn&#39;t chosen to take that risk and use the framework for this project. I did expect that it could get challenging, so I estimated my hours and billed a flat rate based on the expected number of hours, so the client didn&#39;t have to pay for the time that I spent learning the framework, but it was me who paid the cost for the extra time investment that was required to get the app to where it needed to be to call it finished. Nevertheless, I didn&#39;t take the project for the money; instead, I was still seeking more experience and the value of learning through the development process far outweighed the monetary value of the contract. I was still deeply in the initial stages of my development experience, and there was no real substitute for real-world experience, so I would have likely taken these clients on for free if they couldn&#39;t afford to compensate me for my time. Luckily for me, they were willing to pay, and they both ended up very satisfied with the work that I did.</p>

<p>Around the time that I was deep in working on the second client project, I was attending a Django convention online for the first time. I had never been to any convention, much less a software one, but I thought it would be a great way to learn more about Django and web development and keep up with the trends, as well as maybe meet some friends to work on projects together with. The format of an online conference was a bit of a challenge, but I managed to get through it and meet some people. I was thankful for the time that I had spent working on those projects, because it gave me a lot to talk about and to relate to people over while at the conference. I even unknowingly ranted and raved about a library I had found, Django Simple History, to someone who later revealed to me that he was a core maintainer on the project, only for me to be embarrassed to not recognize him. Being surrounded by people who all shared the interest of Django and web development was such a great experience, and having my work be validated by people who had been doing this sort of thing for years really made me feel like my work was meaningful and that I was on the right path. To make a long story short, one person I met at that conference would eventually end up connecting me with an interview that, about 9 months after the conference, would lead to me getting my first job as a software engineer. I didn&#39;t go to the conference to find a job, but I had some idea that it was possible that making connections in the field would eventually give me a leg up into the job market, and it just so happened that I was in the right place at the right time and met the right person to kick start my career.</p>

<p>So what&#39;s the point of telling this long and convoluted story about how I got my first job? Well, it&#39;s the story of how I made it from nothing to get to the point of starting my career off in a field that I love and where I am happy to work every day. I didn&#39;t know that the conference would help me get the job; I didn&#39;t know that the second freelance client would make me confident enough to attend the conference; I didn&#39;t know that the first freelance client would make me confident enough to seek out another project; I didn&#39;t know that my Django finance app would impress someone enough for them to become my first client; I didn&#39;t know that my card game app would leave me so frustrated that I would try out web development; I didn&#39;t know that puzzles and coding challenges would leave me hungry for more serious experience; and I didn&#39;t know that completing my online python course would get me interested in online Python puzzles. We don&#39;t know what path we will be led down until we start our journey. But what I did know is that, after my python course and playing around with some scripts, I was interested in python and wanted to learn more, and so I kept trying to find the next step and the next thing to work on and spent all my effort and time that I could afford pursing that interest, which turned into a hobby, which turned into a passion, which turned into a career.</p>

<p>So for anyone reading this who thinks they may be somewhat interested in programming, web development, tech, or anything, I would encourage you to try and find the next small step that you can take and put as much effort you can towards that one step, because although each phase along the way may just seem convenient, or like a simple small thing that you can do now, you never know where it may lead. And if you&#39;re fortunate enough, it might lead you in the direction that you want to be going.</p>
]]></content:encoded>
      <guid>https://write.as/thewadegreen/dont-quit-your-day-job</guid>
      <pubDate>Wed, 15 Jan 2025 03:11:25 +0000</pubDate>
    </item>
    <item>
      <title>Try New Things</title>
      <link>https://write.as/thewadegreen/try-new-things?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[I&#39;m a firm believer in the idea that the best way to learn something new is by doing something new. I used to be someone who spent a long time researching and preparing and trying to learn ways to do something before I even tried to start my tasks, thinking that if I spend more time preparing, it&#39;ll make the actual act of doing the thing so much easier. While there is something to be said for preparation, it tends to be best served in moderation, and alongside a healthy dose of experience and practice. Sometimes, though, spending too much time preparing can be a wasted investment; if you don&#39;t know that you&#39;re really going to want to do the thing, then it can be a waste if you spend all the time preparing for something you&#39;re not interested in doing.&#xA;&#xA;Programming is one of my favorite hobbies, and I&#39;m fortunate enough to have made it into somewhat of a profession as well. One aspect of programming that I love is the relatively low barrier to entry. When I was younger, I had the unexplainable urge to try and take up playing lacrosse. This meant that I needed to find a lacrosse stick, pick up some lacrosse pads, and find a team and a coach to help teach me the fundamentals of playing lacrosse. I was fortunate enough to live in an area where these things were relatively accessible, and it just so happened that I had a family member who was already playing lacrosse on a team, so that significantly lowered the bar of entry. &#xA;&#xA;But with all that being said, it still cost hundreds of dollars for me to have everything that I need before I was theoretically able to get out on the field. I say theoretically because, although I tried my hardest in practice, I found myself spending most of my time at the games sitting on the bench, with my coach only allowing me a few minutes near the end of the game to try and get on the field and exhibit my lack of skills for the small group of parents who came to watch the games. By the end of the first year, I very much resented my choice to try lacrosse, as it was becoming very clear to me that I did not possess the requisite skill nor the determination to practice and improve in the ways that would be required for me to succeed. My father tried to encourage me to continue, and I did start another season, but midway through that season I ended up quitting the team and giving away my gear to someone else who was eager to try the sport. Overall, I managed to only spend a few hundred dollars of my parents money and waste somewhere in the tens or hundreds of hours of my time and theirs trying to determine whether I was going to be the next lacrosse superstar. This may seem like a lot of time and money, but compared to the bills and time investment that some of the other athletes racked up, it was quite fortunate that I was able to keep the costs to such a minimum.&#xA;&#xA;I wish I had the foresight to know that I would not have enjoyed lacrosse in the first place; it would have saved all that time and money for more helpful pursuits. But by giving it a fair shot, by investing the time and money into trying out something new, I was able to learn two things: that success only comes through hard work and determination; and that I have no interest in working hard and being determined when it comes to lacrosse. There were probably cheaper ways to learn those lessons, and I probably could have just listened to someone tell me that I wasn&#39;t cut out for it, but it wouldn&#39;t have solidified those lessons in my mind as well as having to suffer through the experiences of working hard at practice only to sit on the bench throughout most of the season, and then having to face the embarrassment of quitting when I finally realized it wasn&#39;t for me. Going through those experiences made those lessons real to me, and made them stick with me to this day as I write this post, two decades later.&#xA;&#xA;My experience with lacrosse was well worth it, but I have been fortunate enough to develop a passion for programming, which has a significantly lower barrier to entry. Sure, you could spend a whole heap of money on fancy computers and software, just like my teammates who had their parents fund brand new equipment on day one of the season; but if you really just want to test out programming, you can invest in a simple setup and start learning the trade with a low barrier to entry. These days, you can purchase a raspberry pi or a media PC with integrated graphics and a relatively decent processor and get set up with a computer for well under two hundred dollars. For the cost that I spent on lacrosse equipment, I could have set myself up with some decent hardware and run a linux operating system with some open source software and started working through some free or low-cost online tutorials or resources. Acquiring the tools to setup a language like python, javascript, or go on your system can be done quickly and much more easily these days, and you can go from a computer with an empty hard drive to working on your first project within a few hours, even for the most beginner users who are eager to try new things. In the hours that I spent at lacrosse practice, shuttling to and from games, and practicing my cradling at home, I could have been spinning up webservers, editing files on my filesystem, and building dice simulators for my dungeons and dragons club before I had learned to catch the ball. &#xA;&#xA;Even for those who are on a completely zero budget, there are resources and options to help get your foot in the door and see if programming is for you. Take a bus down to your local library and you can take a turn on a computer there, which likely has access to python or can run a website like replit or pythononline where you can play with online scrpts. Most computers have some form of text editor, even notepad, where you can get a feel for what programming is and what it can do; my very first web pages that I wrote under the guidance of my older sibling back in middle school were written in notepad and I had to manually change the file extensions to .html. If there&#39;s no libraries around, sneak into the apple store at the local mall; all macs come with python installed by default, and you can play around for a bit before you get chased off and have to find somewhere else to be. If you attend a school with a computer lab, make friends with whoever runs the lab; my sibling got to know the computer teacher and he let my sibling spend time on the internet after school when they got grounded from using a computer at home. If you have a friend with a computer, get them interested in programming and take turns writing programs with them. If all else fails, try and get a book from a library or a friend and just start writing out scripts and planning your work on a piece of paper in pencil; when I lived in an area without satellite internet, I kept notes in a notebook that were handwritten and I would wait until I could drive into town and use my laptop in the parking lot of the library to write my code. In the modern day, there are so many ways to spend little to no money to get a taste of what programming is and see if it&#39;s something that interests you; all you need is an interest and the willingness to put forth effort and learn, and the rest of the pieces will fall into place.&#xA;&#xA;I&#39;m very fortunate to have been blessed with so many opportunities to try new things and get the equipment necessary; but i&#39;m here to tell you, if you&#39;re interested in programming, you don&#39;t need a whole lot, just passion and a willingness to try. If you like it, you can keep working and learning, and eventually either use your skills to make enough money to afford to invest more into yourself and your leanring; and if you don&#39;t like it, well, then at least you didn&#39;t waste a bunch of time and money on something that you didn&#39;t like. If I had known back then that programming could be so accessible and easy to learn and find resources for, well, let&#39;s just say there would have been one more space available on that lacrosse team.]]&gt;</description>
      <content:encoded><![CDATA[<p>I&#39;m a firm believer in the idea that the best way to learn something new is by doing something new. I used to be someone who spent a long time researching and preparing and trying to learn ways to do something before I even tried to start my tasks, thinking that if I spend more time preparing, it&#39;ll make the actual act of doing the thing so much easier. While there is something to be said for preparation, it tends to be best served in moderation, and alongside a healthy dose of experience and practice. Sometimes, though, spending too much time preparing can be a wasted investment; if you don&#39;t know that you&#39;re really going to want to do the thing, then it can be a waste if you spend all the time preparing for something you&#39;re not interested in doing.</p>

<p>Programming is one of my favorite hobbies, and I&#39;m fortunate enough to have made it into somewhat of a profession as well. One aspect of programming that I love is the relatively low barrier to entry. When I was younger, I had the unexplainable urge to try and take up playing lacrosse. This meant that I needed to find a lacrosse stick, pick up some lacrosse pads, and find a team and a coach to help teach me the fundamentals of playing lacrosse. I was fortunate enough to live in an area where these things were relatively accessible, and it just so happened that I had a family member who was already playing lacrosse on a team, so that significantly lowered the bar of entry.</p>

<p>But with all that being said, it still cost hundreds of dollars for me to have everything that I need before I was theoretically able to get out on the field. I say theoretically because, although I tried my hardest in practice, I found myself spending most of my time at the games sitting on the bench, with my coach only allowing me a few minutes near the end of the game to try and get on the field and exhibit my lack of skills for the small group of parents who came to watch the games. By the end of the first year, I very much resented my choice to try lacrosse, as it was becoming very clear to me that I did not possess the requisite skill nor the determination to practice and improve in the ways that would be required for me to succeed. My father tried to encourage me to continue, and I did start another season, but midway through that season I ended up quitting the team and giving away my gear to someone else who was eager to try the sport. Overall, I managed to only spend a few hundred dollars of my parents money and waste somewhere in the tens or hundreds of hours of my time and theirs trying to determine whether I was going to be the next lacrosse superstar. This may seem like a lot of time and money, but compared to the bills and time investment that some of the other athletes racked up, it was quite fortunate that I was able to keep the costs to such a minimum.</p>

<p>I wish I had the foresight to know that I would not have enjoyed lacrosse in the first place; it would have saved all that time and money for more helpful pursuits. But by giving it a fair shot, by investing the time and money into trying out something new, I was able to learn two things: that success only comes through hard work and determination; and that I have no interest in working hard and being determined when it comes to lacrosse. There were probably cheaper ways to learn those lessons, and I probably could have just listened to someone tell me that I wasn&#39;t cut out for it, but it wouldn&#39;t have solidified those lessons in my mind as well as having to suffer through the experiences of working hard at practice only to sit on the bench throughout most of the season, and then having to face the embarrassment of quitting when I finally realized it wasn&#39;t for me. Going through those experiences made those lessons real to me, and made them stick with me to this day as I write this post, two decades later.</p>

<p>My experience with lacrosse was well worth it, but I have been fortunate enough to develop a passion for programming, which has a significantly lower barrier to entry. Sure, you could spend a whole heap of money on fancy computers and software, just like my teammates who had their parents fund brand new equipment on day one of the season; but if you really just want to test out programming, you can invest in a simple setup and start learning the trade with a low barrier to entry. These days, you can purchase a raspberry pi or a media PC with integrated graphics and a relatively decent processor and get set up with a computer for well under two hundred dollars. For the cost that I spent on lacrosse equipment, I could have set myself up with some decent hardware and run a linux operating system with some open source software and started working through some free or low-cost online tutorials or resources. Acquiring the tools to setup a language like python, javascript, or go on your system can be done quickly and much more easily these days, and you can go from a computer with an empty hard drive to working on your first project within a few hours, even for the most beginner users who are eager to try new things. In the hours that I spent at lacrosse practice, shuttling to and from games, and practicing my cradling at home, I could have been spinning up webservers, editing files on my filesystem, and building dice simulators for my dungeons and dragons club before I had learned to catch the ball.</p>

<p>Even for those who are on a completely zero budget, there are resources and options to help get your foot in the door and see if programming is for you. Take a bus down to your local library and you can take a turn on a computer there, which likely has access to python or can run a website like replit or pythononline where you can play with online scrpts. Most computers have some form of text editor, even notepad, where you can get a feel for what programming is and what it can do; my very first web pages that I wrote under the guidance of my older sibling back in middle school were written in notepad and I had to manually change the file extensions to .html. If there&#39;s no libraries around, sneak into the apple store at the local mall; all macs come with python installed by default, and you can play around for a bit before you get chased off and have to find somewhere else to be. If you attend a school with a computer lab, make friends with whoever runs the lab; my sibling got to know the computer teacher and he let my sibling spend time on the internet after school when they got grounded from using a computer at home. If you have a friend with a computer, get them interested in programming and take turns writing programs with them. If all else fails, try and get a book from a library or a friend and just start writing out scripts and planning your work on a piece of paper in pencil; when I lived in an area without satellite internet, I kept notes in a notebook that were handwritten and I would wait until I could drive into town and use my laptop in the parking lot of the library to write my code. In the modern day, there are so many ways to spend little to no money to get a taste of what programming is and see if it&#39;s something that interests you; all you need is an interest and the willingness to put forth effort and learn, and the rest of the pieces will fall into place.</p>

<p>I&#39;m very fortunate to have been blessed with so many opportunities to try new things and get the equipment necessary; but i&#39;m here to tell you, if you&#39;re interested in programming, you don&#39;t need a whole lot, just passion and a willingness to try. If you like it, you can keep working and learning, and eventually either use your skills to make enough money to afford to invest more into yourself and your leanring; and if you don&#39;t like it, well, then at least you didn&#39;t waste a bunch of time and money on something that you didn&#39;t like. If I had known back then that programming could be so accessible and easy to learn and find resources for, well, let&#39;s just say there would have been one more space available on that lacrosse team.</p>
]]></content:encoded>
      <guid>https://write.as/thewadegreen/try-new-things</guid>
      <pubDate>Tue, 14 Jan 2025 06:29:00 +0000</pubDate>
    </item>
    <item>
      <title>Pair Programming with ChatGPT</title>
      <link>https://write.as/thewadegreen/the-following-is-an-blog-post-that-i-wrote-while-working-for-a-previous?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[The following is an blog post that I wrote while working for a previous employer; I was able to save the text content of the post, although the screenshots that I took for context seem to be lost to time. I wanted to share my initial thoughts that I wrote on ChatGPT and ai-assisted coding back in 2021-2 as the chatbots were starting to gain traction, as I feel like my thoughts are largely the same, looking back almost 3-4 years later. I look forward to providing a continuation on my perspective on these tools in the future, but for now I want to preserve my thoughts and observations from the first opportunity I had to deeply explore these tools.&#xA;&#xA;Original Text&#xA;&#xA;I can&#39;t say that I&#39;ve always wanted to pair program with a computer. Still, when the opportunity to work on a project with ChatGPT arose, I was eager to try it. Why settle for writing code on a computer when you can make the computer write code for you?&#xA;&#xA;At first, I didn&#39;t have high expectations of the service; but after asking it a few questions, I was impressed by its responses and eager to put it through more rigorous testing. I was planning on composing a server of microservices for handling some routine tasks that I do daily, and working on this project would give me an excellent opportunity to see how capable ChatGPT would be in a real-world setting.&#xA;&#xA;Working with ChatGPT has been surprising for both good and bad reasons. I wanted to share my experience to help anyone looking to use this service for assistance in programming. Would I recommend ChatGPT to someone looking for help with coding? Yes, Maybe, and No, depending on what you are doing with it. Keep reading to understand better where ChatGPT excels and where it can be problematic.&#xA;&#xA;What is it?&#xA;If you are unfamiliar with the service, ChatGPT is a Chatbot designed by OpenAI. It is built on top of the GPT-3 language models, developed in 2020 and designed to use deep learning to produce human-like text. In the past, GPT models have been used to create stories and writings that seem convincing enough to appear to be written by a human, even though they are artificially generated. ChatGPT takes this underlying deep learning model and adds an interface where the user can give it prompts, such as questions or statements. It will process those prompts and respond. Through both unsupervised and supervised learning, ChatGPT has been trained to react convincingly to human prompts in a way that seems similar to how a human would respond. Since its release, people have been asking ChatGPT all sorts of questions, including how to write code. ChatGPT has shown a solid ability to provide responses that answer the questions accurately. I wanted to test ChatGPT by seeing if I could develop my latest project by only asking ChatGPT questions and using its code.&#xA;&#xA;What was the project?&#xA;I want to discuss the project and why I was drawn to use ChatGPT. The overall goal is to build an application from a collection of Microservices to handle some everyday tasks that I do every day. I have a one-year-old daughter at home, so much of my time is spent measuring formula, keeping track of the food and drink she ingests and planning her mealtimes and overall schedules. I have a variety of scripts that I use in different formats for some of these tasks, but I would like to build and deploy a server at home that can handle all of these tasks in a centralized location. I chose the microservices approach because I want to be able to add and remove functionality as my daughter grows up, and using microservices means that it&#39;s a lot easier to enable or disable features without impacting the overall service architecture.&#xA;&#xA;I wanted to build the initial services in Flask for two reasons. The first reason is that I am very familiar with Python, so it would be easier to validate the responses that ChatGPT gave me and spot any inconsistencies or errors right away. The second reason is that, although I had some cursory introduction to Flask, my area of expertise lies more in Django. I have always wanted to spend more time building more lightweight web servers in Flask. Since I have a lot to learn, it would give me a great perspective on how helpful ChatGPT could be to users unfamiliar with a particular language or framework.&#xA;&#xA;Along similar lines, I have some decent experience with Docker and Docker Compose. Still, I needed help figuring out how to set up multiple dockerfiles within one multi-container application. ChatGPT could help guide me along this more complex topic I needed to familiarize myself with.&#xA;&#xA;How did ChatGPT help?&#xA;While building this application, ChatGPT had a lot of valuable features and functionality that helped speed up my development process. First and foremost, ChatGPT is excellent at providing a boilerplate for setting up basic configurations on both the Flask and Docker sides of the application. Being able to ask two questions and have the baseline code for my flask app, the Dockerfile for the first app, and the Docker Compose file that includes the first app was miraculous. I could have come across something similar if I had found a single tutorial that handled all of these topics. Still, that one perfect tutorial usually doesn&#39;t exist. I might have spent up to an hour trying to piece together different tutorials until I had what ChatGPT provided me within seconds.&#xA;&#xA;Moreover, it was super helpful that ChatGPT provides practical walkthroughs of the code it produces, so I can read along with the code and the explanation and get a quick and straightforward answer of precisely what the code is supposed to do and how the different files interact. If I had a question about something ChatGPT wrote, I could ask about a function or concept. It would know how to explain what was happening in context, suggest alternatives, or provide more examples of approaches to the same problem. For someone less familiar with Flask and more complex aspects of Docker, it was great to be refreshed on what I did know and have the newer or more complicated things explained to me simultaneously.&#xA;&#xA;What did it do well (the &#34;good&#34;)?&#xA;ChatGPT has some fantastic features that make it a very appealing programming partner. Because of the thread-based nature of the conversation, ChatGPT can keep a solid understanding of what we are discussing without requiring me to repeat myself. For example, since I was working in Flask and asking questions about Flask throughout this thread, it knew that I would expect responses that apply to building a Flask application. When I asked a question that didn&#39;t include context, such as &#34;How do I set multiple HTTP methods for one route,&#34; it already knew to give me a response relevant to the topic we were discussing. Being able to follow the flow of conversation made the process of interacting with ChatGPT a lot smoother and more like interacting with a human being.&#xA;‍&#xA;&#xA;ChatGPT could also be even better than interacting with human beings because the threads are persistent and stay open over days, weeks, or even years. This means that you could ask a series of questions about Flask, then leave for a month, and come back and ask a question like the one I presented above, and ChatGPT would not miss a beat; it would be able to answer in context with all of the previous chat history fresh in its memory.&#xA;&#xA;ChatGPT also excels in its ability to provide documentation around its code. This benefits someone with less experience in the field for two reasons. First, it makes it easier to understand the code when ChatGPT writes it so the user knows what is happening and what they may need to change. Second, it makes it easier for the user to understand what the code is doing down the road; if the user returns to this code in a month without working in Flask, then it&#39;s likely they may have forgotten the code or why it was written. Writing good documentation is an excellent habit for all developers, human or otherwise. So it&#39;s great that ChatGPT tends to do it by default. Not everything was clearly documented, but it was much more consistent than I tend to be when documenting my code.&#xA;‍&#xA;&#xA;Finally, I was very impressed by ChatGPT&#39;s ability to write code that follows the structure and syntax that Flask applications generally follow. For example, ChatGPT generally recommended that I use the Flask jsonify function to prepare json objects for my responses; since Flask doesn&#39;t automatically serialize and sanitize your data, it is helpful always to make sure to jsonify the data before providing it as content in the response. It could have suggested returning a python dictionary as the json content for the response. Flask typically can handle standard data types within a python dictionary and provide it as a JSON response. Instead, it recommended using jsonify, a safer way to handle the data being returned and accounts for serializing database models straight from python objects into valid json, preventing any implicit serialization issues. ChatGPT had a good handle on some best practices when building standard, simple Flask apps. This was very helpful for someone like me who is coming from a different web server paradigm.&#xA;&#xA;What were some of the hiccups (the &#34;bad&#34;)?&#xA;Although ChatGPT had a lot of features and functionality that impressed me, there were many points where it fell short of impressive and even came close to frustrating. One challenge was that it took a lot of work to communicate context with ChatGPT. It was hard to describe my specific file structure to the service, which meant it couldn&#39;t advise me on import errors and where to store files. There were even some instances, such as when describing where to store my .env files, where ChatGPT would tell me to create a .env file in one directory, but then the next code snippet would be written under the assumption that I had placed the .env file in a completely different directory. When it suggested creating multiple files that referenced each other, sometimes it would be clear from the imports that they were located in the same directory. Still, other times it would just give me the file contents and assume I knew where each file should go. At one point, it even caused my application not to work because it wrote in my Dockerfile that I should run the Gunicorn command and point it to my wsgi.py to start my production server, but I had not yet created that file and inadvertently placed it in the wrong directory, causing my entire run command to fail and my Docker container to crash. When I asked ChatGPT what the issue was, it gave me general advice about how to fix import errors, but I needed a clearer way for me to show it my file tree and have it point out the misplaced files.&#xA;&#xA;ChatGPT also tended to play fast and loose with variable names and imports, which is not a big deal when talking about code snippets and abstract questions but can cause significant issues that are hard to debug when applied to a project. In some responses, it would import the entire datetime library. In contrast, in others, it would use &#34;from datetime import datetime&#34;, and these conflicting imports can cause scripts to crash. In other responses, it would use the jsonify function, but forget to import it. So the code would give an import error instead of working. Sometimes it was clear that the response was just an abstract snippet, whereas other times, it would be an entire fully-written file; but in some instances, it was hard to tell which type of response it was providing, as it wouldn&#39;t tell me if it had written the entire file contents or just one piece. With variable names, many of the responses had abstract names like &#34;data&#34; or &#34;result&#34;, which work well in small snippets but are not descriptive enough to capture what is coming back and can often overlap with other code snippets. There was one example where it named the variable &#34;data&#34;, which represented the response content from the request, but then it ran that &#34;data&#34; through a function and named the return value &#34;data&#34; as well, thus overwriting the original &#34;data&#34; variable from the same example. In practice, this can work fine, but for a less experienced developer trying to debug the code from ChatGPT, this can cause confusion and frustration that can be avoided by simply choosing more varied variable names.&#xA;&#xA;Finally, although ChatGPT initially impressed me with its knowledge of Flask syntax and conventions, it found ways to disappoint me in other areas I was more familiar with. It routinely broke PEP style conventions in writing python code and tended to favor javascript-based forms when simple HTML forms were sufficient. It also has limited knowledge about information beyond 2021, so it was working on outdated information, such as not knowing that the match statement was implemented in Python and using var instead of const or let in Javascript. In one particular instance, it led me to some incorrect implementations, as it told me that, in my Docker configuration, I need to expose the ports for all of my microservices to the host machine and then tell each service to communicate through the host machine. The proper solution for my use case is to use the service name in the URL and have each service communicate directly with the other services. Trying to send requests to the host machine is convoluted at best and failed to work when I tried to implement it. I would have spent hours trying to implement this solution that ChatGPT was leading me toward if I had not spoken with a colleague about the best approach and had him walk me through how the Docker services should actually be set up. (Thanks, Evan Matizza!)&#xA;&#xA;What were the major issues (the &#34;ugly&#34;)?&#xA;As much as I liked working with ChatGPT, some major issues came up during the project. The most severe of these issues was that ChatGPT can be confidently incorrect and still logically explain their answer even though it&#39;s completely wrong. As an example, when I was working on the service for calculating how much powder and water to mix to make formula, I asked it to make a function that would calculate how much powder and water I should mix to prepare the formula. It explained that since one scoop is 20 calories, I can use the recipe below to calculate the correct calorie density and the amount of water to mix with the powder to prepare the formula. It did not ask any clarifying questions or require further input; it simply stated that its recipe would work. The logic made sense, but I was sure to double-check the math with other accurate services that discussed the calorie density of formula and found that the ChatGPT had errors in its calculation. One scoop of formula contains 45 calories, so the function ChatGPT created for me would result in making more than double the calorie density of what I needed. In the past, we have had issues with feeding formula that&#39;s slightly too dense to my baby, which has resulted in significant constipation and other digestive problems; if I had blindly followed the recipe ChatGPT provided, I could likely have seriously harmed my baby. When working with ChatGPT, it&#39;s important to remember that it could sound 100% confident in its answers, even if there are severe calculations or logical flaws, so verifying the answers with other sources you trust is essential.&#xA;‍&#xA;&#xA;Besides that serious issue, there were several times when ChatGPT gave me an answer that was not entirely wrong but was not the right way to approach the problem because of a lack of context. For example, I received an error when I tried to save a string into a database field expecting a bytes object. When I passed the error message along to ChatGPT, it explained that I needed to convert my string into a bytes object and provided code. However, after I looked at the setup and thought about the problem, I realized that the field in my database was set up wrong and that I intended to make it a string field. So, I changed the field type and everything worked. ChatGPT gave me an answer that would have solved the problem, but it wasn&#39;t the correct answer overall because it lacked the context of what I had done and my true goals.&#xA;&#xA;I also had other instances where context was lacking, such as when it told me that I should be returning the database entry directly from my function, but in the context of my application, that function was supposed to return a JSON response. So I needed to return a response object with the database entry jsonified and attached to that response. In another question, I had asked it to make a form that would delete an entry. It made a form that sends a POST request to my endpoint, but then in the suggested code for my endpoint, it set it up to only accept DELETE requests. If I just copy-pasted this code into my app, it would not work, and I would have to spend time tearing apart the suggestion that ChatGPT provided in one cohesive response because that one response was not internally consistent. Even when directly implementing code that ChatGPT suggested, it would sometimes just not work and require the user to be able to figure out what ChatGPT&#39;s mistake was, which could take more knowledge than is required to write it from scratch by themselves.&#xA;&#xA;Finally, I find it difficult to recommend to users with no context of what is going on in the responses it provides. I was fortunate to have a solid foundation in Python and a decent understanding of Flask before starting this project because it takes at least a fundamental understanding of how the language works to piece together the different responses that ChatGPT provides. If you ask it to solve one problem, it might be able to provide all the code necessary for that one solution; but as your application grows and you need to piece together code from different responses, you need to understand what to keep, what to delete, and what to replace. In many of the responses, I would have boilerplate code or general setup code that was repeated but a little differently or with different variable names; if you combined both responses, you might end up duplicating steps at best or breaking your existing code at worst. In one of my inquiries, I could logically piece together the code from multiple responses, but the code stopped working and said there were configuration issues with the database. I asked ChatGPT for help in a few different ways; however, all of its responses just told me that I needed to delete the database and call db.createall() to reset it, which did not work. I did a simple google search for my issue. The first result was a forum post about how you need to call db.createall() only after you import all of your models; otherwise, the database will not be appropriately created; once I refactored my code based on that suggestion, it worked right away. I found other forum posts and articles from 2019 that discussed my exact problem, so I was surprised that ChatGPT could not figure out how to solve my problem. Whether it was a lack of context, a lack of understanding, or a lack of source material that answered the problem, it was clear that there are some problems that ChatGPT won&#39;t know how to solve. It is up to the user to diagnose and understand the problem independently, even when using the code ChatGPT provided.&#xA;&#xA;Would you recommend ChatGPT for writing code?&#xA;Considering all the good, bad, and terrible examples above, I have three answers to whether I recommend using ChatGPT for writing code.&#xA;&#xA;Would I recommend ChatGPT for conceptual questions or questions about overarching themes? Yes!&#xA;&#xA;ChatGPT is excellent at explaining overall concepts with clear words and examples to back up what it is saying. Someone with good general knowledge who wants to learn more can quickly get their questions answered by material that is on-topic and to the point. Suppose you have questions about translating a concept from one language to another or doing everyday tasks within a language. In that case, I have a decent amount of confidence in ChatGPT&#39;s ability to answer those questions. Furthermore, questions you expect to have many answers online, such as questions about common algorithms or programming functionality, should be safe to ask ChatGPT. I always recommend double-checking your answers with verified sources online. Still, it can be a great place to get quick and straightforward answers to general, conceptual questions or as a starting point for research and learning.&#xA;&#xA;Would I recommend ChatGPT for code examples and specific implementations? Maybe.&#xA;&#xA;The code examples I asked for during this project were helpful, and I could either use the entire snippet and modify it myself or take parts that I needed and leave the rest behind. It was beneficial for boilerplate or initial examples or when I needed to write a file and knew I would need some standard things and only needed to tweak a few settings. It felt lacking in areas where the technology is newer or tends to change quickly, such as with new language features in Python or with JavaScript in general. As a rule of thumb, if I worried about it changing in the past 3-5 years, I would take anything ChatGPT said with a grain of salt. They may include more recent data as the service evolves. Still, even so, you&#39;re less likely to have an abundance of source material to draw on if you&#39;re asking questions about a language feature that only recently came out. Furthermore, it can make some specific choices in design patterns and library usage without telling you that there are alternatives or why you might choose an alternative. It is up to you to spot places where there might be other choices that you can make and ask ChatGPT about the alternatives.&#xA;&#xA;Would I recommend ChatGPT for solving problems from start to finish? No!&#xA;&#xA;Although ChatGPT strongly believes that it can solve entire problems, there have been a few instances in this project where it has proven to be false. Furthermore, it may be making assumptions about your goals or the technology, which may not be true, and it will not tell you about those assumptions when it boldly proclaims that it has solved the problem. ChatGPT is missing the critical ability to self-reflect on its answers and explain nuances such as side effects, further questions for the user, and any indication of self-doubt. These skills are critical for any software developer who wishes to provide correct answers; if you want to be sure, then you have to seek out the uncertainty and ensure that all underlying assumptions and foundational knowledge are at least identified, if not challenged and verified.&#xA;&#xA;Overall, ChatGPT is a very powerful tool and can be extremely helpful in the software development process, but it requires a keen eye and strong attention to detail to be used effectively. Although the temptation is there just to ask it questions and take its answers at face value, ChatGPT users must remain diligent and be sure to interpret and verify all responses before putting the code into use. I am very impressed by the state that the service is in currently, and I look forward to seeing it improve and to all the great things you can create when working with ChatGPT!&#xA;&#xA;Note: Since working on this project, the team at OpenAI has been improving ChatGPT&#39;s ability to ask questions and get clarification around code issues. Although I have not seen this feature personally, I am excited to see how ChatGPT evolves and can better address my abovementioned concerns. There may be a part 2 to this article as new features emerge!&#xA;&#xA;‍&#xA;]]&gt;</description>
      <content:encoded><![CDATA[<p>The following is an blog post that I wrote while working for a previous employer; I was able to save the text content of the post, although the screenshots that I took for context seem to be lost to time. I wanted to share my initial thoughts that I wrote on ChatGPT and ai-assisted coding back in 2021-2 as the chatbots were starting to gain traction, as I feel like my thoughts are largely the same, looking back almost 3-4 years later. I look forward to providing a continuation on my perspective on these tools in the future, but for now I want to preserve my thoughts and observations from the first opportunity I had to deeply explore these tools.</p>

<h2 id="original-text">Original Text</h2>

<p>I can&#39;t say that I&#39;ve always wanted to pair program with a computer. Still, when the opportunity to work on a project with ChatGPT arose, I was eager to try it. Why settle for writing code on a computer when you can make the computer write code for you?</p>

<p>At first, I didn&#39;t have high expectations of the service; but after asking it a few questions, I was impressed by its responses and eager to put it through more rigorous testing. I was planning on composing a server of microservices for handling some routine tasks that I do daily, and working on this project would give me an excellent opportunity to see how capable ChatGPT would be in a real-world setting.</p>

<p>Working with ChatGPT has been surprising for both good and bad reasons. I wanted to share my experience to help anyone looking to use this service for assistance in programming. Would I recommend ChatGPT to someone looking for help with coding? Yes, Maybe, and No, depending on what you are doing with it. Keep reading to understand better where ChatGPT excels and where it can be problematic.</p>

<h2 id="what-is-it">What is it?</h2>

<p>If you are unfamiliar with the service, ChatGPT is a Chatbot designed by OpenAI. It is built on top of the GPT-3 language models, developed in 2020 and designed to use deep learning to produce human-like text. In the past, GPT models have been used to create stories and writings that seem convincing enough to appear to be written by a human, even though they are artificially generated. ChatGPT takes this underlying deep learning model and adds an interface where the user can give it prompts, such as questions or statements. It will process those prompts and respond. Through both unsupervised and supervised learning, ChatGPT has been trained to react convincingly to human prompts in a way that seems similar to how a human would respond. Since its release, people have been asking ChatGPT all sorts of questions, including how to write code. ChatGPT has shown a solid ability to provide responses that answer the questions accurately. I wanted to test ChatGPT by seeing if I could develop my latest project by only asking ChatGPT questions and using its code.</p>

<h2 id="what-was-the-project">What was the project?</h2>

<p>I want to discuss the project and why I was drawn to use ChatGPT. The overall goal is to build an application from a collection of Microservices to handle some everyday tasks that I do every day. I have a one-year-old daughter at home, so much of my time is spent measuring formula, keeping track of the food and drink she ingests and planning her mealtimes and overall schedules. I have a variety of scripts that I use in different formats for some of these tasks, but I would like to build and deploy a server at home that can handle all of these tasks in a centralized location. I chose the microservices approach because I want to be able to add and remove functionality as my daughter grows up, and using microservices means that it&#39;s a lot easier to enable or disable features without impacting the overall service architecture.</p>

<p>I wanted to build the initial services in Flask for two reasons. The first reason is that I am very familiar with Python, so it would be easier to validate the responses that ChatGPT gave me and spot any inconsistencies or errors right away. The second reason is that, although I had some cursory introduction to Flask, my area of expertise lies more in Django. I have always wanted to spend more time building more lightweight web servers in Flask. Since I have a lot to learn, it would give me a great perspective on how helpful ChatGPT could be to users unfamiliar with a particular language or framework.</p>

<p>Along similar lines, I have some decent experience with Docker and Docker Compose. Still, I needed help figuring out how to set up multiple dockerfiles within one multi-container application. ChatGPT could help guide me along this more complex topic I needed to familiarize myself with.</p>

<h2 id="how-did-chatgpt-help">How did ChatGPT help?</h2>

<p>While building this application, ChatGPT had a lot of valuable features and functionality that helped speed up my development process. First and foremost, ChatGPT is excellent at providing a boilerplate for setting up basic configurations on both the Flask and Docker sides of the application. Being able to ask two questions and have the baseline code for my flask app, the Dockerfile for the first app, and the Docker Compose file that includes the first app was miraculous. I could have come across something similar if I had found a single tutorial that handled all of these topics. Still, that one perfect tutorial usually doesn&#39;t exist. I might have spent up to an hour trying to piece together different tutorials until I had what ChatGPT provided me within seconds.</p>

<p>Moreover, it was super helpful that ChatGPT provides practical walkthroughs of the code it produces, so I can read along with the code and the explanation and get a quick and straightforward answer of precisely what the code is supposed to do and how the different files interact. If I had a question about something ChatGPT wrote, I could ask about a function or concept. It would know how to explain what was happening in context, suggest alternatives, or provide more examples of approaches to the same problem. For someone less familiar with Flask and more complex aspects of Docker, it was great to be refreshed on what I did know and have the newer or more complicated things explained to me simultaneously.</p>

<h2 id="what-did-it-do-well-the-good">What did it do well (the “good”)?</h2>

<p>ChatGPT has some fantastic features that make it a very appealing programming partner. Because of the thread-based nature of the conversation, ChatGPT can keep a solid understanding of what we are discussing without requiring me to repeat myself. For example, since I was working in Flask and asking questions about Flask throughout this thread, it knew that I would expect responses that apply to building a Flask application. When I asked a question that didn&#39;t include context, such as “How do I set multiple HTTP methods for one route,” it already knew to give me a response relevant to the topic we were discussing. Being able to follow the flow of conversation made the process of interacting with ChatGPT a lot smoother and more like interacting with a human being.
‍</p>

<p>ChatGPT could also be even better than interacting with human beings because the threads are persistent and stay open over days, weeks, or even years. This means that you could ask a series of questions about Flask, then leave for a month, and come back and ask a question like the one I presented above, and ChatGPT would not miss a beat; it would be able to answer in context with all of the previous chat history fresh in its memory.</p>

<p>ChatGPT also excels in its ability to provide documentation around its code. This benefits someone with less experience in the field for two reasons. First, it makes it easier to understand the code when ChatGPT writes it so the user knows what is happening and what they may need to change. Second, it makes it easier for the user to understand what the code is doing down the road; if the user returns to this code in a month without working in Flask, then it&#39;s likely they may have forgotten the code or why it was written. Writing good documentation is an excellent habit for all developers, human or otherwise. So it&#39;s great that ChatGPT tends to do it by default. Not everything was clearly documented, but it was much more consistent than I tend to be when documenting my code.
‍</p>

<p>Finally, I was very impressed by ChatGPT&#39;s ability to write code that follows the structure and syntax that Flask applications generally follow. For example, ChatGPT generally recommended that I use the Flask jsonify function to prepare json objects for my responses; since Flask doesn&#39;t automatically serialize and sanitize your data, it is helpful always to make sure to jsonify the data before providing it as content in the response. It could have suggested returning a python dictionary as the json content for the response. Flask typically can handle standard data types within a python dictionary and provide it as a JSON response. Instead, it recommended using jsonify, a safer way to handle the data being returned and accounts for serializing database models straight from python objects into valid json, preventing any implicit serialization issues. ChatGPT had a good handle on some best practices when building standard, simple Flask apps. This was very helpful for someone like me who is coming from a different web server paradigm.</p>

<h2 id="what-were-some-of-the-hiccups-the-bad">What were some of the hiccups (the “bad”)?</h2>

<p>Although ChatGPT had a lot of features and functionality that impressed me, there were many points where it fell short of impressive and even came close to frustrating. One challenge was that it took a lot of work to communicate context with ChatGPT. It was hard to describe my specific file structure to the service, which meant it couldn&#39;t advise me on import errors and where to store files. There were even some instances, such as when describing where to store my .env files, where ChatGPT would tell me to create a .env file in one directory, but then the next code snippet would be written under the assumption that I had placed the .env file in a completely different directory. When it suggested creating multiple files that referenced each other, sometimes it would be clear from the imports that they were located in the same directory. Still, other times it would just give me the file contents and assume I knew where each file should go. At one point, it even caused my application not to work because it wrote in my Dockerfile that I should run the Gunicorn command and point it to my wsgi.py to start my production server, but I had not yet created that file and inadvertently placed it in the wrong directory, causing my entire run command to fail and my Docker container to crash. When I asked ChatGPT what the issue was, it gave me general advice about how to fix import errors, but I needed a clearer way for me to show it my file tree and have it point out the misplaced files.</p>

<p>ChatGPT also tended to play fast and loose with variable names and imports, which is not a big deal when talking about code snippets and abstract questions but can cause significant issues that are hard to debug when applied to a project. In some responses, it would import the entire datetime library. In contrast, in others, it would use “from datetime import datetime”, and these conflicting imports can cause scripts to crash. In other responses, it would use the jsonify function, but forget to import it. So the code would give an import error instead of working. Sometimes it was clear that the response was just an abstract snippet, whereas other times, it would be an entire fully-written file; but in some instances, it was hard to tell which type of response it was providing, as it wouldn&#39;t tell me if it had written the entire file contents or just one piece. With variable names, many of the responses had abstract names like “data” or “result”, which work well in small snippets but are not descriptive enough to capture what is coming back and can often overlap with other code snippets. There was one example where it named the variable “data”, which represented the response content from the request, but then it ran that “data” through a function and named the return value “data” as well, thus overwriting the original “data” variable from the same example. In practice, this can work fine, but for a less experienced developer trying to debug the code from ChatGPT, this can cause confusion and frustration that can be avoided by simply choosing more varied variable names.</p>

<p>Finally, although ChatGPT initially impressed me with its knowledge of Flask syntax and conventions, it found ways to disappoint me in other areas I was more familiar with. It routinely broke PEP style conventions in writing python code and tended to favor javascript-based forms when simple HTML forms were sufficient. It also has limited knowledge about information beyond 2021, so it was working on outdated information, such as not knowing that the match statement was implemented in Python and using var instead of const or let in Javascript. In one particular instance, it led me to some incorrect implementations, as it told me that, in my Docker configuration, I need to expose the ports for all of my microservices to the host machine and then tell each service to communicate through the host machine. The proper solution for my use case is to use the service name in the URL and have each service communicate directly with the other services. Trying to send requests to the host machine is convoluted at best and failed to work when I tried to implement it. I would have spent hours trying to implement this solution that ChatGPT was leading me toward if I had not spoken with a colleague about the best approach and had him walk me through how the Docker services should actually be set up. (Thanks, Evan Matizza!)</p>

<h2 id="what-were-the-major-issues-the-ugly">What were the major issues (the “ugly”)?</h2>

<p>As much as I liked working with ChatGPT, some major issues came up during the project. The most severe of these issues was that ChatGPT can be confidently incorrect and still logically explain their answer even though it&#39;s completely wrong. As an example, when I was working on the service for calculating how much powder and water to mix to make formula, I asked it to make a function that would calculate how much powder and water I should mix to prepare the formula. It explained that since one scoop is 20 calories, I can use the recipe below to calculate the correct calorie density and the amount of water to mix with the powder to prepare the formula. It did not ask any clarifying questions or require further input; it simply stated that its recipe would work. The logic made sense, but I was sure to double-check the math with other accurate services that discussed the calorie density of formula and found that the ChatGPT had errors in its calculation. One scoop of formula contains 45 calories, so the function ChatGPT created for me would result in making more than double the calorie density of what I needed. In the past, we have had issues with feeding formula that&#39;s slightly too dense to my baby, which has resulted in significant constipation and other digestive problems; if I had blindly followed the recipe ChatGPT provided, I could likely have seriously harmed my baby. When working with ChatGPT, it&#39;s important to remember that it could sound 100% confident in its answers, even if there are severe calculations or logical flaws, so verifying the answers with other sources you trust is essential.
‍</p>

<p>Besides that serious issue, there were several times when ChatGPT gave me an answer that was not entirely wrong but was not the right way to approach the problem because of a lack of context. For example, I received an error when I tried to save a string into a database field expecting a bytes object. When I passed the error message along to ChatGPT, it explained that I needed to convert my string into a bytes object and provided code. However, after I looked at the setup and thought about the problem, I realized that the field in my database was set up wrong and that I intended to make it a string field. So, I changed the field type and everything worked. ChatGPT gave me an answer that would have solved the problem, but it wasn&#39;t the correct answer overall because it lacked the context of what I had done and my true goals.</p>

<p>I also had other instances where context was lacking, such as when it told me that I should be returning the database entry directly from my function, but in the context of my application, that function was supposed to return a JSON response. So I needed to return a response object with the database entry jsonified and attached to that response. In another question, I had asked it to make a form that would delete an entry. It made a form that sends a POST request to my endpoint, but then in the suggested code for my endpoint, it set it up to only accept DELETE requests. If I just copy-pasted this code into my app, it would not work, and I would have to spend time tearing apart the suggestion that ChatGPT provided in one cohesive response because that one response was not internally consistent. Even when directly implementing code that ChatGPT suggested, it would sometimes just not work and require the user to be able to figure out what ChatGPT&#39;s mistake was, which could take more knowledge than is required to write it from scratch by themselves.</p>

<p>Finally, I find it difficult to recommend to users with no context of what is going on in the responses it provides. I was fortunate to have a solid foundation in Python and a decent understanding of Flask before starting this project because it takes at least a fundamental understanding of how the language works to piece together the different responses that ChatGPT provides. If you ask it to solve one problem, it might be able to provide all the code necessary for that one solution; but as your application grows and you need to piece together code from different responses, you need to understand what to keep, what to delete, and what to replace. In many of the responses, I would have boilerplate code or general setup code that was repeated but a little differently or with different variable names; if you combined both responses, you might end up duplicating steps at best or breaking your existing code at worst. In one of my inquiries, I could logically piece together the code from multiple responses, but the code stopped working and said there were configuration issues with the database. I asked ChatGPT for help in a few different ways; however, all of its responses just told me that I needed to delete the database and call db.create<em>all() to reset it, which did not work. I did a simple google search for my issue. The first result was a forum post about how you need to call db.create</em>all() only after you import all of your models; otherwise, the database will not be appropriately created; once I refactored my code based on that suggestion, it worked right away. I found other forum posts and articles from 2019 that discussed my exact problem, so I was surprised that ChatGPT could not figure out how to solve my problem. Whether it was a lack of context, a lack of understanding, or a lack of source material that answered the problem, it was clear that there are some problems that ChatGPT won&#39;t know how to solve. It is up to the user to diagnose and understand the problem independently, even when using the code ChatGPT provided.</p>

<h2 id="would-you-recommend-chatgpt-for-writing-code">Would you recommend ChatGPT for writing code?</h2>

<p>Considering all the good, bad, and terrible examples above, I have three answers to whether I recommend using ChatGPT for writing code.</p>

<h3 id="would-i-recommend-chatgpt-for-conceptual-questions-or-questions-about-overarching-themes-yes">Would I recommend ChatGPT for conceptual questions or questions about overarching themes? Yes!</h3>

<p>ChatGPT is excellent at explaining overall concepts with clear words and examples to back up what it is saying. Someone with good general knowledge who wants to learn more can quickly get their questions answered by material that is on-topic and to the point. Suppose you have questions about translating a concept from one language to another or doing everyday tasks within a language. In that case, I have a decent amount of confidence in ChatGPT&#39;s ability to answer those questions. Furthermore, questions you expect to have many answers online, such as questions about common algorithms or programming functionality, should be safe to ask ChatGPT. I always recommend double-checking your answers with verified sources online. Still, it can be a great place to get quick and straightforward answers to general, conceptual questions or as a starting point for research and learning.</p>

<h3 id="would-i-recommend-chatgpt-for-code-examples-and-specific-implementations-maybe">Would I recommend ChatGPT for code examples and specific implementations? Maybe.</h3>

<p>The code examples I asked for during this project were helpful, and I could either use the entire snippet and modify it myself or take parts that I needed and leave the rest behind. It was beneficial for boilerplate or initial examples or when I needed to write a file and knew I would need some standard things and only needed to tweak a few settings. It felt lacking in areas where the technology is newer or tends to change quickly, such as with new language features in Python or with JavaScript in general. As a rule of thumb, if I worried about it changing in the past 3-5 years, I would take anything ChatGPT said with a grain of salt. They may include more recent data as the service evolves. Still, even so, you&#39;re less likely to have an abundance of source material to draw on if you&#39;re asking questions about a language feature that only recently came out. Furthermore, it can make some specific choices in design patterns and library usage without telling you that there are alternatives or why you might choose an alternative. It is up to you to spot places where there might be other choices that you can make and ask ChatGPT about the alternatives.</p>

<h3 id="would-i-recommend-chatgpt-for-solving-problems-from-start-to-finish-no">Would I recommend ChatGPT for solving problems from start to finish? No!</h3>

<p>Although ChatGPT strongly believes that it can solve entire problems, there have been a few instances in this project where it has proven to be false. Furthermore, it may be making assumptions about your goals or the technology, which may not be true, and it will not tell you about those assumptions when it boldly proclaims that it has solved the problem. ChatGPT is missing the critical ability to self-reflect on its answers and explain nuances such as side effects, further questions for the user, and any indication of self-doubt. These skills are critical for any software developer who wishes to provide correct answers; if you want to be sure, then you have to seek out the uncertainty and ensure that all underlying assumptions and foundational knowledge are at least identified, if not challenged and verified.</p>

<p>Overall, ChatGPT is a very powerful tool and can be extremely helpful in the software development process, but it requires a keen eye and strong attention to detail to be used effectively. Although the temptation is there just to ask it questions and take its answers at face value, ChatGPT users must remain diligent and be sure to interpret and verify all responses before putting the code into use. I am very impressed by the state that the service is in currently, and I look forward to seeing it improve and to all the great things you can create when working with ChatGPT!</p>

<p>Note: Since working on this project, the team at OpenAI has been improving ChatGPT&#39;s ability to ask questions and get clarification around code issues. Although I have not seen this feature personally, I am excited to see how ChatGPT evolves and can better address my abovementioned concerns. There may be a part 2 to this article as new features emerge!</p>

<p>‍</p>
]]></content:encoded>
      <guid>https://write.as/thewadegreen/the-following-is-an-blog-post-that-i-wrote-while-working-for-a-previous</guid>
      <pubDate>Tue, 14 Jan 2025 05:56:23 +0000</pubDate>
    </item>
  </channel>
</rss>