<![CDATA[Sean Peters]]>https://snptrs.dev/https://snptrs.dev/favicon.pngSean Petershttps://snptrs.dev/Ghost 5.118Wed, 24 Sep 2025 20:33:14 GMT60<![CDATA[Improving my Git workflow]]>In my early experiments using AI for coding, I’d often get stuck in a spiral of it just hammering away adding more and more code to try and work around a problem that it didn’t understand. Once they start tunnelling, they think the only way out

]]>
https://snptrs.dev/improving-my-git-workflow/6880a2afbc103d0007d89628Wed, 23 Jul 2025 08:55:50 GMT

In my early experiments using AI for coding, I’d often get stuck in a spiral of it just hammering away adding more and more code to try and work around a problem that it didn’t understand. Once they start tunnelling, they think the only way out is to keep going through.

Now I’m getting better at using these tools, I find it easier to spot when they’re going off track and get them to change course. But I realised that if I was in situations where I needed to nuke my whole feature branch to get back on track, I probably wasn’t using Git effectively.

So what I’m doing now is maintaining a temporary working branch off of my feature branch. For example, if I have a feature branch user-auth, I branch t/user-auth off of that. I commit to the temp branch after every meaningful change. Then when I know something’s working, I review the code, tidy it up and squash all those commits into the feature branch.

If everything goes wrong, I either undo a few commits from the temp branch and try again, or trash it and pick up where I left off on the feature branch.

This feels liberating because I don't have to worry about how many commits I’m making or how good my commit messages are. I’m the only person who sees the temp branch, and I make sure whatever I merge into the feature branch is of good enough quality to later do a PR into main.

]]>
<![CDATA[Bootcamp weeks 11 and 12: Trail app]]>It's incredible how quickly the past few months have gone. When I started the course and joined the demo day for the cohort who were just finishing, I couldn't believe I'd ever produce anything as good as what they'd built. And yet

]]>
https://snptrs.dev/bootcamp-weeks-11-12-trail-app/66f41c022a396c0006201aafMon, 07 Aug 2023 11:00:00 GMT

It's incredible how quickly the past few months have gone. When I started the course and joined the demo day for the cohort who were just finishing, I couldn't believe I'd ever produce anything as good as what they'd built. And yet here we were!

The final project is completely self-driven, from ideation to deployment. It's an opportunity for us to put into practice everything we've learnt over the previous four months.

I was in a group with Eugene, Jessica and Joe. We decided to make a location-based app that finds your five nearest tourist attractions, uses AI to give you a brief history of them, and then generates an audio guide using text-to-speech so that you can listen to it on the move.

Getting started

From the outset, we all agreed that we needed to clearly define the features we wanted and be quite opinionated about what our app is there to do. We realised it would be easy for it to become a bit of a Google Maps clone, and we were clear we didn't want that to happen.

Once we'd decided on the core purpose and features, we started diagramming and wireframing and arrived at a user flow that we were all happy with.

Bootcamp weeks 11 and 12: Trail app
Wireframe of the app's main pages

Building it

We decided to use the MERN stack as we wanted to get more practice with each of those technologies. Although for the features we implemented, we ended up not needing Mongo.

We created:

  • A React frontend. It makes an API call with the user's location to our backend. We used useQuery to handle the requests and caching.
  • A Node/Express backend which handles all the API calls and processes the data so it can be used by the frontend.

We used Jest and Cypress for testing.

Of the services that we researched for generating the place descriptions, we thought Bard would work best as it has access to real-time data, but we couldn't get access to its API at the time. We went with OpenAI for the purposes of building a prototype, but we're planning to switch that once Bard is available.

We also used Google's TTS service as it had the best balance of cost, usability and quality.

The finished product

Overall we were really happy with the finished product. We delivered what we'd planned to build, on-time and well-tested.

Towards the end of the project, I worked on deploying it online. I tested out a few different services, and decided to deploy both the backend and frontend to Railway. It's a fantastic service, and I'll probably do a separate post about how to deploy an Express/React app with it. (I also loved Vercel and am planning to build something in Next.js to try it properly.)

Bootcamp weeks 11 and 12: Trail app
Screenshots of the finished app

