Podcasts about byeeeeeee

  • 36PODCASTS
  • 44EPISODES
  • 49mAVG DURATION
  • ?INFREQUENT EPISODES
  • Feb 26, 2025LATEST

POPULARITY

20172018201920202021202220232024


Best podcasts about byeeeeeee

Latest podcast episodes about byeeeeeee

Russell Howard’s Wonderbox

Hear Rachel Riley's plan for pay-as-you-go giant adult prams! You'll find this and all your other must-know insights into Britain's most well-known maths genius in this episode of Five Brilliant Things! Rachel has a passion for all sorts of things and it was pure pleasure to hear her talking about the excitement of travel, of food, and of course, maths. In there there's some really simple ideas as well about how you, who is intimidated by maths, can instantly get better. Have a listen, feel fuzzy, get good at maths. What a way to spend an hour.

Women Out Loud
Ep. 133: Are You a Beacon for Your "Fuck Yes" Clients?

Women Out Loud

Play Episode Listen Later Jan 22, 2025 29:09


Are you showing up as a beacon for your fuck yes clients? This week, I'm pulling back the curtain on how your energy, authenticity, and branding can magnetize the right people into your world. Whether you're running the show solo or gearing up to delegate, this episode dives into how to align your business with your unique ADHD brain.You'll hear stories, strategies, and a little tough love to help you take radical responsibility for how you're showing up. If you've ever felt like the WRONG people are wrong people are being drawn to you—this one's for you.

The Sarah B Show
Byeeeeeee

The Sarah B Show

Play Episode Listen Later Jul 10, 2024 23:28


In this episode of The Sarah B Show - Sarah B talks(as much as she can) about an upcoming new and exciting adventure and says BYEEEE(for now) as she does not know when she will be back to record another episode! Plus more exciting updates on life, health and LOVE(or lack of!) --- Support this podcast: https://podcasters.spotify.com/pod/show/thesarahbshow/support

love byeeeeeee
Hollywood Tramp
#189 Ein letztes Byeeeeeee - Wir sagen Danke & GaLiGrü!

Hollywood Tramp

Play Episode Listen Later Feb 4, 2024 67:16


Wir sagen Bye! Das ist die letzte Hollywood Tramp Podcast Folge in dieser Form. Berry und sein Co-Host Pierre Daily sagen nach vier Jahren: Byeeeeee! Wir möchten uns bei allen Hörer*innen bedanken. Vielen Dank für eure tellonym Nachrichten, eure Treue und Feedback. Wir sehen und hören uns hoffentlich an anderer Stelle wieder. Um nichts zu verpassen folgt uns: Tickets & Dates auf www.hollywoodtramp.de www.instagram.com/hollywoodtramp www.instagram.com/pierredaily

Arizona Cardinals Podcasts
Cardinals Underground - OK, Byeeeeeee

Arizona Cardinals Podcasts

Play Episode Listen Later Dec 5, 2023 47:56 Transcription Available


Now that Paul Calvisi has dried his socks out from the sideline weather in Pittsburgh, he joins Darren Urban and Dani Sureck into some pre-bye breakdown of an important Cardinals win - one that showed the Cards beating the Steelers at their own game in a perfect sendoff before some time off. The trio talk about the defense standing up after a terrible game against the Rams, James Conner's storybook return to the Steel City, Conner's latest “Angry Runs” award, Jonathan Gannon's work to build the culture, Kyler progress, Trey McBride's evolution, Jonathan Ledbetter's Walter Payton award, and the weather still to come in the final two road games.See omnystudio.com/listener for privacy information.

Cardinals Underground
Cardinals Underground - OK, Byeeeeeee

Cardinals Underground

Play Episode Listen Later Dec 5, 2023 47:56 Transcription Available


Now that Paul Calvisi has dried his socks out from the sideline weather in Pittsburgh, he joins Darren Urban and Dani Sureck into some pre-bye breakdown of an important Cardinals win - one that showed the Cards beating the Steelers at their own game in a perfect sendoff before some time off. The trio talk about the defense standing up after a terrible game against the Rams, James Conner's storybook return to the Steel City, Conner's latest “Angry Runs” award, Jonathan Gannon's work to build the culture, Kyler progress, Trey McBride's evolution, Jonathan Ledbetter's Walter Payton award, and the weather still to come in the final two road games.See omnystudio.com/listener for privacy information.