Friday of the second week was Demo Day and we had to present our apps to the rest of our cohort, other cohorts, and prospective bootcamp students. It was fantastic to see everyone's projects, and really motivating to see how far we've all come in four months.

A recording of our Demo Day presentation (I come in at 2:50)

And with that, the Bootcamp is done! Now begins the equally hard work of job hunting (and also finally getting to work on the ever-expanding list of side projects I've been desperate to get going with).

💡
Takeaways
1. Having a really clear vision about the app's purpose was useful for keeping us on track. Whenever we felt a bit directionless or couldn't decide whether to add a new feature, being able to return to our mission statement about what the app should be doing always helped get us going in the right direction again.

2. This isn't really news to anyone, but this project reaffirmed to me that having clear, achievable tickets and rigorously managing the Trello board is absolutely key to not losing direction or momentum. Once we figured out a prioritisation method that we were all happy with, managing out workflow became a much easier.
🤔
Biggest challenges
1. Every API that we wanted to use worked in a completely different way, and even figuring out the basics of how to authenticate with each of them was quite time-consuming. Even APIs from the same provider can be completely different (we used totally different authentication methods for Google's Places and TTS APIs, for example). In future, I'll make sure I prioritise learning how particular APIs work right at the start of the project; it'll save a lot of headaches further down the line.

2. ChatGPT can't be relied on to generate accurate descriptions. We knew this before we started – it's designed to sound convincing, not to be accurate. But I think we were all surprised but just how convincingly it makes up complete nonsense. I found myself saying "Wow, I never knew that thing near my house had such an interesting history," only to discover that it was completely made up. I'm currently testing some different AI models to see if any of them are better are dealing with real-world locations.

3. Writing Cypress tests proved quite difficult for the components that query the user's location. I need to do some more research into better ways of mocking geodata, or figure out how to get Cypress to play nicer with the browser's location services.
]]>
<![CDATA[Bootcamp weeks 8 and 9: Acebook]]>Time for another group project! I was in a team with Arbnor, Heather, Jessica, Khuslen, Osman and Shoaib.

The brief was to create a simple social networking site, allowing users to register, log in and out, create posts, upload images and view a feed of other users' content.

We

]]>
https://snptrs.dev/bootcamp-weeks-8-9-acebook/66f41c022a396c0006201ab0Sun, 16 Jul 2023 11:00:00 GMT

Time for another group project! I was in a team with Arbnor, Heather, Jessica, Khuslen, Osman and Shoaib.

The brief was to create a simple social networking site, allowing users to register, log in and out, create posts, upload images and view a feed of other users' content.

We were asked to use the MERN stack (MongoDB, Express, React, Node), and Makers gave us some basic code (mainly for parts of the authentication, routing and testing) to get started.

Getting started

We made a collective decision to spend the first couple of days learning and planning, and didn't start actually coding until day three.

We started by diving into the existing codebase, writing some tests to understand how different bits of it work, and creating some sequence diagrams and wireframes.

Bootcamp weeks 8 and 9: Acebook
Initial diagram to help understand the user flow and class interactions

Tech insights

There were lots of interesting technical aspects to this project, but I'm going to focus on three specific parts: authentication, image uploads, and the database.

Authentication

In the basic code that Makers gave us, there was already a JWT token generator and checker implemented as middleware in the Express server. We decided to stick with that as it worked pretty well, and we built our registration and login functions around that.

I'd spent some time learning about authentication for the Chitter challenge and I was familiar with how to hash and validate passwords with BCrypt, so I led on implementing most of this functionality.

Although it worked well, we had to debug quite a few issues with tokens not being properly invalidated when they expired, and components not re-rendering properly when a user logged out. For future projects, I'd try to either use a third-party authentication service, or investigate what good libraries are available to handle some of it.

Image uploads

We wanted users to be able to attach photos to their posts, and also upload profile photos when they registered. None of us had much experience with handling file uploads, and Heather took the lead on investigating what options were available.

We ultimately decided to use Multer as middleware in our Express server to handle the uploads. We were planning to then store and serve the images from Firebase, but we ran out of time and ended up just storing them in our server's filesystem instead. Definitely not an approach we'd roll out to production, but it worked fine for demo purposes.

MongoDB

None of us had used MongoDB before, so I took on the task of figuring out how best to use it for this project. Shout out to this excellent tutorial which gave me enough information to get going with it.

Although it was tempting to retreat to our comfort zone and try and make Mongo work like a relational SQL database, we all agreed that we wanted to try and do things the Mongo way and get the most out of the way it worked.

One example is how we set up our Posts collection. In a relational database, we'd have created separate tables for posts, comments and likes, and then linked them all together. Instead of that, our Posts collection ended up having comments and likes fields which are just arrays, and we push new comments and likes into those (and they each have user fields which reference our Users collection).

There are definitely pros and cons to both approaches, but for our purposes and given the rest of the tech stack we were using, MongoDB worked fantastically well (and I was grateful to have a couple of weeks off from figuring out how to construct massive join queries in SQL!).

The finished product

We were really pleased with the end product. It had all the functionality we'd set out to include, and it was well tested on the backend with Jest and on the frontend with Cypress.

The code we produced was clean and well planned, and I'm pretty sure I'll reuse some of it in future projects whenever I need to implement social functionality.

GitHub - snptrs/bootcamp-acebook
Contribute to snptrs/bootcamp-acebook development by creating an account on GitHub.
Bootcamp weeks 8 and 9: Acebook
💡
Takeaways
1. MongoDB is great! It just worked seamlessly and fits so logically into a JS app like this. I found myself evangelising about it to anyone who would listen.

2. I need to spend a bit of time investigating options for hosting images. Once we started to dive into it, there was so many potentail solutions it was a bit overwhelming. Having a couple of go-to options in my back pocket would be useful for when I next work on a project that needs robust image processing and hosting.

3. We had really clear goals for which features we wanted to implement, and we stuck pretty rigidly to our Trello tickets. If we hadn't been so organised, we definitely wouldn't have finished all the features on time.
🤔
Biggest challenges
1. Learning enough React to be able to build this application in less than two weeks was challenging. But taking a couple of days at the start of the project to try and learn as much about it as we could definitely paid dividends later on. (I've subsequently done a Frontend Masters React course which was brilliant, and I'm now pretty comfortable with it.)
]]>
<![CDATA[Bootcamp week 7: Frontend JavaScript]]>Having focused mainly on learning the basics of JavaScript and running it in Node last week, this week we started to focus more on the frontend. The learning objectives for this week were:

  • Test-drive a simple Javascript program running in a web browser, using modern JS build tools.
  • Use the
]]>
https://snptrs.dev/bootcamp-week-7-frontend-javascript/66f41c022a396c0006201aaeSun, 25 Jun 2023 11:00:00 GMT

Having focused mainly on learning the basics of JavaScript and running it in Node last week, this week we started to focus more on the frontend. The learning objectives for this week were:

  • Test-drive a simple Javascript program running in a web browser, using modern JS build tools.
  • Use the DOM API to build a web user interface for this program.
  • Build a single-page web application fetching and updating remote data using JS.

I've been using HTML and CSS for a long time, so I was already pretty comfortable with concepts like the DOM, events and how to use the browser's developer tools. Where it got trickier though was having to create both a backend and a frontend and have them interact with one another. I could really feel all the knowledge I've picked up over the course so far coming together to help me with that.

TDD was also a lot more challenging this week. We still used Jest for everything, and I'm pretty comfortable with it now, but it felt like there were a lot of plates to keep spinning when switching between mocking API interactions, testing DOM elements, and then producing integration tests.

News headlines project

The final project for the week was to create a news app that fetches the latest stories from the Guardian API and generates a summary of them using AI.

Although the Guardian API documentation looks like it hasn't been updated for several decades, it was surprisingly easy to get up and running with it and pull in the latest headlines.

To generate summaries of the articles, I tested out a few different options. The one that gave the best results was Kagi's Universal Summariser (as a sidenote, Kagi is a fantastic search engine that I happily pay for). I really struggled to get it working when calling the API from the frontend though (another good reason for creating a simple backend for my app - see takeaways below for more on that). So in the end I used OpenAI. The quality of the summaries isn't great, although I could probably improve them by spending some time tuning the prompt.