Pete McMurray Show
Sad News? Buh-byeeeeeee MTV News (we didn't even know it was still on-air)

Pete McMurray Show

Play Episode Listen Later May 20, 2023 7:00


MTV News had a great 36 year run-Kurt Loder the original host-The VJ's who did the news-Politics started with the 1992 election-Does MTV still play music videos-Most played artists early days of MTV

The Minoriteas Podcast

Hey! We are back to talk our shit, come join us and hear our mantra for next week! okay BYEEEEEEE!!!

kiki byeeeeeee
His and Her's Podcast
The early bird is five foot five

His and Her's Podcast

Play Episode Listen Later May 2, 2023 62:55


Hey, welcome back to live with Ashley and Kamaira! Todays episode will be covering various topics. Starting off with the late Jerry Springer and boy oh boy so much more! Stay tuned and enjoy the show. Have an amazig week per usual! Stay positive in all that you do. Byeeeeeee

It's Tanya Time
Tanya plays Never Have I Ever!

It's Tanya Time

Play Episode Listen Later Mar 10, 2023 3:33


Hola guys, hope you guys are all safe and healthy! Thanks so much for all your support, I love you guys so much! Byeeeeeee! --- Support this podcast: https://podcasters.spotify.com/pod/show/its-tanya-time/support

Give. Less. Fks. Podcast
#16 - Being Short...& other things!!! (VIDEO)

Give. Less. Fks. Podcast

Play Episode Listen Later Feb 22, 2023 39:39


Skippy, Tugz, and Rus are back with another hilarious episode of Give Less Fks. Thanks to our friends at Finery who have sent us their epic range in non-alcoholic cocktails. Tugz shares a hilarious yarn about the ups and downs of buying slacks, while Rus takes on the punters' fave words in a quickfire 'Spelling Bee with Lee'. The gang also tries a sour cherry shot from Portugal and kick off the " Fk it bucket list" (bungies, live performances and a casual streak??) Plus, Rus shares how he helped his community after the recent cyclone, and the trio sends their thoughts to all those affected. Don't miss this entertaining and heartfelt episode. K...love you...BYEEEEEEE!!! https://linktr.ee/give.less.fks.podcast/ https://www.finerycocktails.co.nz/ https://www.redcross.org.nz/support-us/our-current-appeals/new-zealand-disaster-fund/

We Got This Girl!
Saturday Devotional #1

We Got This Girl!

Play Episode Listen Later Feb 18, 2023 17:19


Hey girls (and a few guys)! Get ready for a devotional every Saturday. Purpose: enter into a new week with a scripture for meditation and prayer. This week is Psalm 19. Byeeeeeee and see you next week! --- Support this podcast: https://anchor.fm/wegotministry/support

Back to the Vax: A Journey Back to Evidence Based Medicine
Back to the Vax S2 E7 Dr Alison Meek and Laura from @Iamlevelingup

Back to the Vax: A Journey Back to Evidence Based Medicine

Play Episode Listen Later Dec 28, 2022 76:43


Dr Alison Meek is a history professor focusing on cults, conspiracy theories, and extremism. She teaches: #HIS2133 Cults/Terrorism #HIS2301 US Survey #HIS3308 Conspiracy Theories at Queens University Laura (@Iamlevelingup on tiktok and now youtube) is a returning guest who left the crunchy life. We feel that leaving the crunchy antivax life was like leaving a cult and so we discuss the parallels with an expert in cult behaviour. Apologies for my mic. I dont know why it was so tinny sounding. Hieeeee! Crunchy antivax brigade, you can leave me all the one star reviews. I take them as a badge of honour. Byeeeeeee! Lydia Greene

The Bike Shed
360: ActiveRecord Models

The Bike Shed

Play Episode Listen Later Nov 1, 2022 28:37


Fellow thoughtboter Sarah Lima joins Joël to discuss an issue Sarah had when she was doing a code review recently: making HTTP requests in an ActiveRecord model. Her concern with that approach was that a class was having too many responsibilities that would break the single-responsibility principle, and that it would make the class hard to maintain. Because the ActiveRecord layer is a layer that's meant to encapsulate business roles and data, her issue was that adding another responsibility on top of it would be too much. Her solution was to extract a class that would handle the whole HTTP request process. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. SQL TRIM() (https://popsql.com/learn-sql/postgresql/how-to-trim-strings-in-postgresql) Iteration as an anti-pattern (https://thoughtbot.com/blog/iteration-as-an-anti-pattern) WET tests (https://thoughtbot.com/blog/the-case-for-wet-tests) thoughtbot code review guidelines (https://github.com/thoughtbot/guides/tree/main/code-review) Side effects in tests (https://thoughtbot.com/blog/simplify-tests-by-extracting-side-effects) Active Resource (https://github.com/rails/activeresource) Different strategies for 3rd party requests (https://thoughtbot.com/blog/testing-third-party-interactions) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. And today, I'm joined by fellow thoughtboter Sarah Lima. SARAH: Happy to be here. JOËL: And together, we're here to share a little bit of what we've learned along the way. So, Sarah, what's new in your world? SARAH: Well, after a year and a half working on the same thoughtbot client, I have rolled off, and I have joined a new team. And I am learning a lot about not only a new codebase but learning to work with a new team. So that's always challenging, and this time it's not different. JOËL: What is something that you like to do when joining a new team to help smooth the onboarding process? SARAH: Well, I think especially getting to know people with one on ones. This time, I didn't do that right away because I had a bunch of time off scheduled right at the beginning of the project. But I did it right after I came back. And I'm learning a lot about my new colleagues, how they like to work, how they learn best. So, for instance, there are some people that like to learn and grow by reading blog posts, reading books, and there are other people that don't like that as much. JOËL: So when you joined the new project, you just reached out to all of these people and set up a few meetings just to get to know them. SARAH: Yeah, exactly. JOËL: That's really good. I've never done that on a project. And now that you've said it, it kind of seems obvious. Maybe I should do that moving forward to get to know new teammates. SARAH: Yeah. And I think it's easier on my project because it's a very small team. There are four of us thoughtboters, and there are just two client developers. So it was easier. JOËL: What about on the code side of things? Are there any tricks you like to do when you're first getting started in a new codebase? SARAH: Well, I think I really enjoy diving in right away, working on something small, and asking questions. I have also found it helpful in the past, especially on larger codebases, that someone that's experienced on a project gives me an overview showing me the quirks. And, of course, a good README is always a good thing to have, and during the process, always be updating the README. In this recent project, it was not different. I opened a lot of PRs to update the README. So that was good to have a PR right on your first day. JOËL: I love that. I think that's usually my goal when I start on a new project is to have a PR the first day that fixes anything in the setup script that has been broken since the last person onboarded or documentation that was wrong. SARAH: Yeah, absolutely. JOËL: It's always a strong first contribution. SARAH: Yeah. What about you, Joël? What's going on? What's new in your world? JOËL: I've been investigating flaky tests, and I ran across a wild bug this week. I had a test that would fail every now and then. And it was pulling some data from Postgres and then doing some transformations on it. And I couldn't figure out why it was failing. It was a complex query. So it was just pulling out not ActiveRecord objects but a raw array of values. At some point, I was putting a PUT statement in the code with the array of values I expected to get and the array I would actually get. And I was surprised to see that there is a field in there that is a float that was rounded to a different number of decimal places. I was like, that doesn't seem right. And so I was digging into it more, and I found out that this decimal value is from a timestamp that is in a file name for an mp4 video file name. And what is happening is that when we're querying the database, we're trying to extract the timestamp out of the file name by dropping the .mp4 file extension. And we're using the SQL TRIM function. Unfortunately, TRIM does not do whatever the original authors thought it does. It doesn't just remove that substring from the end, but instead, it will remove any of those characters, so in my case, any of dot, M, P, or 4 in any combination from the end of the string. So anytime that my timestamp ended in a four, any fours were just getting chopped off. So if it ended in 44.mp4, the 44 would also get removed, not just the .mp4, which meant that randomly whenever a timestamp happened to end in 4, my test would flake. SARAH: Wow. Do you have any idea how much time you spent debugging that? JOËL: Oh, probably took, I'd say, a day, two days. This is spread over a couple of debugging sessions. But eventually, finding that particular location for the bug probably took us a couple of days. In the end, the bug fix for this is just a couple of lines, a couple of days work, and the diff is only a few lines. But I'm sure that the discussion on the PR is going to be really interesting. There's probably going to be a description that is a lot longer than the actual diff. SARAH: Yeah, 100%. [laughs] JOËL: Have you run across any interesting PRs on your new project? SARAH: Yeah, I did. In fact, I recently reviewed a PR that had three interesting main issues that I wanted to address. And I wanted to lead the person that was working on it to a slightly better solution. So the three issues I saw were that the tests that were added were very DRY, so that was making everything a bit difficult to understand. The second one was that I saw one of the ActiveRecord classes was making HTTP requests, and that didn't sound like a good idea to me. JOËL: That is unusual. SARAH: Yes. The third one was that there were a lot of collections being built iteratively where another innumerable method would be a better fit, such as map instead of an each call. JOËL: Oh, this is a classic situation where you're just using each to go through and transform something, and you've got some sort of external array that you're mutating as part of the each. SARAH: Yes. JOËL: There's a great thought article, I believe, by Joe Ferris on Iteration as an Anti-pattern. SARAH: I think it's by Mike Burns. And I have referred to that article. In fact, I had very good articles for two of these three problems. I referred to a bunch of articles about WET tests as opposed to DRY tests, like how striving for tests that are DRY is not a good idea as opposed to telling a whole story in your tests. And I referred to that other article how iteratively building a collection can be an anti-pattern by Mike Burns. But the second issue about HTTP requests I didn't have anything to refer to. Maybe we should write one. JOËL: This reminds me that in the thoughtbot Slack, we have a custom emoji for you should write a blog post about that. And this would probably be a good time to use it. SARAH: Yes. So, Joël, how do you typically handle a PR that is maybe too long, and you have a lot of concerns about it? And how do you handle delivering that feedback? JOËL: Oh, that is a challenge. I've definitely done it poorly in the past. And I think the wrong way to go about that situation is to go thoroughly through the PR and leave 50, 60 comments. That is overwhelming for the other person. And they're going to have a really bad day when they see 50 comments come through. And there's so much that they can't really address the main things you were talking about anyway. So what I generally try to do, and it's kind of nice now that GitHub doesn't immediately publish your comments, is if I realize...like I start putting some more detailed comments, and then I realize, oh, there's going to be a lot, zoom out a little bit, and try to find are there some higher level trends that I can talk about? And maybe even just summarize in a larger comment at the bottom and say, "Hey, I see some larger structural issues," or "This PR is leaning very heavily on a technique that I think is maybe not the best use here. Maybe we should discuss that," instead of digging into maybe the actual implementation details of the code. SARAH: Yeah, funny, you should mention that. I have recently also started doing that, using the summary version of GitHub reviews. And I used to just go file by file and leaving comments right away. And I'm thinking that this is not a good idea, especially when the PR is long. So I think another thing I would do is also call the person to pair and ask questions and understand where the person is coming from and also explain what are your concerns and how you both can get to a better place with that PR. JOËL: That's really important. You have to remember there's another person on the other end of this. I love the idea of reaching out to them directly. Especially if there's a larger conversation to be had around approach or implementation, it's often easier to resolve those directly rather than back and forth in GitHub comments. So you mentioned situations where the PR is really long. Have you ever had to push back on that in some way? SARAH: Yes. Especially when I saw, whoa, that's going to be difficult to understand, that's going to be difficult to review. And I have reached out to the person to say, "Hey, what about we split that PR in two?" Of course thinking about splitting the PR in a way that makes sense, in a way that still delivers our users' value as soon as possible. JOËL: I've been in situations like that where it's a really long PR, and the person has already invested a lot of work into it. And maybe it's even gone through a round of reviews. It feels almost too late to ask them to split up the work. But then I've actually regretted not doing that because there's so much complexity going on that then it doesn't work, or there are some bugs in it. We struggle to ship this, or it might just have to go through so many rounds of review and re-review and re-review. And because the PR is so long, it's a huge commitment for me to re-review it every time. So there are situations I've been in where I wish that before even looking at the code at all, I was like, this is too long. We need to either slim down the story of what's being done. Because sometimes that's what happens is that the ticket is not well-defined, and someone goes in and just sort of keeps adding more code. And it becomes a bit of a big ball of mud. So, either helping to refine the ticket first or splitting the PR rather than actually looking at the code. SARAH: Yeah, and pairing often can also help with that. So especially as consultants, our clients may ask us to work on different projects, and you work alone. And you may have tight deadlines, but I think it's always helpful to find time anyway to help your colleagues as well. JOËL: I like that. I think there's a lot of value in the work that we do, where we collaborate with others in addition to whatever we do solo. So, oftentimes, it's great to pair with people at a client where possible to become involved in the code review process to even get involved in maybe some of the more broader system design conversations, sprint planning. All of those things are really good to jump into more than just getting siloed into working on just a solo feature. SARAH: Yes, 100%. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: So one of the things you mentioned that stood out for you when you were doing some code review recently was making HTTP requests in an ActiveRecord model. Why is that something that sort of caught your eyes, maybe an area to push back on in a particular design? SARAH: That's a good question. My concern with that approach was that our class was having too many responsibilities that would break the SRP principle, the single-responsibility principle, and that would make our class hard to maintain. So the ActiveRecord layer is a layer that's meant to encapsulate business roles and data. So I was worried that adding another responsibility on top of it would be too much. So my idea was that we would extract a class that would handle the whole HTTP request process. JOËL: Yeah, I feel like my instincts typically when I've done third-party integrations is that the ActiveRecord class should not know about the external internet world. It knows about the database. It knows about some of its core model functionality but that knowing about the internet world is somebody else's responsibility and that, ideally, the direction of dependency should flow the other way. So maybe the class that makes an external request knows about the ActiveRecord object if it needs to let's say, instantiate an instance of that model using data from an external request. Or maybe it's even some third-party thing; maybe it's their controller that knows how to make or that will ask another object to make a request to some API and might also make a request to the model and ask it for some database data and then combine those two together. But that the ActiveRecord object only knows about that database area of responsibility and doesn't know that other things are also happening in the system. SARAH: Absolutely. And I was also thinking that that class would have a difficult test to write. So a good idea is to separate our code that is side-effectful into their own classes, and that makes our tests so much easier. JOËL: I actually wrote an article on the topic where one of my realizations at some point was that a lot of the pain points in code are what functional programmers would call side effects, so things like HTTP requests. And these are often things where we need to stub or do other things. And so isolating them as much as possible often simplifies our tests. SARAH: Yeah, certainly. And I refer to that article every time I have the chance. JOËL: Have you encountered the general concept of layered architectures, or hexagonal architectures, or things like that in the world of Rails or maybe elsewhere? SARAH: Not hexagonal architecture. I have heard about it, but I haven't dived into it yet. Can you give us an overview? JOËL: So I've also not worked with an actual hexagonal architecture. But the general idea, I guess, of layered architectures is that you build your code in a variety of layers, and different layers don't have access to or don't know about the ones...and I forget in this model if it's above or below, let's say it's below. So the inner layers don't know about the outer layers, but the outer layers can know about anything below them. And so if the core of your app is the database, your database is most definitely not knowing about anything outside of just its data. And your ActiveRecord models that sit on top of that know about the database, but they don't know if they're being fronted by a web application, or a command line, or anything else. And then, above that, you might have more of a business process layer that knows about the database. It might know about how to make some external requests, but it doesn't know about anything above that. And then, maybe at the final layer, you've got an application layer that handles things like controllers and interactions with users of the site. The core idea is that you split it into layers, and the higher-up layers know about everything below them, but no layer knows about what's above it. I feel like we're loosely applying that to the situation here with ActiveRecord in that it feels like the ActiveRecord layer if you will, shouldn't really know about third-party API requests. SARAH: So, one exception to that is the ActiveResource approach that connects our business objects to REST services. So if you have an external website and you want to connect it via HTTP, you can do it using Rails ActiveResource. JOËL: That is interesting because it functions like an ActiveRecord object, but instead of being backed by the database, it's backed by some kind of API. I almost wonder if...let's refactor our mental model here. And instead of saying that HTTP belongs in a separate layer that's higher up, maybe, in this case, it's almost like a sibling layer. So your ActiveRecord models know about the database, and they make database requests in ActiveResource, or I think there are some gems that provide similar behavior. It might be backed by a particular API, but neither of them should know about the other. So maybe an ActiveResource model should not be making database requests. SARAH: Yes, I like that line of thought. JOËL: I guess the question then becomes, what about interactions between the two where you want to, I don't know, have some kind of association? You know, I don't think I've ever used ActiveResource on a project. SARAH: I did once when trying to work with something close to microservice architecture. So we had a monolith, and we built a small service that was also in Rails, and we needed to consume the data that was stored in the monolith. JOËL: And did you like that approach? SARAH: Yeah. I think in that specific scenario, it was very productive. And I enjoyed a lot the API that Rails provided me via ActiveResources. JOËL: Did you ever have to mix ActiveResource models and ActiveRecord models? SARAH: No, I didn't; thankfully, not. I have never thought about that. JOËL: So maybe in most applications, those two will just sort of naturally fall into maybe separate parts of the app, and they don't need to interact that much. SARAH: Yeah, I think that will be the case. So mixing two of those subjects we're talking about here, that's testing and HTTP requests; we've been having a discussion in our project about the usage of VCR. That's a gem that records your HTTP requests interactions and replays them during tests. We've been discussing if using it is a good idea or not because we've been having issues with cassettes, that's one of VCR's concepts when these cassettes are not valid anymore. So do you have any thoughts on the subject? Maybe that will make a whole episode. JOËL: We could definitely do a whole episode, I think, on testing third-party APIs. VCR is one of multiple different strategies that can be used to not make actual real network requests in your tests which brings some stability. There are also some downsides to it. I have found, in general, that over time, cassettes become brittle. So the idea of VCR is really cool. In practice, I think I've found that a few hand-rolled Webmock stubs usually do the job better for my needs. SARAH: Yeah, I'll be interested in hearing that episode because, at least in my project, we have a lot of HTTP requests to external services, and they return a lot of information. I'm wondering if just dealing with that with Webmock would be too much work. JOËL: One of the really useful things about VCR is that you can just make your request from anywhere, and it will just completely handle it. In some ways, though, I think it maybe hides some of that test pain that we were talking about earlier and allows you to sort of put HTTP in a lot of places that maybe you don't want it to. And by allowing yourself to feel a little bit of that test pain, you can more easily notice the places where maybe an object should not be making a request. Or the actual HTTP logic can be moved to a concentrated place where all the HTTP is done together. And then only that object will need unit tests that actually need to mock the network, and most of your objects are fine. Where it gets interesting is more for things like integration tests, where now you're doing a lot of interactions, and you might have quite a few background requests that need to be made. SARAH: I'm looking forward to the whole episode on this subject because I feel there's so much to talk about. JOËL: There really is. I have a blog post that sort of summarizes a few different common categories of approaches to testing third-party requests, which might be different depending on whether you're doing a unit test or an integration test. But I grouped common solutions into four different categories. We'll make sure to link that in the show notes. So we've been talking a lot about testing. I'm curious when you review PR, do you start with the tests, maybe read through the tests first, and then the implementation? SARAH: That's a good question. I have never thought about starting with tests. I think I'm going to give that a try anytime. But I just start reviewing them like by the first file that comes up. [laughs] JOËL: I'm the same. I normally just do them in order. I have occasionally tried to do a test first, and that is sometimes interesting. Sometimes you read the test and, especially when you don't know what the implementation is going to be, you're like, why is this in the test? And then you jump to the implementation like, oh, that's what's going on. Well, thank you so much, Sarah, for joining us on this whirlwind tour of code review, design of objects, and interacting with HTTP and testing. SARAH: My pleasure. JOËL: Where can people find you online if they would like to follow your work? SARAH: I'm on Twitter @sarahlima_rb. JOËL: We'll make sure to link that in the show notes. And with that, let's wrap up. The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed, or reach me at @joelquen on Twitter, or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeeee!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.

Crown Chronicles
Creating A Space For Self

Crown Chronicles

Play Episode Listen Later Oct 9, 2022 48:21


On this episode of Crown Chronicles, the ladies discuss the importance of creating a space for "self" and maintaining a sense of individuality outside of being a mom, spouse, etc. Thank you to those who continue to engage, listen and support weekly! Please continue to share, comment and tune in weekly! Love Y'all, BYEEEEEEE

space lovey byeeeeeee
The Bike Shed
355: Test Performance

The Bike Shed

Play Episode Listen Later Sep 20, 2022 42:44


Guest Geoff Harcourt, CTO of CommonLit, joins Joël to talk about a thing that comes up with a lot with clients: the performance of their test suite. It's often a concern because with test suites, until it becomes a problem, people tend to not treat it very well, and people ask for help on making their test suites faster. Geoff shares how he handles a scenario like this at CommonLit. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Geoff Harcourt (https://twitter.com/geoffharcourt) Common Lit (https://www.commonlit.org/) Cuprite driver (https://cuprite.rubycdp.com/) Chrome DevTools Protocol (CDP) (https://chromedevtools.github.io/devtools-protocol/) Factory Doctor (https://test-prof.evilmartians.io/#/profilers/factory_doctor) Joël's RailsConf talk (https://www.youtube.com/watch?v=LOlG4kqfwcg) Formal Methods (https://www.hillelwayne.com/post/formally-modeling-migrations/) Rails multi-database support (https://guides.rubyonrails.org/active_record_multiple_databases.html) Knapsack pro (https://knapsackpro.com/) Prior episode with Eebs (https://www.bikeshed.fm/353) Shopify article on skipping specs (https://shopify.engineering/spark-joy-by-running-fewer-tests) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. And today, I'm joined by Geoff Harcourt, who is the CTO of CommonLit. GEOFF: Hi, Joël. JOËL: And together, we're here to share a little bit of what we've learned along the way. Geoff, can you briefly tell us what is CommonLit? What do you do? GEOFF: CommonLit is a 501(c)(3) non-profit that delivers a literacy curriculum in English and Spanish to millions of students around the world. Most of our tools are free. So we take a lot of pride in delivering great tools to teachers and students who need them the most. JOËL: And what does your role as CTO look like there? GEOFF: So we have a small engineering team. There are nine of us, and we run a Rails monolith. I'd say a fair amount of the time; I'm hands down in the code. But I also do the things that an engineering head has to do, so working with vendors, and figuring out infrastructure, and hiring, and things like that. JOËL: So that's quite a variety of things that you have to do. What is new in your world? What's something that you've encountered recently that's been fun or interesting? GEOFF: It's the start of the school year in America, so traffic has gone from a very tiny amount over the summer to almost the highest load that we'll encounter all year. So we're at a new hosting provider this fall. So we're watching our infrastructure and keeping an eye on it. The analogy that we've been using to describe this is like when you set up a bunch of plumbing, it looks like it all works, but until you really pump water through it, you don't see if there are any leaks. So things are in good shape right now, but it's a very exciting time of year for us. JOËL: Have you ever done some actual plumbing yourself? GEOFF: I am very, very bad at home repair. But I have fixed a toilet or two. I've installed a water filter but nothing else. What about you? JOËL: I've done a little bit of it when I was younger with my dad. Like, I actually welded copper pipes and that kind of thing. GEOFF: Oh, that's amazing. That's cool. Nice. JOËL: So I've definitely felt that thing where you turn the water source back on, and it's like, huh, let's see, is this joint going to leak, or are we good? GEOFF: Yeah, they don't have CI for plumbing, right? JOËL: [laughs] You know, test it in production, right? GEOFF: Yeah. [laughs] So we're really watching right now traffic starting to rise as students and teachers are coming back. And we're also figuring out all kinds of things that we want to do to do better monitoring of our application, so some of this is watching metrics to see if things happen. But some of this is also doing some simulated user activity after we do deploys. So we're using some automated browsers with Cypress to log into our application and do some user flows, and then report back on the results. JOËL: So is this kind of like a feature test in CI, except that you're running it in production? GEOFF: Yeah. Smoke test is the word that we've settled on for it, but we run it against our production server every time we deploy. And it's a small suite. It's nowhere as big as our big Capybara suite that we run in CI, but we're trying to get feedback in less than six minutes. That's sort of the goal. In addition to running tests, we also take screenshots with a tool called Percy, and that's a visual regression testing tool. So we get to see the screenshots, and if they differ by more than one pixel, we get a ping that lets us know that maybe our CSS has moved around or something like that. JOËL: Has that caught some visual bugs for you? GEOFF: Definitely. The state of CSS at CommonLit was very messy when I arrived, and it's gotten better, but it still definitely needs some love. There are some false positives, but it's been really, really nice to be able to see visual changes on our production pages and then be able to approve them or know that there's something we have to go back and fix. JOËL: I'm curious, for this smoke test suite, how long does it take to run? GEOFF: We run it in parallel. It runs on Buildkite, which is the same tool that we use to orchestrate our CI, and the longest test takes about five minutes. It signs in as a teacher, creates an account. It creates a class; it invites the student to that class. It then logs out, logs in as that student creates the student account, signs in as the student, joins the class. It then assigns a lesson to the student then the student goes and takes the lesson. And then, when the student submits the lesson, then the test is over. And that confirms all of the most critical flows that we would want someone to drop what they were doing if it's broken, you know, account creation, class creation, lesson creation, and students taking a lesson. JOËL: So you're compressing the first few weeks of school into five minutes. GEOFF: Yes. And I pity the school that has thousands of fake teachers, all named Aaron McCarronson at the school. JOËL: [laughs] GEOFF: But we go through and delete that data every once in a while. But we have a marketer who just started at CommonLit maybe a few weeks ago, and she thought that someone was spamming our signup form because she said, "I see hundreds of teachers named Aaron McCarronson in our user list." JOËL: You had to admit that you were the spammer? GEOFF: Yes, I did. [laughs] We now have some controls to filter those people out of reports. But it's always funny when you look at the list, and you see all these fake people there. JOËL: Do you have any rate limiting on your site? GEOFF: Yeah, we do quite a bit of it, actually. Some of it we do through Cloudflare. We have tools that limit a certain flow, like people trying to credential stuffing our password, our user sign-in forms. But we also do some further stuff to prevent people from hitting key endpoints. We use Rack::Attack, which is a really nice framework. Have you had to do that in client work with clients setting that stuff up? JOËL: I've used Rack:Attack before. GEOFF: Yeah, it's got a reasonably nice interface that you can work with. And I always worry about accidentally setting those things up to be too sensitive, and then you get lots of stuff back. One issue that we sometimes find is that lots of kids at the same school are sharing an IP address. So that's not the thing that we want to use for rate limiting. We want to use some other criteria for rate limiting. JOËL: Right, right. Do you ever find that you rate limit your smoke tests? Or have you had to bypass the rate limiting in the smoke tests? GEOFF: Our smoke tests bypass our rate limiting and our bot detection. So they've got some fingerprints they use to bypass that. JOËL: That must have been an interesting day at the office. GEOFF: Yes. [laughter] With all of these things, I think it's a big challenge to figure out, and it's similar when you're making tests for development, how to make tests that are high signal. So if a test is failing really frequently, even if it's testing something that's worthwhile, if people start ignoring it, then it stops having value as a piece of signal. So we've invested a ton of time in making our test suite as reliable as possible, but you sometimes do have these things that just require a change. I've become a really big fan of...there's a Ruby driver for Capybara called Cuprite, and it doesn't control chrome with Chrome Driver or with Selenium. It controls it with the Chrome DevTools protocol, so it's like a direct connection into the browser. And we find that it's very, very fast and very, very reliable. So we saw that our Capybara specs got significantly more reliable when we started using this as our driver. JOËL: Is this because it's not actually moving the mouse around and clicking but instead issuing commands in the background? GEOFF: Yeah. My understanding of this is a little bit hazy. But I think that Selenium and ChromeDriver are communicating over a network pipe, and sometimes that network pipe is a little bit lossy. And so it results in asynchronous commands where maybe you don't get the feedback back after something happens. And CDP is what Chrome's team and I think what Puppeteer uses to control things directly. So it's great. And you can even do things with it. Like, you can simulate different time zone for a user almost natively. You can speed up or slow down the traveling of time and the direction of time in the browser and all kinds of things like that. You can flip it into mobile mode so that the device reports that it's a touch browser, even though it's not. We have a set of mobile specs where we flip it with CDP into mobile mode, and that's been really good too. Do you find when you're doing client work that you have a demand to build mobile-specific specs for system tests? JOËL: Generally not, no. GEOFF: You've managed to escape it. JOËL: For something that's specific to mobile, maybe one or two tests that have a weird interaction that we know is different on mobile. But in general, we're not doing the whole suite under mobile and the whole suite under desktop. GEOFF: When you hand off a project...it's been a while since you and I have worked together. JOËL: For those who don't know, Geoff used to be with us at thoughtbot. We were colleagues. GEOFF: Yeah, for a while. I remember my very first thoughtbot Summer Summit; you gave a really cool lightning talk about Eleanor of Aquitaine. JOËL: [laughs] GEOFF: That was great. So when you're handing a project off to a client after your ending, do you find that there's a transition period where you're educating them about the norms of the test suite before you leave it in their hands? JOËL: It depends a lot on the client. With many clients, we're working alongside an existing dev team. And so it's not so much one big handoff at the end as it is just building that in the day-to-day, making sure that we are integrating with the team from the outset of the engagement. So one thing that does come up a lot with clients is the performance of their test suite. That's often a concern because the test suite until it becomes a problem, people tend to not treat it very well. And by the time that you're bringing on an external consultant to help, generally, that's one of the areas of the code that's been a little bit neglected. And so people ask for help on making their test suite faster. Is that something that you've had to deal with at CommonLit as well? GEOFF: Yeah, that's a great question. We have struggled a lot with the speed that our test suite...the time it takes for our test suite to run. We've done a few things to improve it. The first is that we have quite a bit of caching that we do in our CI suite around dependencies. So gems get cached separately from NPM packages and browser assets. So all three of those things are independently cached. And then, we run our suites in parallel. Our Jest specs get split up into eight containers. Our Ruby non-system tests...I'd like to say unit tests, but we all know that some of those are actually integration tests. JOËL: [laughs] GEOFF: But those tests run in 15 containers, and they start the moment gems are built. So they don't wait for NPM packages. They don't wait for assets. They immediately start going. And then our system specs as soon as the assets are built kick off and start running. And we actually run that in 40 parallel containers so we can get everything finished. So our CI suite can finish...if there are no dependency bumps and no asset bumps, our specs suite you can finish in just under five minutes. But if you add up all of that time, cumulatively, it's something like 75 minutes is the total execution as it goes. Have you tried FactoryDoctor before for speeding up test suites? JOËL: This is the gem from Evil Martians? GEOFF: Yeah, it's part of TestProf, which is their really, really unbelievable toolkit for improving specs, and they have a whole bunch of things. But one of them will tell you how many invocations of FactoryBot factories each factory got. So you can see a user factory was fired 13,000 times in the test suite. It can even do some tagging where it can go in and add metadata to your specs to show which ones might be candidates for optimization. JOËL: I gave a talk at RailsConf this year titled Your Tests Are Making Too Many Database Calls. GEOFF: Nice. JOËL: And one of the things I talked about was creating a lot more data via factories than you think that you are. And I should give a shout-out to FactoryProf for finding those. GEOFF: Yeah, it's kind of a silent killer with the test suite, and you really don't think that you're doing a whole lot with it, and then you see how many associations. How do you fight that tension between creating enough data that things are realistic versus the streamlining of not creating extraneous things or having maybe mystery guests via associations and things like that? JOËL: I try to have my base factories be as minimal as possible. So if there's a line in there that I can remove, and the factory or the model still saves, then it should be removed. Some associations, you can't do that if there's a foreign key constraint, and so then I'll leave it in. But I am a very hardcore minimalist, at least with the base factory. GEOFF: I think that makes a lot of sense. We use foreign keys all over the place because we're always worried about somehow inserting student data that we can't recover with a bug. So we'd rather blow up than think we recorded it. And as a result, sometimes setting up specs for things like a student answering a multiple choice question on a quiz ends up being this sort of if you give a mouse a cookie thing where it's you need the answer options. You need the question. You need the quiz. You need the activity. You need the roster, the students to be in the roster. There has to be a teacher for the roster. It just balloons out because everything has a foreign key. JOËL: The database requires it, but the test doesn't really care. It's just like, give me a student and make it valid. GEOFF: Yes, yeah. And I find that that challenge is really hard. And sometimes, you don't see how hard it is to enforce things like database integrity until you have a lot of concurrency going on in your application. It was a very rude surprise to me to find out that browser requests if you have multiple servers going on might not necessarily be served in the order that they were made. JOËL: [laughs] So you're talking about a scenario where you're running multiple instances of your app. You make two requests from, say, two browser tabs, and somehow they get served from two different instances? GEOFF: Or not even two browser tabs. Imagine you have a situation where you're auto-saving. JOËL: Oooh, background requests. GEOFF: Yeah. So one of the coolest features we have at CommonLit is that students can annotate and highlight a text. And then, the teachers can see the annotations and highlights they've made, and it's actually part of their assignment often to highlight key evidence in a passage. And those things all fire in the background asynchronously so that it doesn't block the student from doing more stuff. But it also means that potentially if they make two changes to a highlight really quickly that they might arrive out of order. So we've had to do some things to make sure that we're receiving in the right order and that we're not blowing away data that was supposed to be there. Just think about in a Heroku environment, for example, which is where we used to be, you'd have four dynos running. If dyno one takes too long to serve the thing for dyno two, request one may finish after request two. That was a very, very rude surprise to learn that the world was not as clean and neat as I thought. JOËL: I've had to do something similar where I'm making a bunch of background requests to a server. And even with a single dyno, it is possible for your request to come back out of order just because of how TCP works. So if it's waiting for a packet and you have two of these requests that went out not too long before each other, there's no guarantee that all the packets for request one come back before all the packets from request two. GEOFF: Yeah, what are the strategies for on the client side for dealing with that kind of out-of-order response? JOËL: Find some way to effectively version the requests that you make. Timestamp is an easy one. Whenever a request comes in, you take the response from the latest timestamp, and that wins out. GEOFF: Yeah, we've started doing some unique IDs. And part of the unique ID is the browser's timestamp. We figure that no one would try to hack themselves and intentionally screw up their own data by submitting out of order. JOËL: Right, right. GEOFF: It's funny how you have to pick something to trust. [laughs] JOËL: I'd imagine, in this case, if somebody did mess around with it, they would really only just be screwing up their own UI. It's not like that's going to then potentially crash the server because of something, and then you've got a potential vector for a denial of service. GEOFF: Yeah, yeah, that's always what we're worried about, and we have to figure out how to trust these sorts of requests as what's a valid thing and what is, as you're saying, is just the user hurting themselves as opposed to hurting someone else's stuff? MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! GEOFF: You were talking about test suites. What are some things that you have found are consistently problems in real-world apps, but they're really, really hard to test in a test suite? JOËL: Difficult to test or difficult to optimize for performance? GEOFF: Maybe difficult to test. JOËL: Third-party integrations. Anything that's over the network that's going to be difficult. Complex interactions that involve some heavy frontend but then also need a lot of backend processing potentially with asynchronous workers or something like that, there are a lot of techniques that we can use to make all those play together, but that means there's a lot of complexity in that test. GEOFF: Yeah, definitely. I've taken a deep interest in what I'm sure there's a better technical term for this, but what I call network hostile environments or bandwidth hostile environments. And we see this a lot with kids. Especially during the pandemic, kids would often be trying to do their assignments from home. And maybe there are five kids in the house, and they're all trying to do their homework at the same time. And they're all sharing a home internet connection. Maybe they're in the basement because they're trying to get some peace and quiet so they can do their assignment or something like that. And maybe they're not strongly connected. And the challenge of dealing with intermittent connectivity is such an interesting problem, very frustrating but very interesting to deal with. JOËL: Have you explored at all the concept of Formal Methods to model or verify situations like that? GEOFF: No, but I'm intrigued. Tell me more. JOËL: I've not tried it myself. But I've read some articles on the topic. Hillel Wayne is a good person to follow for this. GEOFF: Oh yeah. JOËL: But it's really fascinating when you'll see, okay, here are some invariants and things. And then here are some things that you set up some basic properties for a system. And then some of these modeling languages will then poke holes and say, hey, it's possible for this 10-step sequence of events to happen that will then crash your server. Because you didn't think that it's possible for five people to be making concurrent requests, and then one of them fails and retries, whatever the steps are. So it's really good at modeling situations that, as developers, we don't always have great intuition, things like parallelism. GEOFF: Yeah, that sounds so interesting. I'm going to add that to my list of reading for the fall. Once the school year calms down, I feel like I can dig into some technical topics again. I've got this book sitting right next to my desk, Designing Data-Intensive Applications. I saw it referenced somewhere on Twitter, and I did the thing where I got really excited about the book, bought it, and then didn't have time to read it. So it's just sitting there unopened next to my desk, taunting me. JOËL: What's the 30-second spiel for what is a data-intensive app, and why should we design for it differently? GEOFF: You know, that's a great question. I'd probably find out if I'd dug further into the book. JOËL: [laughs] GEOFF: I have found at CommonLit that we...I had a couple of clients at thoughtbot that dealt with data at the scale that we deal with here. And I'm sure there are bigger teams doing, quote, "bigger data" than we're doing. But it really does seem like one of our key challenges is making sure that we just move data around fast enough that nothing becomes a bottleneck. We made a really key optimization in our application last year where we changed the way that we autosave students' answers as they go. And it resulted in a massive increase in throughput for us because we went from trying to store updated versions of the students' final answers to just storing essentially a draft and often storing that draft in local storage in the browser and then updating it on the server when we could. And then, as a result of this, we're making key updates to the table where we store a student's answers much less frequently. And that has a huge impact because, in addition to being one of the biggest tables at CommonLit...it's got almost a billion recorded answers that we've gotten from students over the years. But because we're not writing to it as often, it also means that reads that are made from the table, like when the teacher is getting a report for how the students are doing in a class or when a principal is looking at how a school is doing, now, those queries are seeing less contention from ongoing writes. And so we've seen a nice improvement. JOËL: One strategy I've seen for that sort of problem, especially when you have a very write-heavy table but that also has a different set of users that needs to read from it, is to set up a read replica. So you have your main that is being written to, and then the read replica is used for reports and people who need to look at the data without being in contention with the table being written. GEOFF: Yeah, Rails multi-DB support now that it's native to the framework is excellent. It's so nice to be able to just drop that in and fire it up and have it work. We used to use a solution that Instacart had built. It was great for our needs, but it wasn't native to the framework. So every single time we upgraded Rails, we had to cross our fingers and hope that it didn't, you know, whatever private APIs of ActiveRecord it was using hadn't broken. So now that that stuff, which I think was open sourced from GitHub's multi-database implementation, so now that that's all native in Rails, it's really, really nice to be able to use that. JOËL: So these kinds of database tricks can help make the application much more performant. You'd mentioned earlier that when you were trying to make your test performant that you had introduced parallelism, and I feel like that's maybe a bit of an intimidating thing for a lot of people. How would you go about converting a test suite that's just vanilla RSpec, single-threaded, and then moving it in a direction of being more parallel? GEOFF: There's a really, really nice tool called Knapsack, which has a free version. But the pro version, I feel like if you're spending any money at all on CI, it's immediately worth the cost. I think it's something like $75 a month for each suite that you run on it. And Knapsack does this dynamic allocation of tests across containers. And it interfaces with several of the popular CI providers so that it looks at environment variables and can tell how many containers you're splitting across. It'll do some things, like if some of your containers start early and some of them start late, it will distribute the work so that they all end at the same time, which is really nice. We've preferred CI providers that charge by the minute. So rather than just paying for a service that we might not be using, we've used services like Semaphore, and right now, we're on Buildkite, which charge by the minute, which means that you can decide to do as much parallelism as you want. You're just paying for the compute time as you run things. JOËL: So that would mean that two minutes of sequential build time costs just the same as splitting it up in parallel and doing two simultaneous minutes of build time. GEOFF: Yeah, that is almost true. There's a little bit of setup time when a container spins up. And that's one of the key things that we optimize. I guess if we ran 200 containers if we were like Shopify or something like that, we could technically make our CI suite finish faster, but it might cost us three times as much. Because if it takes a container 30 seconds to spin up and to get ready, that's 30 seconds of dead time when you're not testing, but you're paying for the compute. So that's one of the key optimizations that we make is figuring out how many containers do we need to finish fast when we're not just blowing time on starting and finishing? JOËL: Right, because there is a startup cost for each container. GEOFF: Yeah, and during the work day when our engineers are working along, we spin up 200 EC2 machines or 150 EC2 machines, and they're there in the fleet, and they're ready to go to run CI jobs for us. But if you don't have enough machines, then you have jobs that sit around waiting to start, that sort of thing. So there's definitely a tension between figuring out how much parallelism you're going to do. But I feel like to start; you could always break your test suite into four pieces or two pieces and just see if you get some benefit to running a smaller number of tests in parallel. JOËL: So, manually splitting up the test suite. GEOFF: No, no, using something like Knapsack Pro where you're feeding it the suite, and then it's dividing up the tests for you. I think manually splitting up the suite is probably not a good practice overall because I'm guessing you'll probably spend more engineering time on fiddling with which tests go where such that it wouldn't be cost-effective. JOËL: So I've spent a lot of time recently working to improve a parallel test suite. And one of the big problems that you have is trying to make sure that all of your parallel surfaces are being used efficiently, so you have to split the work evenly. So if you said you have 70 minutes worth of work, if you give 50 minutes to one worker and 20 minutes to the other, that means that your total test suite is still 50 minutes, and that's not good. So ideally, you split it as evenly as possible. So I think there are three evolutionary steps on the path here. So you start off, and you're going to manually split things out. So you're going to say our biggest chunk of tests by time are the feature specs. We'll make them almost like a separate suite. Then we'll make the models and controllers and views their own thing, and that's roughly half and half, and run those. And maybe you're off by a little bit, but it's still better than putting them all in one. It becomes difficult, though, to balance all of these because then one might get significantly longer than the other then, you have to manually rebalance it. It works okay if you're only splitting it among two workers. But if you're having to split it among 4, 8, 16, and more, it's not manageable to do this, at least not by hand. If you want to get fancy, you can try to automate that process and record a timing file of how long every file takes. And then when you kick off the build process, look at that timing file and say, okay, we have 70 minutes, and then we'll just split the file so that we have roughly 70 divided by number of workers' files or minutes of work in each process. And that's what gems like parallel_tests do. And Knapsack's Classic mode works like this as well. That's decently good. But the problem is you're working off of past information. And so if the test has changed or just if it's highly variable, you might not get a balanced set of workers. And as you mentioned, there's a startup cost, and so not all of your workers boot up at the same time. And so you might still have a very uneven amount of work done by each worker by statically determining the work to be done via a timing file. So the third evolution here is a dynamic or a self-balancing approach where you just put all of the tests or the files in a queue and then just have every worker pull one or two tests when it's ready to work. So that way, if something takes a lot longer than expected, well, it's just not pulling more from the queue. And everybody else still pulls, and they end up all balancing each other out. And then ideally, every worker finishes work at exactly the same time. And that's how you know you got the most value you could out of your parallel processes. GEOFF: Yeah, there's something about watching all the jobs finish in almost exactly, you know, within 10 seconds of each other. It just feels very, very satisfying. I think in addition to getting this dynamic splitting where you're getting either per file or per example split across to get things finishing at the same time, we've really valued getting fast feedback. So I mentioned before that our Jest specs start the moment NPM packages get built. So as soon as there's JavaScripts that can be executed in test, those kick-off. As soon as our gems are ready, the RSpec non-system tests go off, and they start running specs immediately. So we get that really, really fast feedback. Unfortunately, the browser tests take the longest because they have to wait for the most setup. They have the most dependencies. And then they also run the slowest because they run in the browser and everything. But I think when things are really well-oiled, you watch all of those containers end at roughly the same time, and it feels very satisfying. JOËL: So, a few weeks ago, on an episode of The Bike Shed, I talked with Eebs Kobeissi about dependency graphs and how I'm super excited about it. And I think I see a dependency graph in what you're describing here in that some things only depend on the gem file, and so they can start working. But other things also depend on the NPM packages. And so your build pipeline is not one linear process or one linear process that forks into other linear processes; it's actually a dependency graph. GEOFF: That is very true. And the CI tool we used to use called Semaphore actually does a nice job of drawing the dependency graph between all of your steps. Buildkite does not have that, but we do have a bunch of steps that have to wait for other steps to finish. And we do it in our wiki. On our repo, we do have a diagram of how all of this works. We found that one of the things that was most wasteful for us in CI was rebuilding gems, reinstalling NPM packages (We use Yarn but same thing.), and then rebuilding browser assets. So at the very start of every CI run, we build hashes of a bunch of files in the repository. And then, we use those hashes to name Docker images that contain the outputs of those files so that we are able to skip huge parts of our CI suite if things have already happened. So I'll give an example if Ruby gems have not changed, which we would know by the Gemfile.lock not having changed, then we know that we can reuse a previously built gems image that has the gems that just gets melted in, same thing with yarn.lock. If yarn.lock hasn't changed, then we don't have to build NPM packages. We know that that already exists somewhere in our Docker registry. In addition to skipping steps by not redoing work, we also have started to experiment...actually, in response to a comment that Chris Toomey made in a prior Bike Shed episode, we've started to experiment with skipping irrelevant steps. So I'll give an example of this if no Ruby files have changed in our repository, we don't run our RSpec unit tests. We just know that those are valid. There's nothing that needs to be rerun. Similarly, if no JavaScript has changed, we don't run our Jest tests because we assume that everything is good. We don't lint our views with erb-lint if our view files haven't changed. We don't lint our factories if the model or the database hasn't changed. So we've got all these things to skip key types of processing. I always try to err on the side of not having a false pass. So I'm sure we could shave this even tighter and do even less work and sometimes finish the build even faster. But I don't want to ever have a thing where the build passes and we get false confidence. JOËL: Right. Right. So you're using a heuristic that eliminates the really obvious tests that don't need to be run but the ones that maybe are a little bit more borderline, you keep them in. Shaving two seconds is not worth missing a failure. GEOFF: Yeah. And I've read things about big enterprises doing very sophisticated versions of this where they're guessing at which CI specs might be most relevant and things like that. We're nowhere near that level of sophistication right now. But I do think that once you get your test suite parallelized and you're not doing wasted work in the form of rebuilding dependencies or rebuilding assets that don't need to be rebuilt, there is some maybe not low, maybe medium hanging fruit that you can use to get some extra oomph out of your test suite. JOËL: I really like that you brought up this idea of infrastructure and skipping. I think in my own way of thinking about improving test suites, there are three broad categories of approaches you can take. One variable you get to work with is that total number of time single-threaded, so you mentioned 70 minutes. You can make that 70 minutes shorter by avoiding database writes where you don't need them, all the common tricks that we would do to actually change the test themselves. Then we can change...as another variable; we get to work with parallelism, we talked about that. And then finally, there's all that other stuff that's not actually executing RSpec like you said, loading the gems, installing NPM packages, Docker images. All of those, if we can skip work running migrations, setting up a database, if there are situations where we can improve the speed there, that also improves the total time. GEOFF: Yeah, there are so many little things that you can pick at to...like, one of the slowest things for us is Elasticsearch. And so we really try to limit the number of specs that use Elasticsearch if we can. You actually have to opt-in to using Elasticsearch on a spec, or else we silently mock and disable all of the things that happen there. When you're looking at that first variable that you were talking about, just sort of the overall time, beyond using FactoryDoctor and FactoryProf, is there anything else that you've used to just identify the most egregious offenders in a test suite and then figure out if they're worth it? JOËL: One thing you can do is hook into Active Support notification to try to find database writes. And so you can find, oh, here's where all of the...this test is making way too many database writes for some reason, or it's making a lot, maybe I should take a look at it; it's a hotspot. GEOFF: Oh, that's really nice. There's one that I've always found is like a big offender, which is people doing negative expectations in system specs. JOËL: Oh, for their Capybara wait time. GEOFF: Yeah. So there's a really cool gem, and the name of it is eluding me right now. But there's a gem that raises a special exception if Capybara waits the full time for something to happen. So it lets you know that those things exist. And so we've done a lot of like hunting for...Knapsack will report the slowest examples in your test suite. So we've done some stuff to look for the slowest files and then look to see if there are examples of these negative expectations that are waiting 10 seconds or waiting 8 seconds before they fail. JOËL: Right. Some files are slow, but they're slow for a reason. Like, a feature spec is going to be much slower than a model test. But the model tests might be very wasteful and because you have so many of them, if you're doing the same pattern in a bunch of them or if it's a factory that's reused across a lot of them, then a small fix there can have some pretty big ripple effects. GEOFF: Yeah, I think that's true. Have you ever done any evaluation of test suite to see what files or examples you could throw away? JOËL: Not holistically. I think it's more on an ad hoc basis. You find a place, and you're like, oh, these tests we probably don't need them. We can throw them out. I have found dead tests, tests that are not executed but still committed to the repo. GEOFF: [laughs] JOËL: It's just like, hey, I'm going to get a lot of red in my diff today. GEOFF: That always feels good to have that diff-y check-in, and it's 250 lines or 1,000 lines of red and 1 line of green. JOËL: So that's been a pretty good overview of a lot of different areas related to performance and infrastructure around tests. Thank you so much, Geoff, for joining us today on The Bike Shed to talk about your experience at CommonLit doing this. Do you have any final words for our listeners? GEOFF: Yeah. CommonLit is hiring a senior full-stack engineer, so if you'd like to work on Rails and TypeScript in a place with a great test suite and a great team. I've been here for five years, and it's a really, really excellent place to work. And also, it's been really a pleasure to catch up with you again, Joël. JOËL: And, Geoff, where can people find you online? GEOFF: I'm Geoff with a G, G-E-O-F-F Harcourt, @geoffharcourt. And that's my name on Twitter, and it's my name on GitHub, so you can find me there. JOËL: And we'll make sure to include a link to your Twitter profile in the show notes. The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed or reach me at @joelquen on Twitter or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeeee!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.

The Bike Shed
353: Mental Models

The Bike Shed

Play Episode Listen Later Sep 6, 2022 38:22


Mental models are metaphors that help us understand complex problems we work on. They can be a simplified roadmap over an infinite area of complexity. How does one come up with mental models? How are they useful? Are they primarily a solo thing, or can they be used to communicate with the team? What happens when your model is inaccurate? Today, Joël is joined by Eebs Kobeissi, a Developer and Dev Manager at You Need a Budget, to discuss. This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. Eebs on Twitter (https://twitter.com/EebsKobeissi) You Need a Budget (https://www.youneedabudget.com/) Skill floors and skill ceilings (https://thoughtbot.com/blog/who-is-empowered-by-your-design) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. And today, I'm joined by Eebs Kobeissi, a Developer and Dev Manager at You Need a Budget. EEBS: Hi, Joël. It's really good to be here. JOËL: And together, we're here to share a little bit about what we've learned along the way. So, Eebs, what's new in your world? EEBS: Oh, a whole lot. I'm a new dad, so I'm getting to experience all those things. But in the developer world, I've recently picked up programming on an ESP32, which controls LED lights. And so I'm having fun lighting up my office. JOËL: Is that like one of those little microboards, kind of like a Raspberry Pi? EEBS: Yeah, exactly. It's a little board that's compatible with the Arduino IDE. And I literally only played with it last weekend, so it's still very new to me. JOËL: Nice. Have you done any Arduino development or Raspberry Pi or anything like that before? EEBS: No, I have a Raspberry Pi that I run like a DNS server on, but I haven't done any actual programming. I did make an LED blink, which is pretty cool. JOËL: What kind of programming is required for a board like that? EEBS: From my understanding, it's either in Python or C. Those are, I think, the two languages that you can program on it. I definitely do not know C. And so I'm just going through a bunch of tutorials and reading some sample code. But I think if I ever end up trying to implement something more complex, I'll probably switch over to Python because that's a little more familiar. JOËL: So the coding feels fairly high level even though you're writing controller code for LEDs. EEBS: I hope so. I'd love to be able to take advantage of whatever abstractions I can. JOËL: Do you have any fun goals you're trying to do with this? Or is this just for the fun of trying a completely different environment than web development? EEBS: No, it's actually rooted in something visual. So I have these shelves behind me that are in my webcam when I'm in meetings or whatever. And so I want to be able to put a light strip across these shelves and have some sort of visual thing in the background. JOËL: Like LED mood ring? EEBS: Yeah, kind of. My eventual goal would be that as I'm talking, a little equalizer display pops up behind me. I thought that would be pretty neat. JOËL: That is amazing. That will give you all of the cred in the meetings. EEBS: Right? I thought that'd be pretty cool. What have you been thinking about recently, Joël? JOËL: I've been submitting to the RubyConf call for proposals which, as of the recording of this episode, has just closed this week. And like many people, I submitted on the last day. EEBS: [laughs] JOËL: And it was really fun trying to take some ideas that I'm excited about and then turn them into a proposal that is accessible to other people. EEBS: Nice. Do you want to share a little bit about what the talk is, or is it under wraps for now? JOËL: I don't know if anyone on the committee will listen to this before the review goes out. This might break the anonymity of the proposal. EEBS: Oh, right, right. JOËL: One thing I will share that's interesting is that there are topics that I'm excited about. It's like, oh, here are a bunch of cool things about something, some technical topic. But talks that are just ten cool things about X are not that great. And so I needed to find some sort of unifying idea that I could use to share that. And that generally is in the form of trying to find a story that I can tell. What unifies all of these things together? What tells a compelling story? Is there some metaphor I can lean into? EEBS: Nice. I think that's a really powerful way of communicating something deeper is through telling something that people can relate to. JOËL: One way that thinking about metaphors has been really impactful for me recently is the idea of mental models and how those can help us in development. I'm curious; we've thrown around the phrase a little bit you and I in past conversations; what does a mental model mean to you? EEBS: I tend to be a visual thinker. And from talking to others, I've heard similar statements. So for me, a mental model is how I think about a particular domain or how I think about code flow or structure. And for me, it's usually either as two-dimensional objects or occasionally three-dimensional objects that I have floating in my visual space. So, for example, if we had two classes that are collaborators in some way, I often think of them maybe as two rectangles that are side by side. And when they interact, there's some little amorphous blob from one of those rectangles that reaches out into the other one or passes a message from one to the other. And I sort of have this idea of how many connections are there between these two physical things. Or, if I'm thinking about code flow and the path of execution that code might take, sometimes I visualize it as maybe a tree or potentially loops if there are such cases. JOËL: So when you think of these concepts, just in general, you're seeing in your mind's eye squares and rectangles floating in the air. EEBS: Yeah, pretty often. Sometimes it takes those shapes, and as I build up a mental model of some code, I'm usually adding new shapes into that picture I have in my mind. I tend to view things sort of top-down. So like, the start of code or the start of execution is usually at the top or maybe the far left or far right. And as execution happens, I usually view that as moving in towards the middle and potentially going back out when a response is returned. If it's a web request, something like that, I view it as this sort of outside in. And there's a bunch of pieces in there that are all talking to each other. JOËL: That's really cool. So not only is there a geometric aspect to it, but there's a spatial aspect to it as well. EEBS: Yeah. And it's interesting, like, I haven't actually thought about it [laughs] in this level of detail before. But yeah, there certainly is a spatial aspect to it. And I have this idea in my mind of like things and domain objects kind of belong at the bottom, and they should have well-defined boundaries. But the pieces that are a little bit towards the outer edges may be a little more fuzzy and may have less definition around them. JOËL: That's really interesting because I also have this sort of in my mind's eye see these things when I'm thinking about concepts like that. But I've talked to other people, and some people don't even have much of a mind's eye at all. They don't tend to visualize things in their mind in that way. EEBS: Yeah, it's really interesting how different people approach this thinking about code. A lot of people write things down. And I write things down, too, and draw little arrows that don't really make any sense. But it helps me do something physically sometimes as well as just thinking about it. JOËL: Have you ever tried to convert these pictures you see in your mind and actually draw them on paper? EEBS: Occasionally. And for the most part, that usually takes the form of some kind of domain modeling, whether it's based on database tables or just domain objects. And sometimes I will try and draw them out and then specify the relationships between them like, oh, you know, this one model talks to this other model in this particular way. And I'll define a relationship between them, which helps me think about them and how they interact. JOËL: I've found that even though for some things I can see it very vividly in my mind's eye, I struggle to then concretely translate that onto paper or digital paper if you will. It's almost like trying to, say, translate an emotion into words and that even though I feel like I see a visual picture, I can't reproduce it by drawing necessarily. EEBS: It's interesting you brought up feeling because a lot of the times, I have this gut feeling about a mental model, like whether I think it is correct or not. And sometimes I have this uneasy feeling of, like, that doesn't feel right to me, but it's hard to articulate why. And I think sometimes that's when I have to pull out something physical, start making those relations, start connecting things. And that's when I might uncover, like, oh, this feels odd because I have a circle here or a cycle or something. Or I've sort of represented the truth of something in two different places. Do you have any techniques for getting it out of your head and into something physical that you could share with someone else, maybe it's text or a picture? JOËL: I think I do struggle with that conversion sometimes. Practice definitely helps. I think maybe there is a metaphor here between converting these, let's call them, pictures that I see in my mind's eye and then drawing diagrams with trying to take feelings and expressing them in words. In the same way that, maybe I might have some feelings, and then I want to journal how I feel, and I struggle to express that. But finding a way to express that gives me a certain amount of precision and a more concrete thing. In the same way, these things that flash in front of my mind's eye, if I can take the time to put them on paper, they're now more real. They're more concrete. I think you can probe the edges, the ways that it kind of falls apart more easily. EEBS: Yeah, that makes a lot of sense. There's a lot of value in writing that down and going through those details in a methodical way because oftentimes, you'll catch inconsistencies, or you'll find better ways to describe it. And being able to share your mental model with someone else is often...well, it can be really tricky. And I think that's why it's important to go through and maybe find a common medium that you can share because I can't see into your brain. You can't see into mine. But if we can share our mental models, then hopefully, we have a better chance of agreeing on the solution or finding inconsistencies. JOËL: Exactly. I think, in many ways, there are almost multiple layers of mental models and that you might have an abstraction or a metaphor for a concept that you're working with separate from the diagram. And then the diagram is yet another metaphor, but now we're going geometric to represent a broader idea. EEBS: Yeah. Are there any other ways that you take that picture from your mind's eye besides written documents or conversations? Do you use any diagramming tools that specifically help with that? Or is it just kind of free-form? JOËL: I do a mix. I am a big fan of draw.io, which allows you to just free-hand or pull shapes together, things like that. There are some more structured tools that I will use. I'll use Mermaid.js. EEBS: Yeah, I've been using that a lot too. JOËL: Yeah, that's great. I've been digging into more structured diagrams recently, particularly the idea of graphs, directed graphs. And those have interesting properties. EEBS: Can you share a little more detail about what you mean? JOËL: So a graph in the computer science sense is a bunch of nodes. They are typically represented as circles and then edges which are the connections between them. A directed graph is now there's an arrow pointing in a particular direction. A really interesting property that you can have with directed graphs is whether or not they include cycles. So can you only by following the arrows effectively create a loop? Or will the arrows always lead you to some kind of terminal node? EEBS: Gotcha. Is that a directed acyclic graph? JOËL: If there are no cycles, yes, it is a directed acyclic graph or DAG, as you'll often see it abbreviated. EEBS: [laughs] How do you relate that graph to code? And what benefits do you get from expressing it that way? JOËL: So this shows up in a lot of places. And I'd even say that thinking of certain aspects of my code as a graph and a potentially directed acyclic graph is itself a mental model or a metaphor that helps bring clarity to the way I think about things. So, for example, code, you know, you invoke some main function at some point to call the code, and then that's going to call out some other functions, which call out some other functions, and so on. You may have heard that referred to as a call graph. But that is a graph of calls. There might be cycles in there for co-recursive functions and things like that. But that is one way you can then sift through and analyze how control flow or how logic flows through your application is through a function graph. You mentioned earlier the idea of objects and how they're connected to each other. That's an object graph. EEBS: Right. Recently, I had to work through a state transition problem where a customer has some billing, and they can go through many different states, whether it's active, or canceled, or past due, those sorts of things. And so actually, I reached for Mermaid.js and built a graph of, okay, they start here in this empty state. And then they subscribe, which then they become active. They might cancel their subscription, which moves them to a different state. And by listing out all the states and the transitions between them, it helped me to understand what methods I might need to define on which objects in order to allow those transitions to happen and what checks I might need to make before allowing those transitions depending on the state of the system. JOËL: I'm hearing the keywords states and transitions. And that's making me think of finite-state machines. Are you drawing a finite-state machine graph or something a bit more free-handed? EEBS: It's a bit more of free-handed. I don't think I've actually drawn out a state machine since college but just representing the different states as different boxes and the transitions that are possible from those states. I mean, I guess that kind of is a state machine in some way. So graphs are great visual approaches. Are there any non-visual approaches that you take? JOËL: That's a great question because not all mental models have to be visual. I think the power of a mental model exists in a metaphor. And one that's kind of broad but that I've applied to a lot of different areas is the general idea of something being parallel or in series. I think I first came across this concept talking about electric circuits. And are we talking about two little light bulbs that are in parallel, and if the electricity to one is cut, the other one still lights up? Or are they chained together in series? EEBS: Yeah, like my LEDs. JOËL: Exactly, going back to Arduino, but it can also be applied to a bunch of other things. We can talk about code being in parallel or in series. We can talk about work being in parallel or in series. Interestingly, I took that mental model as a sort of quick shortcut when I was digging into some functional programming ideas. Monads and applicatives are the fancy terms here. EEBS: Oh boy, I'm ready. JOËL: In general, and there's a hefty asterisk here, I think of monads as being serial, so you're chaining something; one thing happens, then another. So you can think of, for example, chaining promises in JavaScript, promise one, then promise two, as opposed to applicatives which are parallel. So you might think of maybe zipping two lists or two arrays in Ruby. The two arrays, there are no dependencies between the two of them. They get processed side by side as you're traversing both of them together. EEBS: Interesting. I've heard the term monad a lot, but I haven't heard the term applicative. Are there any other details you can share about them and what makes them different or how they might be seen in our code? JOËL: I think that the key difference is that distinction in how they're processed. Applicatives are a way of combining two independent, let's call them data sources, and then you find a way to combine them together. So it could be two independent arrays, and you're zipping through them. It might be two independent HTTP requests, and they can both fire in parallel. But then you want to combine their outputs. So you say wait until both are successful and then combine their output. EEBS: Oh, okay, gotcha. JOËL: It could even be nullable values. So you say do this thing if both values are present. But you're not...the value of one or the fact that one is null or not is not dependent on whether the other one is null or not. They're independently null or not as opposed to something...Monads are, again, a different way of combining. You might call them data sources or operations. But in this case, there is a clear dependency one, and then its output influences the next one. You might say check the value is null or present or not. And then, if it is present, take that value and then put it as the input of my next operation. And then, if it is null or not, do another thing. See, now you have a sort of chain. EEBS: Where do you see these chains happening in code? Or is it everywhere? JOËL: Once you know that pattern which, again, could be thought of as another mental model, you start seeing it everywhere. So promises in JavaScript chaining together that's effectively monads. Don't @ me, all the functional programming people. EEBS: [laughs] JOËL: I know that's not quite true. Anything dealing with multiple operations that could succeed or fail depending on, again, whether you're treating them as dependent or independent, that's probably going to look very similar to either monad or applicative. EEBS: So the first thing that actually comes to mind here is things like background jobs. Using Sidekiq or Resque or other job processors, you can have a queue of jobs that need to be executed, and they might need to run in serial, or potentially you have multiple workers pulling from a single queue, and thus the work is happening in parallel. Is that a reasonable analogy? JOËL: I think it's good for the serial versus parallel, but it's not necessarily a good analogy for understanding monads and applicatives. EEBS: Gotcha. JOËL: So with two workers, you can process a queue in parallel, and a bunch of things happen. EEBS: But there's not necessarily anything that is bringing those two workers together to produce a single output. JOËL: Yes. And there's no dependency between the tasks in the queue. EEBS: Right, right, gotcha. JOËL: So if you have a task that says execute this task and then only if this task succeeds, then do the second task, now you've created a dependency. And you couldn't process that in parallel because if task one, which has to be executed first, is executed by worker one, task two should not get processed unless task one is successful. You can't just say, oh, I've got another worker free. I haven't processed task two because it's waiting to know does task one succeed. EEBS: Right. So an example in code would be a user creates a new order. And when they create a new order, we send them a confirmation email. That would be an example of that happening in serial or a monad-like thing. [chuckle] JOËL: Yes, I found that thinking of things as serial or parallel is a good shortcut for thinking about monads and applicatives. I don't know that the reverse is necessarily true. They don't necessarily transfer one-to-one with each other. And maybe that's a danger of mental models, right? You find a mental model that describes a situation, and then you try to reverse it, and then you make false assumptions about the world. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: Another mental model that is not necessarily visual that I like actually comes from the video game community, and that's thinking of skill ceilings and skill floors. So in, I think, particularly the MOBA Community, that's a Multiplayer Online Battle Arena, they'll talk about characters as having a high skill floor or a low skill ceiling. And generally, what that means, and again, the meaning varies a little bit by community, is that a character with a low-skill floor is an easily accessible character. They might not have a lot of skill shots, like, you press a button, and things happen around your character. You don't need to aim, things like that. A high skill ceiling means that there's a lot of room for you to grow, and as you get more skilled, you can get significantly better with that character. EEBS: Gotcha. So the opportunity is greater with a higher skill ceiling. JOËL: Correct. And depending on how the character is set up, you might have a very narrow range that could be in the low range where it has a low skill floor and a low skill ceiling, which means that the character is easy to learn. But once you've learned it, there's not really a lot you can do with it. It's a fairly basic character. So getting better at the game is not necessarily going to make you that much more impactful. And then you could have one that's the opposite that is high both skill floor and skill ceiling where a character is very hard to learn. But once you learn it, that's kind of all there is to it. And then you might have one that has a large range somewhere; maybe it's easy to learn, but it's hard to master, or there's a lot of room for growth. And so, taking this framework for analyzing characters and video games, I think we can apply that to technology in general. This could be language design. This could be just API design. And you might say, well, I want this to be very accessible. People can jump in very easily. You might say I want this to be very powerful and have a lot of high-end features that make your power users very happy and very productive. EEBS: That's interesting. When you first were talking about it, I was actually less thinking about it from a user's perspective of what maybe they could do in the application but potentially from the standpoint of a developer writing the system itself. One of the pieces I always come back to in software development is that change is inevitable. And so, making something easy to change often pays great benefits down the road. And so I wonder how that fits into this idea of a low skill ceiling or a high skill ceiling in terms of perhaps flexibility or being decoupled such that you can take one idea and easily extend it or easily get more from it than you originally set out to build. JOËL: There's often a trade-off. So you make something easy to change. It's highly decoupled. But you maybe introduce more indirection to the system. So while it's easier to change one single piece, it's harder to understand the system as a whole. EEBS: Yeah, that's true. And sometimes, you bake in assumptions that you make about the future, which turn out not to be true. JOËL: [laughs] Yes, that is definitely something I'm guilty of. EEBS: I think we all are. JOËL: One thing that I find interesting is as you evolve the design of an architecture pattern, a system, a whole language, you might want to move one of those if I think of them like two independent sliders on a one-dimensional scale. So maybe you want to move the upper boundary a little bit and say I want a higher skill ceiling for this, but they don't actually move completely independently. So introducing some advanced features might inadvertently also raise the skill floor. And conversely, making the language super accessible so that it has a low-skill floor, you might have to decide I will not introduce certain features. EEBS: One thing I wanted to ask you about is, do you view different languages as having different skill floors and ceilings? And, you know, I love Ruby. I know you love Element. I've played with Element. It's been a great learning tool for me. How do you view those two languages in terms of skill ceilings and skill floors in terms of, I guess, what you can do with them? JOËL: That's a great question. And I think you can definitely apply that to languages. Admittedly, I think you could probably start a lot of flame wars with that. EEBS: [chuckles] Let's not do that. JOËL: I wrote an article a while back where I applied that mental model to look at the F# programming language. And there was a debate in that community about certain features to add and whether they would allow advanced programming but potentially at the cost of accessibility to newer members of the community and how to balance those. And so I thought, hey, let's throw this video game metaphor at the problem and talk about it through that lens. EEBS: That's really cool. Did you draw any conclusions, or was it as a way to start a conversation? JOËL: It is a way to start a conversation. I don't think there is a single correct or best distribution of your skill, ceiling, and floor. It has to match the goals you set out for your project. Just like in games, people love to rank which characters are best and not. And sometimes you can show that, in general, this character is better. But oftentimes, in a balanced game, you can talk about this character being easier to get started with or this character working very well if you're a pro. But the fact that you have a higher or lower skill ceiling or floor doesn't necessarily make the character better or worse. EEBS: So, this conversation about differing mental models, I think I hadn't realized that there can be so many different types of mental models. And some things that I do in my thinking I haven't classified as a mental model. But now that you bring it up, I think one that I think about fairly often is this idea of two objects that are collaborators and reaching into the internals of one of those objects from the other object. So A and B are two separate things. And if A reaches into B's bucket and messes with the state of B, I view that as sort of a bad practice. You're not really adhering to maybe the public API that that object is exposing. You're kind of reaching in and going around behind its back and changing some stuff that it may not expect. JOËL: Would you refer to that maybe as tight coupling? EEBS: Yeah, it's definitely tight coupling. It's not just tightly coupled; it's almost worse than that. It's almost like going behind somebody's back and making a change without them knowing. And so when I see that in code or when I write code that does that, I have this really intense desire to separate that and to say, no, no, you can't go in and update this record directly in the database. You have to send it a message and say, "Hey, I would like you to be aware of something," and then it goes and changes its own internal state as a response to that. And so I have this very vivid sort of mental feeling of it being wrong, of it being like, I'm being sneaky, or I'm not being gracious to the person I'm interacting with as though I were one of these objects. JOËL: That's fascinating. You've practically anthropomorphized these objects. EEBS: I do. I view them as little people. JOËL: You describe this interaction as going behind someone's back. That is the thing that I, a person, do to someone else. It's not a function making a direct call. And yet, it's such a strong...we use a social mental model to talk about objects and interactions. EEBS: Yeah, I almost want them to be friends. And I think that applies to real-life relationships, right? If you have a nice dialogue back and forth, there's an understanding. There's commonality that you can find. But if I were to go do something behind your back without chatting with you about it first, you might not be so happy with me. JOËL: I'd feel betrayed. EEBS: Right. JOËL: I feel like there's probably a really fun conference talk to be done about that. We often use that metaphor; I think when talking about objects sort of subconsciously but making it explicit and just being, hey, let's talk about these objects as if they were people. Why don't we want to do this? Because this one here is betraying the other object there. This one here is being impolite. EEBS: We could have two people get on stage and talk to each other. And I might then go and reach in your pocket and pull out some change without you knowing, and you might be upset with me. JOËL: That would be great. Get a little skit going up on stage. Or even if you're artistically inclined, you could probably draw some really fun little characters to illustrate this. EEBS: That would be really cool. I, unfortunately, don't have the artistic talent to do that. JOËL: Well, free conference talk idea to all listeners of the podcast. I expect to see this for RailsConf 2023, maybe. EEBS: I'll be looking for it. So I've shared a mental model that I didn't really know was a mental model. Are there other mental models that you want to share that I may not be thinking of? JOËL: Here's one that I've just come to realize recently that I'm actually quite excited about: when you think about the word refactoring, how would you describe that idea? EEBS: Well, refactoring to me is changing the implementation without changing the behavior. JOËL: Yes, I think that is the classical definition. You should be able to change the implementation of a method, and the tests without changing are still green after you've done that. EEBS: I guess, mentally, I think about that as perhaps drawing a box around some of the objects that are floating in my mind's eye, rearranging how they exist within that box, and then the box dissolves. And the tests still pass, but the structure of the objects or the code has changed in my mind. JOËL: I love that you immediately went to a visual approach there. And I think I have something similar, but I'm coming at it from a slightly more domain modeling perspective. So thinking maybe less from an individual method approach but looking at maybe a larger system, what you're trying to do is use code to describe some version of reality. So it might be a business process that you have. It might be trying to describe some aspect of your customer's life that you're trying to automate for them. Oftentimes, this thing you're trying to describe in code terms is going to be a simplification because life has a ton of edge cases, and many of them we don't care about. So if we go with a visual metaphor here, you're trying to draw some kind of shape using only straight lines to approximate some weird curve. And so, let's say you draw something with only four lines. It's really simple, how you have a diamond. That's the shape you're trying to create. And then you're going to fill it in with little other shapes that approximate a diamond. And those are your different models and functions and all the other components that we use to build software. At some point, your understanding of the underlying reality might change. Maybe you need more precision, or maybe the actual feature requirements have changed. The thing you're trying to approximate with your code is not a diamond. Maybe you've added a few more sides to it. It's a pentagon. So we've gone from four sides to five. And the little components, and modules, and things that you have there approximate that diamond work. They still mostly approximate your pentagon, but it's really clunky because the initial design was to approximate something else. They were really good for fitting in really tightly and being very loosely coupled to each other when we were trying to do a diamond, but then they don't work as well in the pentagon. EEBS: So maybe some of the internal shapes need to change or adjust to fill the space that the pentagon has now created. JOËL: To fill the space or maybe even just to fill it in a way that's less clunky. And so the idea here in this metaphor is that the reality we're targeting in software is always changing. And so the underlying reality changes, and so we're changing that shape that we're creating all the time. But also, we're getting more precision as we decide; oh, we care about this edge case now. We didn't in version one, and so as part of that, we're constantly having to take the modules that maybe were very well designed initially but then restructure them to fit the new requirements because now there's a fourth object coming in, and it's kind of clunky with our current configuration. EEBS: That's interesting. One of the first things that jumps to mind is that maybe there are better ways or worse ways to do that refactoring to fit that new shape. Do you think there's any truth to that in the sense that you might initially design a system that perfectly fits that diamond or very closely fits that diamond but then as it changes to a pentagon, do you need to simply add a new piece to fill in that empty space? Or do you need to restructure everything within the diamond now to fit the shape of the pentagon? JOËL: Oftentimes, you do need to restructure. And I think there's this wonderful little phrase from; I believe it's Kent Beck that says, "Make the change easy, and then make the easy change." EEBS: Yep. JOËL: And so, to me, that makes the change easy is that initial restructuring that you need to do of those first shapes so that you can finally bring in the new one. EEBS: Oh, that's a cool visual. I immediately can imagine the pieces in the pentagon moving around to make space for a new piece that you need to now bring in. And that movement of all those pieces can be really difficult. Have you ever played that game where it's a square, and you're trying to get a ship out of a port, but there's a whole bunch of other ships, and you can only move them left and right and up and down? And you can do that. And that's what I'm picturing right now is moving shapes within that pentagon to then make space for either a new shape or to allow a shape to escape that is no longer relevant. JOËL: I played a version of that that had cars, cars, and trucks. EEBS: Gotcha. Yeah, I think I played that too. JOËL: That would also be a fun conference talk, right? Like, start with that game as your initial metaphor. And then you use that as a way to talk about refactoring. EEBS: That would be really cool. JOËL: I would watch that talk. To anybody listening who wants to give that talk, I want to see you at RailsConf 2023. EEBS: [laughs] Are we just a talk factory now? [laughter] JOËL: I love talk ideas. Maybe this should become a segment. Just have Eebs come in for five minutes once a month and give us a talk idea. It could even be fun to see a talk idea that multiple people implemented differently. EEBS: That would be really cool, actually. I always get nervous about giving talks or being on podcasts like this one. I would love to be the person that gets to sit there and throw out random ideas and have other people fulfill my dreams. JOËL: Well, thank you so much, Eebs, for joining us to talk about mental models. And to all of our listeners, I'd love to hear about what mental models you find are helpful, and so please share them with us. On Twitter, you can reach us at @_bikeshed. EEBS: Thanks for having me, JOËL. This has been super fun. JOËL: And on that note, let's wrap up. The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed or reach me at @joelquen on Twitter or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeeee!!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.

Medias Lokas Podcast
EPISODE 11 PT. 2 - UMM HE LICKED WHAT?! (FEAT. FERNANDO)

Medias Lokas Podcast

Play Episode Listen Later Aug 31, 2022 31:23


HIIIII WELCOME BACK! THIS WEEK WE HAVE PART 2 OF LAST WEEK'S EPISODE WITH FERNANDO! LISTEN IN TO HEAR EVERYONE'S OPINIONS ABOUT CLUBBING IN YOUR 30'S AND TO FIND OUT HOW JTOOLIT AND FERNANDO MET!MAKE SURE TO FOLLOW US ON ALL SOCIAL MEDIA @MEDIASLOKASPODCASTAND YOU CAN WATCH FULL EPISODES ON OUR YOUTUBE @MEDIASLOKASPODCASTTHANK YOU FOR LISTENING! BYEEEEEEE

The Bike Shed
352: Case Expressions

The Bike Shed

Play Episode Listen Later Aug 30, 2022 32:23


As developers, we care a lot about code quality. How do we know how good is good enough? When do we stop improving code? Alternatively, when working on code that's really bad, how much do you improve it before calling it a day? thoughtbot's Stephanie Minn joins Joël to chat about this and case expressions: We recently discussed these as part of thoughtbot's RubyScience reading group. Are case expressions bad? Are they equivalent to multi-way conditionals? When do you use polymorphism? This episode is brought to you by Airbrake (https://airbrake.io/?utm_campaign=Q3_2022%3A%20Bike%20Shed%20Podcast%20Ad&utm_source=Bike%20Shed&utm_medium=website). Visit Frictionless error monitoring and performance insight for your app stack. RubyConf 2022 (https://rubyconf.org/) RubyConf Mini (https://www.rubyconfmini.com/) Stephanie's talk at RubyConf 2021 (https://www.youtube.com/watch?v=m0dC5RmxcFk) WNB.rb (https://www.wnb-rb.dev/) Joël's RailsConf 2022 talk (https://www.youtube.com/watch?v=LOlG4kqfwcg) Ruby Science (https://books.thoughtbot.com/books/ruby-science.html) older episode on wizards (https://www.bikeshed.fm/295) TCR (https://www.honeybadger.io/blog/ruby-tcr-test-commit-revert/) Transcript: JOËL: Hello and welcome to another episode of The Bike Shed, a weekly podcast from your friends at thoughtbot about developing great software. I'm Joël Quenneville. And we're here to share a little bit about what we've learned along the way. Today, I'm joined by a fellow thoughtboter, Stephanie Minn. STEPHANIE: Hi, Joël. JOËL: Welcome to the show. STEPHANIE: Thanks. Happy to be here. JOËL: Stephanie, what's new in your world? STEPHANIE: Thanks for asking. I've been working on writing a CFP for RubyConf, which you have been plugging internally at thoughtbot. I wasn't really sure if I wanted to do it, and then I found out about RubyConf Mini, which is happening as an alternative to the main conference in Houston. And that got me really excited to have some more options and just got me thinking about what I might have sitting on the back-burner that I might want to give a talk about. JOËL: That's really exciting. I'm curious, what is your process for coming up with an idea for a talk? STEPHANIE: I think they come in seasons, ideas, for me, so not even necessarily when it's conference time. But if something has been sticking in my brain for a really long time, especially as it relates to processes on teams that I'm on or my day-to-day workflow, and it's something that I keep coming back to and trying to figure out what it is about it that my brain wants to work through a process, that usually tips me off that this might be something that other people are thinking about or working through. In this case, I am planning to write a CFP about pair programming. And yeah, it's something that I've been thinking about doing for a while, and it seems kind of an evergreen topic. So I thought I would pull it out for this conference. And if it doesn't end up getting accepted, I can always resubmit again in the future. JOËL: I love that. So it sounds like you have a note or maybe an actual written notepad somewhere where you just, over the course of the year, build up ideas, and then you take a look at that when conference time comes around. STEPHANIE: Yeah, that's about it. I have just a very long-running note of half-formed thoughts. And then, when I give myself time to really reflect on how things have been going at work, I usually revisit it, and if any of them still resonate or stand out to me, I will go through and try to see if there's any content to come out of that. What about you? I know you are an extensive note-taker and ideas blogger. JOËL: I have to say I really like your approach of gathering ideas throughout the year. I've worked with many people who would love to give a talk at a conference as a professional goal but then get stuck in the I don't have any ideas. I don't know what I would talk about. And most people have a thing they could talk about. They just don't know it. And it sounds like you've done a really great job of gathering this info throughout the year so that when the time does come, you don't just freeze. You're like, no, here are the 10-20 things that I experienced or that I am an expert in or that I would love to share. And maybe there are two or three in there that would be very well-fitted for the conference you're looking at. So I love that idea. I have not done that myself personally, but maybe I should start doing that. STEPHANIE: What about you, Joël? What's up in your world? JOËL: So I've also been thinking a lot about RubyConf coming up, working on a few ideas for myself. And then, there are a few people that have reached out to me to help them craft ideas or get a little bit of feedback on their proposal. So I've been doing a lot of proposal reviews as well. STEPHANIE: What do you enjoy about reviewing other people's proposals? JOËL: I think for many people speaking at a conference is a really big, ambitious professional goal, and so helping people achieve that is really fulfilling for me. Some people might feel almost inadequate or unprepared. But because I know them, I know they've got good things to share. And so it's almost seeing the greatness in them that they don't quite see yet or that they don't feel confident about. And so being able to see that in their proposal and say, "Oh, there's a core of a great idea right here, tweak it a little bit, and that'll give you a slightly better chance with the committee and help you towards that path of being on stage for the first time," is really exciting. STEPHANIE: I spoke at RubyConf last year, in 2021, virtually. And I remember that was my first time speaking at a conference. And I was worried that my talk was not super hardcore, technical enough. But my goal for my talk was to aim it towards other developers like me who are maybe mid-level and wanting to reach this whole audience of people who are attending these conferences to learn and to level up who aren't necessarily super senior experienced developers. And it was a really great experience. People seemed to really resonate with that. So I really encourage folks to speak about things that are resonating with them at whatever point in their careers because there are so many people out there who are probably in the same boat and want to hear what you have to say. JOËL: Absolutely. I'm curious, now that you have experienced the full cycle at least once, from ideas to crafting a submission, to getting accepted, preparing a talk, delivering the talk, and then recovering from that, what are maybe some lessons learned or some things you weren't expecting the first time you went into that that now you do know going into another cycle? STEPHANIE: Yeah, the power of community; I had a lot of support from WNB.rb, a woman and non-binary Ruby community. We crafted our CFPs together and then practiced our talks together and had a working group that met every couple of weeks to give feedback on our talks as we were working on them. And it was really awesome to have that accountability, to have that support, people to tell you that your talk is good and give you a thumbs-up. And I really want to continue investing in my community that way. And I really appreciate you asking this question because I guess I do have things I've learned and would want to share that with other people in my community, and yeah, just continue to encourage folks who may not have been traditionally encouraged to speak at conferences. JOËL: Community is so powerful. Even though I've spoken at multiple conferences, I still get nervous about my talks. I have a lot of self-doubt about whether my topic is good, whether I'm sharing it in a way that's going to be impactful. And I had a magical experience at RailsConf this year where a group of us were at a hotel lobby practicing our talks the night before. And I was just still so unsure about my talk. And the feedback that I got there gave me a huge boost of confidence that I was able to ride into the next day and give a talk that I think turned out rather well. But honestly, that was my favorite moment of the conference was 11:30 p.m., a group of people in the hotel lobby taking turns practicing their talks. STEPHANIE: Yeah, I love that. MID-ROLL AD: Debugging errors can be a developer's worst nightmare...but it doesn't have to be. Airbrake is an award-winning error monitoring, performance, and deployment tracking tool created by developers for developers that can actually help cut your debugging time in half. So why do developers love Airbrake? It has all of the information that web developers need to monitor their application - including error management, performance insights, and deploy tracking! Airbrake's debugging tool catches all of your project errors, intelligently groups them, and points you to the issue in the code so you can quickly fix the bug before customers are impacted. In addition to stellar error monitoring, Airbrake's lightweight APM helps developers to track the performance and availability of their application through metrics like HTTP requests, response times, error occurrences, and user satisfaction. Finally, Airbrake Deploy Tracking helps developers track trends, fix bad deploys, and improve code quality. Since 2008, Airbrake has been a staple in the Ruby community and has grown to cover all major programming languages. Airbrake seamlessly integrates with your favorite apps to include modern features like single sign-on and SDK-based installation. From testing to production, Airbrake notifiers have your back. Your time is valuable, so why waste it combing through logs, waiting for user reports, or retrofitting other tools to monitor your application? You literally have nothing to lose. Head on over to airbrake.io/try/bikeshed to create your FREE developer account today! JOËL: One thing we've been doing recently at thoughtbot is every other week book club discussion, and we've been looking through the book Ruby Science published by thoughtbot. Every week, we'll have someone who is a facilitator, who has done the reading and has prepared some questions for the group. And you recently facilitated a session on the topic of CASE expressions and why they might be a code smell. That sounds like a really controversial statement. How did you approach that topic? STEPHANIE: It's funny because I was looking at the upcoming chapters to pick a topic to facilitate for this book club, and CASE statements stood out to me because I was like, oh, I know what that is; that will be easy. [laughs] But it turned out to be a bit meatier than I thought it was going to be. I'd say that I didn't really consider them a code smell until I read the chapter of Ruby Science talking about them. So I was a bit surprised because they seem so common, which is probably also why I thought it would be an easy topic. JOËL: Would you say that reading the book or that particular chapter changed your mind? STEPHANIE: I think it did only because I hadn't necessarily given them a second thought or thought of them more deeply in that way. I think that, at least in my experience, you encounter CASE expressions pretty early in your career, and you think they're a cool tool for making your conditionals look a bit nicer. And it takes probably a bit more experience, a little bit more pain using them or trying to extend them that you start to have a bit of a more higher level awareness of what might be problematic about a CASE expression. But the book club that I facilitated, we had a really engaging discussion where most folks agreed that it was a code smell but also said that it depends. JOËL: Classic consultants. STEPHANIE: Truly. One thing that someone said that was a really nice takeaway for me was that CASE expressions get a bad rap in object-oriented languages because there are typically other tools or options you can reach for that might be preferred. And someone else said that it's probably a sign that you might be doing too much in the method. JOËL: Hmm. You mentioned that there are some tools and things that might be preferred over CASE expressions. What are the common alternatives that people say you should use instead of a CASE expression? STEPHANIE: I think one simple solution that we discussed in the book club for more straightforward cases would be a hash lookup to use instead of checking for equality via CASE statement. Another solution we talked about was polymorphism, which I think might refer back to the idea of having a bit of a higher level understanding of abstractions in the codebase and what things might look like in the future, especially when you might not have too many conditionals yet in your CASE expression. Another thing that really stuck out to me in our book club discussion was another thoughtboter mentioned Sandi Metz's 99 Bottles of OOP. And in that initial solution, she presents a CASE statement as the perfectly fine solution for now. And I thought that was really interesting because, in some cases, that might be all we know about the problem, and that is perfectly fine. What do you think about that? JOËL: I love the idea of starting simple. Don't try to start with abstraction, especially if you're doing test-driven development. You have a test, make it go green, use the simplest thing, use duplication, use all the dirty tricks. And then from there, now that you know I have a test that was red and this code makes it go green, now the question isn't how do I solve the problem? It's how do I improve the solution? So we've kind of separated those two steps out, and I really like that. STEPHANIE: Yeah, I remember you mentioned that you had refactored something into using a CASE statement. And I'm curious if you want to share more about that. JOËL: Oh boy, this was a "fun" problem. Fun is in air quotes, by the way. It was a multi-step form, AKA a wizard in a Rails app, where every step submitted to the same controller, and the controller was a huge mess. It had to handle submissions from four or five different forms, some of which shared fields. And it was this huge, deeply nested conditional thing that checked if this field is present in params, that probably means we're on step three, except if this other field is also present, then it probably means we're on step four. But if this Boolean flag in the database is set to false, we might be on a variation of step three. And because there was branching, potentially, it was an absolute mess. By looking at the code, you could never know what step of the processing you were on. What I did is instead of all of these nested if else conditions, I wrote a flat CASE expression that just said, if step one, do step one logic or process step one form. If step two, process step two form and so on. So it was nice and flat. I was able to reuse some parts of the work across by making private methods or other objects, things like that. But you could easily tell in any part of the code what step you were processing. Which means if you get a new feature from the client that says, "Can you modify the behavior on step four?" Now you actually know where to go to. You go to this controller; you find the big CASE expression. You find the branch that says, "If step four," and then you drill down from there. STEPHANIE: So after refactoring that into a flat structure, did you find the code more readable? Did other folks on the project think so too? JOËL: Yes, it was unanimously loved because this is the part of the code that everybody feared to touch. It was the most awful, gnarliest code. And a few of us had touched it, and so if you did the git blame, our names would show up, which meant that anytime anybody got stuck in that code, they would reach out to us and say, "Hey, you're the last one who touched it. Can you fix this for me?" And it was a big game of not it. Cleaning it up made this code accessible to everybody on the team. STEPHANIE: And why do you think a CASE statement was the right solution in this particular case? JOËL: I think if it's a multi-step form that maybe had seven steps in it, you clearly have seven branches that you're working with. And so hiding that behind nested conditions where you try to reuse each other's branches just muddied the waters. We have a seven-way branching path; let's be honest about it upfront and do a seven-way CASE expression. STEPHANIE: One thing that we didn't really talk about as much in our book club discussion was that CASE statements can be quite readable, especially for newer developers. And even though we all did think it was a bit of a code smell, I recently encountered on my client project in a code review someone saying that they preferred a CASE statement in that situation because it was easier for them to grok. I think that's a benefit worth considering before trying to do something fancier in some cases. And I'm curious what you think about that. JOËL: I strongly agree that a CASE expression is a great place to start, especially when you have actually more than two branches. Your logic could go one of n ways. I generally like to branch earlier than later in a lot of code. It's better in my mind to have a seven-way branch at the top of your decision tree and then just straight lines down than this constantly looping back and branching again and looping back, trying to force everything down a single path when it really doesn't want to be. STEPHANIE: So, in this case, did you know that you had those seven branching paths upfront, or did you have to tease that out? JOËL: I did not know from the code. Honestly, it would be very difficult to infer that from the code. But from the product, I knew this is a multi-step form with seven steps. And so I knew what the branches were from the product description. But no, it was almost impossible to infer that from the code. Long-time listeners of The Bike Shed may remember an older episode where Steph and Chris discussed multi-step forms and how best to approach them in Rails and also in JavaScript. And one thing that did come up is that an ideal way to work with a multi-step form in Rails is to have every step be its own controller. So you have a view, it submits to a controller, which renders another view or redirects to another view which submits to another controller. And that is the direction that we went with this multi-step form eventually. Once the single controller had a big CASE expression in it, we slowly started moving each branch out to its own controller. And now we had the step one controller, the step two controller, the step three controller, and so on. And I think that was probably the best solution in the end. But we had to go through the CASE expression just to know what was safe to move out. Interestingly, this refactor is effectively replacing a conditional with polymorphism because all of our controllers are controller objects. They respond to the same interface. And so this gets classic refactor that Ruby Science suggests, which is what we did and kind of what Steph and Chris recommended if you had the luxury of starting from scratch all those episodes ago. STEPHANIE: Nice, I'm glad it turned out that way and was a lot more manageable. JOËL: It's really interesting when you're working with a situation like that where you've got really messy code, and you can make some improvements. And it's like, how far do you go? Especially because there's usually a backlog of new features that the customer wants you to implement. So I'm curious for you, Stephanie, how do you know when you've gone far enough in improving code, either in a refactor step for your own code for a feature you're writing or maybe you're trying to take a break and say I'm going to take a little bit of time today to improve this area of the code. How do you know how good is good enough? STEPHANIE: That's an interesting question. I think I encounter that in a couple of ways, either in my own work when I am tasked with a feature, and I start getting into the code, and it stresses me out and leaves me a bit confused and not sure where to go to work on my feature. That is usually a signal that I might need to pay some attention first and make the change easy and then making the easy change. The other common thing that I have experienced on teams is we collectively feel the pain of an area of the codebase. And maybe we talk about it at a developer meeting, and all agree that, yeah, we really want to give this part of the code some love and add it to the backlog. But it's tough in that case because, like you said, there are a lot of new features that stakeholders want. And we as developers want to be over here taking care of our little codebase [laughs], making sure that it is healthy and it feels good to work with. JOËL: I feel like I don't just want my codebase healthy; I want it pristine. STEPHANIE: Ooh, pristine. What does that mean to you? JOËL: I want it perfect, nice, and shiny. And, of course, it's never that, which is why it's always tempting to toss out the old code and start over and do it right this time. That's not a good thing. You have to be able to live with the messiness of everyday life and the fact that, okay, here's an idea. I think if your codebase is perfect, you've put too much work into it. You've gone too far, and you're beyond that; when is good enough good enough? STEPHANIE: Whoa, that's a big statement. JOËL: [laughs] Feel free to disagree with me here. STEPHANIE: I guess I'm curious what perfect is in this case. JOËL: I think it's subjective for the developers who are writing it. But oftentimes, the ones who are looking for perfection go way too far in their quest for that. STEPHANIE: Way too far at the expense of things like business value or other things? JOËL: I think in two ways; one, you probably ended up overengineering things to try to make it so perfect. Your design needs to have some amount of flex in it for the unknown. It's okay to have some rough corners because it's going to change. And you're going to have to redo that corner next week anyway. So you need to not go all the way in making everything absolutely perfect. The other thing is that if you are putting in the effort to make everything perfect, at some point, you hit diminishing returns. And that's not worth your time from a business perspective or even on a personal project where you're just trying to ship things. At some point, you need to make actual progress. STEPHANIE: I'm curious if you mainly hold yourself to those very high standards or if you also think about that when reviewing other people's code. JOËL: So I mentioned earlier that I want my code to be pristine. I want to be clear, that's a bad thing. I do not actually hold myself to that standard. And I try not to hold other people to that standard, either. It's sort of tempering idealism with pragmatism. So being able to say, look, can we cut scope and focus on just one thing? Or does this fulfill the need that we have? And will it hurt us if we leave it like this and come back to it later? Or that question I asked you at the beginning, is this good enough? And maybe we can come back to it eventually. STEPHANIE: I really struggle with that question sometimes because, in some ways, people talk about software as a craft. And if we were building it in a vacuum, we could fine-tune and hone it until it's this beautiful, perfect, pristine thing. But because we write software for real things in the real world, we are constrained by the needs of our users, or the business, or just the purpose of building software is for folks to use it. And in that case, part of the job is evaluating trade-offs and deciding when is good enough. But sometimes, when I'm by myself working or coding for a little while, I do get sucked into wanting to make this the best that it could be just for my own personal fulfillment and joy. And I have to pull myself out of it sometimes and take a step back and be like, is this good enough for now, good enough for other people to be able to understand, work with in the future? And sometimes, it also requires getting other people's input too. JOËL: That's really valuable. STEPHANIE: Yeah, the worst thing that could happen is squirreling away with your code, and then you emerge with something that was totally not what was asked for. [laughs] JOËL: Especially on a work project. On a personal project, it's often good to know why you're doing a thing. And so maybe you want to see how far you can get away with pushing a particular metric, whether it's you want to go extreme on the decoupling or 100% TDD, or maybe you want to try something like test && commit || revert which is a development methodology. And those are all great as learning experiments, and then you go as deep as you want. I'm going to make another hot take here, and again, feel free to tell me I'm wrong. I'm going to say that on your own personal projects, if you pursue perfection, even when it's not for work, pursuing perfection on personal projects dooms them to join the others on the pile of uncompleted projects on your GitHub. STEPHANIE: That is an interesting take. I think it depends on the goal of your personal project because I personally like to have my projects be a bit of a sandbox, and I have no expectations that they will end up being anything that other people would necessarily look at, even though I guess they just end up public on my GitHub and are just sitting there in a weird, unfinished state. But yeah, I like to use them as an opportunity to, like you said, practice those concepts that I am really excited to explore but might not necessarily have the opportunity to on whatever client project I'm currently working on. And sometimes, I end up just scrapping it, but the exercise itself was valuable for me. I'm curious, though, what types of personal projects you have that lead you to have that opinion. JOËL: I think the way I use personal projects is very similar to you in that they're generally for my own personal growth and entertainment. It's about the journey, not the destination. So I generally have no intention of making this a thing that other people will use. It's typically a way to try out a technique, or a concept, or an idea. And so, for those, going really far on a performance or quality metric can be the goal. And that's completely okay with the knowledge that I probably will not complete or ship this project. I've done a few others where I've done the opposite. I've joined Game Jam events where you typically have a hard deadline. This could be a longer one, like maybe a month or as short as a day or a weekend, and you have to build and ship something within that deadline. And then you have to really make some pragmatic choices. STEPHANIE: Yeah, that sounds like a lot of pressure. I don't know if I would necessarily thrive in that kind of environment. I really like to spend a lot of time thinking about my code and looking over it again, sometimes to the point where I might be a little bit too precious about it. I was reflecting on this recently, and I thought about back when I was earlier in my career and didn't have any idea of what clean or good code was or looked like. And I would just write the code that would make my future work and just put it up for review. And I was very blissfully naive, I think, at that point in my career where I wasn't self-conscious about it in any way. And I think I'm trying to find a good middle ground between being comfortable with whatever comes out when I do some work or write some code while also having more knowledge and experience being able to revisit it and give it a deeper look after some space and feeling good about it without spending too much precious time on it. JOËL: Yeah, it's that classic consulting; it depends. Learn to balance code quality idealism versus the pragmatic reality of your goal, which is I want to ship something, both on your personal project and at work. That perfect code is useless if you can't ship it for contexts where you actually care about shipping. And on that note, let's wrap up. The show notes for this episode can be found at bikeshed.fm. This show is produced and edited by Mandy Moore. If you enjoyed listening, one really easy way to support the show is to leave us a quick rating or even a review in iTunes. It really helps other folks find the show. If you have any feedback, you can reach us at @_bikeshed or reach me at @joelquen on Twitter or at hosts@bikeshed.fm via email. Thank you so much for listening to The Bike Shed, and we'll see you next week. Byeeeeeee!!!!! ANNOUNCER: This podcast was brought to you by thoughtbot. thoughtbot is your expert design and development partner. Let's make your product and team a success.

Valley Girl
The Most Iconic Movie Makeover Montages: The Princess Diaries, Miss Congeniality, She's the Man, First Wives Club, Mrs. Doubtfire, The Devil Wears Prada, Hercules, Mulan and more

Valley Girl

Play Episode Listen Later Aug 27, 2022 78:08


This week we're talking a look at one of our favorite Hollywood tropes: the movie makeover montage! You know it well... our hero is defeated. They're new in town, they've been broken up with, they've been fired, they're in a rut, they're lost. But with a little help from their friends... BAM! ZERO TO HERO (just like that)! There are few things we love more than a glow-up of our favorite movie characters. In this episode, we break down the best makeover montages of all time and give our own ANTM-style Makeover Awards for the all-time greats, including: She's all that Legally Blonde She's the Man Miss Congeniality The Devil Wears Prada Clueless Mrs. Doubtfire First Wives Club Don't Tell Mom the Babysitter's Dead Pitch Perfect Bridget Jones Mean Girls 10 things I Hate About You Mulan Hercules Moana Cruella The Princess Diaries Dirty Dancing Remember the Titans Bend It Like Beckham Blue Crush Karate Kid Warrior Creed Rocky Knights Tale   Take a listen and follow @Valleygirlpodcast on Instagram to vote for your favorites! Byeeeeeee

Story Time with Elliana 📚
Curious George Takes a Train By: Margret & H.A Rey's

Story Time with Elliana 📚

Play Episode Listen Later Jul 10, 2022 9:13


Hello friendly listeners time to enjoy another story with Elliana a seven year old homeschool kid that loves to read to her Daddy and the world. Have a blessed day Byeeeeeee. --- Support this podcast: https://podcasters.spotify.com/pod/show/elliana--iuna/support

Moody Readers Podcast
Ep. 8 LETS KETCHUP

Moody Readers Podcast

Play Episode Listen Later Jul 5, 2022 45:02


Hi everyone! this week we'll be catching up with eachother. This episode was recorded in June (hints why we said Happy pride). We hope you all have been well. Enjoy the episode. BYEEEEEEE

ketchup byeeeeeee
Story Time with Elliana 📚
The Very Hungry Caterpillar by Eric Carle.

Story Time with Elliana 📚

Play Episode Listen Later Jun 27, 2022 6:52


A 7 year old reads to her Daddy come along for story time. Thanks friends Byeeeeeee.. --- Support this podcast: https://podcasters.spotify.com/pod/show/elliana--iuna/support

PUMPED Podcast
EP 2: Precipitous Labour, Homebirth & Two Babies: "A Whole New World"

PUMPED Podcast

Play Episode Play 30 sec Highlight Listen Later Nov 4, 2021 47:12


Have you ever heard of a precipitous labour? We hadn't until we had the chance to sit down with the lovely Ineka Gow. We chat about all things  fourth trimester including home birth, mumma life with two kids, and finishing a PhD. That's right, this clever cookie studies infectious diseases. If she sounds like a superwoman, it's because she absolutely is. This episode is brought to you with the help of our Sponsor, Night N Day Comfort, who are proud supporters of the Pumped Podcast. Remember to use PUMPED10 at the checkout for a special discount.Go to our website: www.pumpedpoddy.com for more information about us and don't forget to throw us a like on Facebook and a follow on our Instagram: @pumpedpoddy Byeeeeeee x

Badass Chicas
S5 - E12: Did someone say Night Stalker? Ft. Anonymous

Badass Chicas

Play Episode Listen Later Oct 29, 2021 23:04


Last episode of Season 5 we get an inside scoop on what went down the day Richard Ramirez aka the Night Stalker got caught. Hope you all have an amazing Halloween weekend and enjoyed this season as much as I did recording it! Thank you to all my guest who came over or submitted stories! Talk to y'all next season! Byeeeeeee!!!!! WARNING: SERIOUS TALKS ABOUT DEATH, SCARY AND TRAUMATIZING EXPERIENCES ALL SEASON! LISTEN AT YOUR OWN RISK

Quick Resume Podcast
Xbox 20th anniversary stream! Avowed, new Killer Instinct and more! QR podcast episode 29

Quick Resume Podcast

Play Episode Listen Later Oct 25, 2021 123:35


Today we cover 2 weeks worth of Xbox news in QRP fashion; gleefully! There is a 20th-anniversary stream coming soon, there was an Avowed leak from Jez Corden at Windows Central, Killer instinct was leaked, another MMO and a Wu-Tang game??? This stuff is getting hard to keep up with... That's not including the Starfield video, god damn SpongeBob Xbox, new SSD expansions, games pass C O N C E R N S or the mini-fridge launch. Anyway, we'll catch ya next week. As I type this the new Halo campaign overview has been revealed for tomorrow, so I'm pretty mad about it. Byeeeeeee. You can watch us on video at Youtube! https://youtu.be/DyO8V8mMQs8Come say hi on our Twitter! https://twitter.com/QuickResumePod You can also listen to us on all popular podcast platforms like Spotify, Anchor and Google podcasts! Just search for 'Quick Resume Podcast' and we will appear to jabber in your ear. See acast.com/privacy for privacy and opt-out information.

Keystone Copycats with Chris & Zach
Episode 201 - Point Break

Keystone Copycats with Chris & Zach

Play Episode Listen Later Jul 14, 2021 107:58


Welcome back to Keystone Copycats with Chris & Zach! We missed you. This week we kick off a new season that we're calling The Point Breakdown. As you can no doubt infer from the name, this season's Keystone movie is the 1991 surfing bank robber classic, Point Break. We get into our new tropes, ninja turtle sporting goods, and meatball subs. And, we scoop into the mail bag to answer a listener question. It's more fun than a barrel full of smaller barrels that are in turn full of smaller barrels which are in turn full of something that I can't quite make out, maybe it's Funyuns? Either way, enjoy our antics and tell your friends. Love you, BYEEEEEEE! Follow us on Facebook and Instagram @KeystoneCopycats and on twitter @KeystoneCopycat. You can direct your questions and comments to KeystoneCopycats@gmail.com OR you can leave us a voicemail at (513) 239-7682. https://blacklivesmatters.carrd.co/ https://anti-asianviolenceresources.carrd.co/

Showing Up
Ep. 12 - SCIFI WEEK! + FA Cup + Bitcoin Update + Jeff Bezos Yatch + CoronaVirus: Where did it really come from?

Showing Up

Play Episode Listen Later Jun 14, 2021 113:38


Join us this week as we talk about all things SCIFI!!! Your hosts Babs and Eve geek out on all sorts of scifi films and books, from classics such as Close Encounters of the Third Kind, Brightburn, Jurassic Park, For All Mankind, Star Wars, Dune, Silent Running, to Arrival, Life, Extinction, the X-Files, and many many more. But first we get on to the topics that highlighted our week: Leicester City match, European Super League drama, the luxurious yatchs of the super rich, and Fauci, the Wuhan lab, Gain-of-function research and the likelihood of Covid-19 having come from a lab. Tune in to this jam packed episode, and leave us a review! If you wanna chat to us, you can find us at showingupbabseve@gmail.com or on Instagram @showingupbabseve. We can't wait to hear from you! Byeeeeeee

The Greyboys at Large Podcast
The Greyboys At Large Podcast # 133 - Byeeeeeee

The Greyboys at Large Podcast

Play Episode Listen Later May 27, 2021 64:47


This week The Greyboys At Large Podcast sadly comes to an end. We can't thank all of you enough for listening to our nonsense over the past 133 episodes. We hope we managed to bring at least a few laughs to you guys. Thanks for listening. Thanks for being Greys. 

large greys byeeeeeee
Oddvice
33.5 - Bye For Now ❤️

Oddvice

Play Episode Listen Later Apr 22, 2021 63:33


The end of Season 1! Don't worry, Season 2 isn't far away. Thank you for all of your endless support - the community we've created is so close to our hearts. We love each and every one of you so so much. Keep up with us on our socials (@oddvicepodcast). Stay safe, stay healthy. BYEEEEEEE!!! Make sure to check out our sponsor! Better Help at betterhelp.com/oddvice. Come over to YouTube: YouTube.com/OddvicePodcast. Hosted by Kristen McAtee (@kristenmcatee) & Alex Koot (@alexkoot.jpg).

betterhelp byeeeeeee
King Of Bits
Byeeeeeee!

King Of Bits

Play Episode Listen Later Feb 5, 2021 22:26


This week Ruly tells you why you should annoy everyone around you. Also special voice message from a show favorite Chris Spring! He's gonna tell if he got that part! Enjoy donuts! --- Send in a voice message: https://podcasters.spotify.com/pod/show/the-ruly/message

byeeeeeee
Guyzrcrazy
Szn 1 *finale*

Guyzrcrazy

Play Episode Listen Later Dec 24, 2020 37:40


6 months later and you can have a lil break from us, as a treat. Hannah & Meg talk about Taylor Swift, dating during the holidays, New Years resolutions, the best places to cry in NYC, and what we've learned from season 1 of our world famous podcast! We'll be back on January 7th with an exciting new season, so stay tuned! Aaand in the meantime, catch up on all the episodes you've missed and make sure to subscribe, rate, review, and follow us on social media for updates. Byeeeeeee! --- This episode is sponsored by · Anchor: The easiest way to make a podcast. https://anchor.fm/app

Jyoti Wellbeing Podcast
JYOTI EP.26 : GOODBYE 2020

Jyoti Wellbeing Podcast

Play Episode Listen Later Dec 12, 2020 21:13


Episode terakhir di tahun ini oleh Jyoti! 2020 has many ups and downs but definitely an exciting year for Jyoti podcast. So, disini kita summarize semua episode yang pernah kita bawain dan harapan kita untuk episode berikutnya di season 4 di tahun 2021. Happy holidays and see you next year! Byeeeeeee 2020

byeeeeeee
Cognac & Chemistry
CC2: I'm Expecting Good Treatment

Cognac & Chemistry

Play Episode Listen Later Sep 6, 2020 59:20


Welcome back to another episode ! This week Ki and Marty discuss expectations in dating and relationships. Who pays for the date? What type of treatment do you expect once you become exclusive? Listen to the two chat about these topics. Don't forget to follow us on IG @cognacandchempod . Byeeeeeee

Cognac & Chemistry
CC2: My Pu$$y, My Rules Ft. Breast Side Story Pod

Cognac & Chemistry

Play Episode Listen Later Aug 21, 2020 69:38


Yerrrrrr! We're back on our new drop dayyyyy. Today's episode is Marty & Ki discussing the policing of women's bodies with special guests Ayana and Kaci of the Breast Side Story podcast. Yasssss our first guests!! Get into the convo, laugh at some jokes and get some insight on how women really feel. Don't worry Marty will get a chance to have the guys out number Ki. Thanks for tuning in and listening to Cognac and Chem ! Byeeeeeee !

Journeying through life
Shooting your shots

Journeying through life

Play Episode Listen Later Jun 13, 2020 9:41


Hi guysss! I have a special guest on today's episode and it's so exciting and interesting. You all should please listen and send in your feedback I hope you enjoy this episode! See you guys next week! Byeeeeeee

shooting shots byeeeeeee
Thinking Out Loud
Ventriloquist dummies are kind of creepy: The History, creepy stories, and some movie reviews about ventriloquist dummies.

Thinking Out Loud

Play Episode Listen Later Apr 18, 2020 55:09


In this episode I talk about ventriloquist dummies, the history behind ventriloquy, The Lady who had no Children Only Dolls, and read some movie reviews on horror/pyschological thriller movies. As always, have great day, a great life, a great whatever, stay safe out there and I'll see you next time, BYEEEEEEE!!!!!!! https://toplessrobot.com/2010/04/the_10_creepiest_ventriloquist_tales_of_all_time.php https://thevocalvent.com/scary-ventriloquist-doll-stories

Thinking Out Loud
some creepy, true unsolved mysteries

Thinking Out Loud

Play Episode Listen Later Feb 7, 2020 73:29


In this episode, I read various creepy unsolved murders where people don't know what exactly happened, how the death was caused, the identity of the victim, or who the killer is. here is the links for what I used in this episode https://www.ranker.com/list/unsolved-texas-mysteries/steve-wright https://oceanhero.today/images?q=true+scary+unsolved+mysteries&id=364CD8AB2E4C384DCF10D5772E72B00BFE0CD0C0 Hope you guys have a great day, a great life, a great whatever, stay safe out their, and I'll see ya next time, BYEEEEEEE!!!!!!

The Residuals: A Paranormal Podcast
Episode 11: I Have Dead People in My Neck

The Residuals: A Paranormal Podcast

Play Episode Listen Later Jan 30, 2020 56:04


A haunted hospital, college sleepovers, Zak Bagans, skydiving, The Cecil Hotel, ouija boards, surgery, and more! Can you believe it? We have a lot to tell you and most of it will probably keep you up at night. Start a chatroom with other listeners so you can commiserate. Byeeeeeee. * * * * * * * * * * Between the present and past there are memories held in the walls and earth.  Follow Emily and Joy as they explore the spaces between the living and the dead. Hauntings, extrasensory perception, and all things paranormal.   Welcome to The Residuals.   Music provided by www.purple-planet.com Twitter @TheResidualsPod Instagram @The_Residuals_Podcast ©2019

Thinking Out Loud
Chicago baby kidnapped 55 years ago was found, 33 unsolved missing persons cases, and a bit about The Lost Girls of Panama case

Thinking Out Loud

Play Episode Listen Later Dec 20, 2019 102:29


in this episode, I read an article that caught my eye earlier today, about how they found the baby that was kidnapped from a Chicago hospital 55 years ago, 33 unsolved missing persons cases, as well as a bit about The Lost Girls of Panama case. if you want read any of the articles yourself, or found about more information about the Lost Girls of Panama case, or any of the other cases mentioned briefly in this episode, such as the Elisa Lam case, here are the URL's for the websites that I used in todays episode: https://www.msn.com/en-us/news/crime/chicago-baby-kidnapped-55-years-ago-reportedly-found/ar-BBYcbEd?ocid=spartanntp https://thoughtcatalog.com/lorenzo-jensen-iii/2017/12/33-unsolved-missing-persons-cases-that-will-make-you-scared-to-ever-leave-your-house-again/ https://www.thedailybeast.com/the-lost-girls-of-panama-the-full-story Have a great day, a great life, a great whatever, stay safe out their, and I'll see you guys next time, BYEEEEEEE!!!!!!!

Thinking Out Loud
Christmas horror and ghost stories, and "A Strange Christmas Game" by Charlotte Riddell

Thinking Out Loud

Play Episode Listen Later Dec 8, 2019 52:29


Hi guys!!!!!!! since it is getting super close to the Christmas and other Holidays, I wanted to talk about some Christmas horror stories and some Christmas ghost stories. In this episode I also read "A Strange Christmas Game" by Charlotte Riddell. if you want to check out any of the websites I used in this episode, use these URLs right here https://www.littlethings.com/xmas-horror-stories/5 https://www.theparisreview.org/blog/2014/12/19/ghosts-on-the-nog/ https://www.shortstoryproject.com/story/strange-christmas-game/ I love you guys!!!!! have a great day, a great life, a great whatever, stay safe out there, and I'll see you next time, BYEEEEEEE!!!!

Debut Buddies
Euro Stuff with Kat Atwell

Debut Buddies

Play Episode Listen Later Jul 28, 2019 74:06


Mental health advocate, entertainer, published writer and mom, Kat Atwell comes to the show to battle Shannon on the theme of Euro Stuff. We talk about Frenching, Irish Goodbyes, Belgian Dips, and Double Dutch. Plus, some stories from Shannon's trip to Iceland, and Kat's pillow-mouthed former paramour... We also play Scootin' With Putin, Fuck Marry Kill, and Recast! Color you hair with Grecian Formula, and get ready to recess some headlights... It's A Vague Idea!If you like the show, please tell people, share links, etc. We don't advertise, so word-of-mouth is the jam.Follow us on social media at @avagueideapod on Twitter and @avagueideapodcast on Instagram.Check out Kat's work in McSweeney's: https://www.mcsweeneys.net/articles/5-underrated-places-a-woman-can-cry-in-peaceAnd, as Nate's new closing catchphrase goes: Live your life, and don't make the world worse...Byeeeeeee.

The High Low
Is "hey guys" anti-feminist?; & why we are better people than our worst joke

The High Low

Play Episode Listen Later Aug 1, 2018 58:45


Jeremy Hunt forgot his wife's nationality; someone tried to book 6 hotel rooms at The High Low (us neither); & Dolly smashed a glass of wine all over CJ's recording equipment. Hola August: the summer madness has officially begun! We discuss Jane Garvey's comment on Radio 4's Woman's Hour this week: that "hey guys" should not be used when a gathering includes women. Is "guys" an anti-feminist collective term; or has it evolved into unisex slang? And are there any non-gross alternatives?Also today, we talk about comedian and talk show host Trevor Noah and his distasteful 2013 joke about aboriginal women, which has recently re-surfaced and has seen Australians boycotting his upcoming tour in Australia. Should we be allowed to evolve beyond our past (worst) jokes? And what is the role of comedy, in a post-MeToo, Trumpian world?The High Low will be taking a summer break, so Pandora can play with her baby and Dolly can take a post-book tour breather. We'll be back on September 6th. Byeeeeeee!EMAIL: thehighlowshow@gmail.comTWITTER: @thehighlowshowLINKS:Fight Like A Girl, by Clementine Ford https://www.amazon.co.uk/Fight-Like-Girl-Clementine-Ford/dp/1760292362Paris For One (& Other Stories), by Jojo Moyes https://www.amazon.co.uk/Paris-One-Other-Stories-Discover/dp/1405928166/ref=sr_1_1?s=books&ie=UTF8&qid=1533158639&sr=1-1&keywords=jojo+moyes+parisAmerican Housewife, by Helen Ellis https://www.amazon.co.uk/American-Housewife-Helen-Ellis/dp/1471153800/ref=sr_1_1?s=books&ie=UTF8&qid=1533158662&sr=1-1&keywords=american+wives+helen+ellisHadley Freeman interviews Jameela Jamil, for The Guardian magazine https://www.theguardian.com/lifeandstyle/2018/jul/28/jameela-jamil-wont-become-double-agent-patriarchyTable Manners With Jessie Ware: https://www.acast.com/tablemanners/Jason Segel on WTF with Marc Maron: http://www.wtfpod.com/podcast/episodes/episode_623_-_jason_segelThe Florence Kleiner Bursary at The Old Vic: https://www.oldvictheatre.com/news/2018/07/the-florence-kleiner-bursaryWhy It's Wrong To Call Out Trevor Noah For Off-Colour Jokes They Made In Their Past, by Shappi Khorsandi for The Independent: https://www.independent.co.uk/voices/trevor-noah-dan-harmon-old-jokes-exposure-wrong-alt-right-james-gunn-a8466011.html See acast.com/privacy for privacy and opt-out information.

The Extra Magic Hour: A Walt Disney World Podcast!
Extra Magic Hour Episode 79: Byeeeeeee!

The Extra Magic Hour: A Walt Disney World Podcast!

Play Episode Listen Later Aug 17, 2017 71:04


This is the last episode of the Extra Magic Hour. Find out why by listening.

magic hour byeeeeeee