The most challenging part was getting the layout working. I had very little experience with CSS layout, so I spent a lot of time learning Flexbox. Once I knew what I was doing, it was really simple to create a grid of cards for the headlines.

It was a really enjoyable project, and one I plan to return to and develop further.

GitHub - snptrs/news-summary-challenge
Contribute to snptrs/news-summary-challenge development by creating an account on GitHub.
Bootcamp week 7: Frontend JavaScript
💡
Week 7 takeaways

1. When you're interacting with an API from a frontend app, it's a real pain to manage authentication without accidentally exposing credentials. For the purposes of testing my news summary app, I just passed keys for the Guardian and OpenAI APIs in the query string. If I decided to deploy a production version of this, I'd need to create a simple backend that handled to API calls so I could store the credneitals as environment variables.
🤔
Biggest challenges

1. I found working with a monorepo much more confusing than I thought I would. Trying to keep track of what was happening in the backend versus the frontend, making sure the right servers and build process were running for each, and catching errors in the relevant consoles was all conceptually quite challenging.

]]>
<![CDATA[Bootcamp week 6: JavaScript fundamentals]]>It was all-change this week as we switched from Ruby to JavaScript. The learning objectives for the week were:

  • Test-drive a simple JavaScript program using Node.
  • Explain how asynchronous programming is different from synchronous, blocking programming.
  • Apply a coherent process to learn a new language.

Overall it was a pretty

]]>
https://snptrs.dev/bootcamp-week-6-javascript/66f41c022a396c0006201aadSat, 17 Jun 2023 14:59:00 GMTIt was all-change this week as we switched from Ruby to JavaScript. The learning objectives for the week were:

  • Test-drive a simple JavaScript program using Node.
  • Explain how asynchronous programming is different from synchronous, blocking programming.
  • Apply a coherent process to learn a new language.

Overall it was a pretty tough week, but also one of the most useful weeks of the course so far.

Having started to get fairly comfortable in Ruby, it was initally quite demoralising to suddenly be back at the start with a new language, not knowing how to even do ‘Hello, world!’ or FizzBuzz. It was a real test of resillience to have to push through and get my head around basic concepts all over again.

But after a couple of days I had a bit of an epiphany and realised that the fundamentals are very similar across both languages. I started creating a cheatsheet to compare the similarities and differences. Although there are already lots of  similar cheatsheets available, creating it myself forced me to really understand the concepts and research things in the Ruby and JavaScript documentation.

The most challenging part was trying to understand asynchronous programming. It’s a big mindset shift from working with a synchronous language like Ruby. Yevhen and I spent hours pairing and trying to create passing tests for a simple Pokédex that retrieved data from an API. Small mistakes like not correctly returning a value from a promise, or incorrectly chaining .then statements constantly tripped us up.

By the end of the week, I was comfortable enough with JavaScript to start accessing data from the OpenWeather API, and creating an Express server to enable interaction with a project I'd created earlier in the week.

Bowling challenge in JavaScript

It feels like I'm never going to escape from the bowling scorecard! The weekend challenge for this week was to rewrite the scorecard I created the previous week in Ruby, but this time in client-side JavaScript.

It was relatively easy to translate the classes and methods from Ruby into JS. Adding a frontend was a bit trickier though, as we hadn't learnt about using templates with Express yet. I did some research and ended up using Handlebars. I created a simple layout in HTML, and then use Handlebars to populate the scores after each turn.

With benefit of hindsight and having now learnt a bit more about JavaScript, if I were to do this challenge again I'd do it in React. It would be much easier to set this up as React componenents and use hooks to refresh the scores.

Rendering the template server-side with Handelebars was a good learning experience though, and I'm starting to understand the pros and cons of both approaches depending on the type of project now.

💡
Week 6 takeaways
1. Jest is similar enough to RSpec that it was pretty easy to get up and running with JavaScript tests. In fact, mocking seems more straightforward in Jest. Even testing interaction with DOM elements was fairly simple. It seems like the most challenging aspect of testing is coming up with tests that actually test the right things; I definitely wrote a few tests this week that weren't testing what I thought they were testing.
🤔
Biggest challenges
1. Some of the basics that are so fundamental to JavaScript are quite tricky to get your head around at first. Asynchronicity is a bit mindblowing when you're used to working in a syncronous language. Even the concept of using callback functions takes a lot of getting used to. It's worthwhile taking the time to really understand these concepts from the outset.
]]>
<![CDATA[Bowling challenge]]>The final challenge for week five was to create a bowling scorecard program. Conceptually, this was the most difficult project so far and it required a lot of research and planning.

The requirements were:

  • Count and sum the scores of a bowling game for one player.
  • Create it as a
]]>
https://snptrs.dev/bootcamp-bowling-challenge/66f41c022a396c0006201aabMon, 12 Jun 2023 08:09:26 GMT

The final challenge for week five was to create a bowling scorecard program. Conceptually, this was the most difficult project so far and it required a lot of research and planning.

The requirements were:

  • Count and sum the scores of a bowling game for one player.
  • Create it as a terminal app using Ruby.
  • No database backend needed.

Why is bowling scoring so tricky?

I'd never thought about how bowling scores are calculated, but when I saw this challenge I assumed it must be fairly straightforward. It isn't. A lot of the complexity comes from the fact that when you get a strike or a spare in a frame, the  score for that frame isn't calculated until the next one or two balls have been bowled. That means you're often going back to previous frames and updating their scores.

To add extra complexity, the first nine frames basically work the same way (two bowls per frame, or one if you get a strike), but the tenth frame can have up to three bowls.

I started by watching some YouTube videos about bowling scoring. (As a result, my  feed is now full of bowling content. Gotta love the algorithm!) I then diagrammed the first couple of frames of a game to help me understand the logic.

Bowling challenge
My diagram for the first two frames of a bowling game

Designing the application

I initially thought I'd use an array of hashes to store the ball, frame and bonus scores. I started sketching that out, but it was clear that it would quickly get difficult to manage. It also didn't feel right to separate the data from the methods like that. The essential unit of the game is a frame, so it felt more logical to take a properly object-oriented approach and create instances for each frame.

Bowling challenge
Class diagram for the bowling score app

I designed a class system that separated the various elements into:

  • Frame which is a model class and holds the score for each frame, along with methods like .strike? that can be called by the other classes to determine if a particular frame contains a strike.
  • Application which creates 10 Frames when the application is first run, and contains a run loop which calls the Gameplay methods.
  • Gameplay contains various methods to prompt for and process terminal IO, and determine whether the game is over.
  • Scorecard has various methods to calculate frame and game scores, and apply frame bonuses after strikes and spares.

Final product

I tried a few different ways of displaying the output, but I wasn't happy with any of them. There's surpsingly high information density in a traditional bowling scorecard, and it's hard to replicate that in a different format. So I decided to figure out how to draw a proper scorecard template in the terminal.

Bowling challenge

I started by drawing a single frame in ASCIIFlow, then broke that down into template methods. There's some slightly clunky code in there, and if I get a chance to go back and refactor, I'd look at making better use of map to re-sort the array elements into the correct order. Overall though, I was surprised and pleased that I managed to get the formatting to work.

GitHub - snptrs/bootcamp-bowling-challenge
Contribute to snptrs/bootcamp-bowling-challenge development by creating an account on GitHub.
Bowling challenge
💡
Key takeaways
1. Taking the time to properly learn how bowling scoring works before I started planning the application paid dividends. If I'd started coding before I understood the logic, I know I'd have ended up needing to scrap the code and start again.

2. This is one of the first projects I've done where I've truly understood the benefits of object-oriented programming. Being able to call methods like .frame_score from within the frame is such a neat and efficient way of approaching things.
🗒️
Still to do
- A couple of the methods are in the wrong classes. .final_score needs to move from Gameplay into ScoreCard, for example.
- Drawing the scorecard could be refactored to make it simpler.
- Everything is unit tested, but I need to implement more integration testing (particularly for terminal IO).

]]>
<![CDATA[Bootcamp week 5: Group project]]>This week we did the first group project of the course. The learning objectives were:

  • Learn to work and communicate effectively as part of a team to build a web application.
  • Learn to break down projects into tasks and assign them to pairs.
  • Learn to use agile ceremonies to organise
]]>
https://snptrs.dev/bootcamp-week-5-group-project/66f41c022a396c0006201aacSun, 11 Jun 2023 19:02:00 GMT

This week we did the first group project of the course. The learning objectives were:

  • Learn to work and communicate effectively as part of a team to build a web application.
  • Learn to break down projects into tasks and assign them to pairs.
  • Learn to use agile ceremonies to organise your work and improve your processes.
  • Learn to use the developer workflow to plan, implement and peer-review features.

I was in a group with four great teammates: Arbnor, Heather, Osman and Shoaib. Our project for the week was to build a ‘MakersBnB’. We used Ruby, Sinatra and PostgreSQL for the backend, and some fairly basic HTML and CSS for the frontend.

Workflow

On Monday, we all got together to review the guidance from Makers and agree how we were going to approach the project.

We decided we’d have a standup every morning at 10am, and a retro every afternoon at 5pm. We also broke the week up into three tiny sprints to try and get a flavour of the Agile workflow.

The first tasks was to take the requirements we’d been given and turn them into user stories. We then broke those stories down into tasks and added them to a Trello board.

Bootcamp week 5: Group project

Once we’d agreed the tasks, we split into pairs and rotated the groups for each sprint. I focused slightly more on the backend, as a lot of what I’d done the previous week for the Chitter challenge (like authentication, session management and some of the database tasks) meant I could help get the basics up and running fairly quickly.

I paired with Osman for most of the week. We made a great team, bouncing ideas off of each other and suggesting alternative approaches whenever we got stuck.

The finished product

We managed to implement all the core functionality by the end of the week: hosts could list properties and approve bookings, and guests could find somewhere to stay and submit a booking request.

Bootcamp week 5: Group project

Given slightly more time, the next steps would have been to improve the design, implement better UI features (like a proper avaiability calendar), and add email and SMS booking confirmations.

Overall, we were really pleased with the final product and learnt a lot about effective ways of working together on projects like this.

💡
Week 5 takeaways
1. Regular standups and retros are massively useful for aligning with the rest of the team and helping each other overcome any obstacles. At first it seemed like a lot of time to take out of each day, but it paid dividends and meant we were all really clear about what we should be working on.

2. Although we all had slightly different visions of what the end product should be, we were happy to compromise and make sure that everyone got to contribute equally. We ended the week as a happy team and would all be keen to work together again.

3. It was important to be realistic about what we could achieve in the time available. We decided on the first day that we would focus on creating a good MVP with all the basic requirements, and add bells-and-whistles after that was done. That turned out to be the right approach, as we ended up being really pushed for time to even get the MVP completed.
🤔
Biggest challenges
1. Creating tasks that are clear, specific and achievable within a sprint is key to success, and also really difficult. We oscilated between having tasks that were too broad that ended up taking all week, and tasks that were so small and specific that we could finish them within half an hour.
]]>
<![CDATA[Bootcamp week 4: Web applications]]>Everything we've learnt so far came together this week and we finally got to create some actual web apps! 🥳

Topics for the week included:

  • Understanding the basics of HTTP requests and responses.
  • Using Sinatra to create routes and serve webpages.
  • Writing unit and integration tests for web
]]>
https://snptrs.dev/bootcamp-week-4-web-applications/66f41c022a396c0006201aaaMon, 05 Jun 2023 20:25:29 GMT

Everything we've learnt so far came together this week and we finally got to create some actual web apps! 🥳

Topics for the week included:

  • Understanding the basics of HTTP requests and responses.
  • Using Sinatra to create routes and serve webpages.
  • Writing unit and integration tests for web applications.
  • Deploying database-driven apps to cloud hosting platforms.

Everyone seemed to enjoy this week more than last week, and the workload was more manageable. It's been a definite morale-boost to get a glimpse of what all this learning and endless hours of testing and debugging are training us be able to do.

Chitter project

The final project for the week was to build a basic Twitter clone. The requirements were for users to be able to:

  • Register and log in.
  • Publish ‘Peeps’ and view a timeline of all the posts.
  • Tag other users who’d then get an email notification (this was a stretch requirement, but I managed to implement a basic version of it).
Bootcamp week 4: Web applications

The database for this project was more simple than for last week's Shop Manager app. I just needed users and peeps tables, with a one-to-many relationship between then. If I were to implement proper threaded replies, I'd re-think the database schema as I think it might be more efficient to add a join table.

I used the bcrypt gem to hash and check user passwords, and Sinatra sessions to keep track of user login status. If a logged-out user tries to post a Peep, they’ll be redirected to the login screen.

Once I’d got the MVP up and running, I created a branch to work on the email notification feature. I really wanted to try and implement it, but didn’t think I’d have time to complete it over the weekend, so I developed it in a branch so that it wouldn’t affect my main app.

I used Mailgun to send notifications, and wrote a very (very) basic method to match @mentions at the start of a Peep. I then updated my Peep creation method to pass all new posts through this.

I was really pleased with the final product. I even added a proper README with deploy instructions. I can’t imagine anyone would want to use this (slightly clunky and fairly flaky) app, but it’s there if anyone wants it!

💡
Week 4 takeaways
1. I learnt a lot from the Chitter project about encrypting and validating passwords, managing user sessions and sending transactional emails. bcrypt is amazing!

2. Plan, plan, plan! I produced a lot of code this week, and with the number of different challenges and projects there were to juggle, it would have got really confusing if I hadn’t planned effectively. I’ve realised that spending lots of time of designing database schemas and application classes pays dividends further down the line.

3. I had a bit of an epiphany this week about test-driven development. Up to now, I've felt like it was a bit of a pain to have to keep writing tests before I actually produce any code. But it all seemed to click into place this week, and I’ve realised it actually speeds up the development process (and saves time debugging) if you just put in the effort up front to write good tests.
🤔
Biggest challenges
1. I'm not doing a great job of tracking learning objectives (or updating my TIL). I need to try and set aside some time every day to reflect on what I've learnt.
]]>
<![CDATA[Bootcamp week 3: Databases]]>This week we started learning about databases. Using Ruby and PostgreSQL, we completed a range of modules and challenges starting with simple single-table designs, right through to more complex multi-table joins.

It felt like a step up in difficulty, and most of us found it challenging to get through all

]]>
https://snptrs.dev/bootcamp-week-3-databases/66f41c022a396c0006201aa9Sun, 28 May 2023 20:00:00 GMT

This week we started learning about databases. Using Ruby and PostgreSQL, we completed a range of modules and challenges starting with simple single-table designs, right through to more complex multi-table joins.

It felt like a step up in difficulty, and most of us found it challenging to get through all the content. But working through the many (many!) errors I encountered during the week really helped develop my testing and debugging skills, and by the end of the week I was feeling fairly confident about creating schemas, seeds and SQL queries.

There were also plenty of opportunities to practice skills I started learning over the previous couple of weeks, including analysing user stories, creating design documents, and making diagrams to visualise how all the components fit together.

Shop Manager project

The final project of the week was to create a basic retail stock and order management system using Ruby.

Bootcamp week 3: Databases

I started off by designing the tables, classes and methods. For the Postgres database, I created orders and items tables, and an items_orders join table.

I used the colorize gem to spruce up the terminal output. I also created a Format class to handle output. It's something I started thinking about in the previous week's challenge, and it seems sensible to separate out all the repetitive spacing and tweaks needed to try and make the terminal output more reabable.

class Format
  def string(text = "", color = :default, spacing = "")
    return if text == ""
    text = text.colorize(color)
    text = "\n#{text}" if spacing == :pad || spacing == :before
    text = "#{text}\n" if spacing == :pad || spacing == :after
    return text
  end
  
  def currency(price)
    return sprintf("£%.2f", price)
  end
  
  def header(text)
    return string("====== #{text} ======", :red, :before)
  end
end

This lets me do something like Format.string("Lorem ipsum", :cyan, :pad), which will return “Lorem ipsum” in blue with linebreaks before and after.

Overall I was pretty pleased with the finished product. I put a lot of effort into the RSpec tests, and was happy to get 95% test coverage. Given more time, the next steps would be to implement error handling and better input validation.

💡
Week 3 takeaways
1. Debugging by inserting binding.irb breakpoints into my code proved invaluable this week. We learnt about it earlier in the course, but being able to go into methods and see what was actually being returned from database queries saved me a huge amount time and head-scratching.

2. There were lots of points throughout the week when I was completely stumped by a concept. I've decided that if I understand 75% of something, it's better to keep moving ahead as the same concepts will keep being revisted and eventually they click into place. I'm becoming much more comfortable with being in a constant state of confusion!

3. Getting good at reading documentation seems like an important skill to develop. Looking up in the Postgres docs how to do a calculation in a SQL UPDATE statement took me about 30 seconds; it would've taken longer than that to find a decent Stack Overflow answer or wade through a possibly-made-up answer from ChatGPT. Not to say those resources aren't useful, but sometimes just starting with the official docs is the quickest and most reliable route.
🤔
Biggest challenges
1. I needed to mock a lot of Terminal IO in RSpec, and found it challenging to create the right tests when there was lots of input and output. I ended up stubbing some methods when I should have been using output from real classes, just so I could isolate the data and get the tests to pass. Definitely need to do more research into RSpec best-practice. The RSpec Style Guide and Better Specs seem like good starting points.

2. Managing the volume of directories, projects and files I needed to create and keep track of this week was challenging. After spending the first few days juggling a mass of disorganised files, I adopted a ruthless approach to setting up new projects, naming things, and making sure that everything was where I expected it to be.
]]>
<![CDATA[Bootcamp weeks 1 and 2: Golden Square]]>Now we’ve completed the first four weeks of introductory content, the bootcamp got properly underway with the ‘Golden Square’. This is a pathway of content and challenges that introduced us to four of the central concepts we’ll be focusing on during the bootcamp:

  • Test-driven
]]>
https://snptrs.dev/bootcamp-weeks-1-2-golden-square/66f41c022a396c0006201ab1Sun, 14 May 2023 11:00:00 GMT

Now we’ve completed the first four weeks of introductory content, the bootcamp got properly underway with the ‘Golden Square’. This is a pathway of content and challenges that introduced us to four of the central concepts we’ll be focusing on during the bootcamp:

  • Test-driven development (TDD)
  • Object-oriented design (OOD)
  • Debugging
  • Pair programming

We started off learning the basics of TDD in Ruby using RSpec. Then we moved onto designing multi-class systems, and learnt how to apply various debugging techniques. There were pair programming sessions every afternoon, and it was great to get to work with different teammates, figure out different people's learning styles, and try out different approaches to pairing.

Takeaway project

The weekend project at the end of week 2 was to create a takeaway order management system. The requirements were to:

  • Show a menu of available dishes
  • Allow the user to place an order
  • View an itemised receipt
  • Send the user an SMS confirmation.
Bootcamp weeks 1 and 2: Golden Square

I used the colorize gem to make the terminal output a bit nicer. For sending the SMS confirmation, I used Twilio. It was really easy to set up an account, and the API is free for testing purposes (you have to pre-define recipient phone numbers, which was fine for this project). There's an official twilio-ruby gem which I used to handle the API interaction.

It's a really simple application, but I was quite surprised by how much I've already learnt, and was really excited when I received my first order confirmation text message.

GitHub - snptrs/gs-solo-project
Contribute to snptrs/gs-solo-project development by creating an account on GitHub.
Bootcamp weeks 1 and 2: Golden Square
💡
Takeaways
1. Spending time planning classes, methods and tests was really worthwhile. I found that once I'd planned everything out properly, it was really quick to write the actual code.

2. I'd initially thought I'd interact with the Twilio API manually, but once I investigated the official gem, it was clear that it was a much more robust solution to just use that. It would've taken ages to write all the error and exception handling methods myself.
🤔
Biggest challenges
1. The second half of the module involved a lot of mocking in RSpec, which I found pretty challenging at first. Actually implementing the mocks and stubs is straightforward, but I found it a difficult concept to get my head around at first. I had to take a step back and read a few blog posts and watch some YouTube videos to try and understand the basics before going back and implementing them myself.
]]>