<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>The N00b Developer</title>
    <description>My blog where I can share random things</description>
    <link>http://jasonamyers.github.io//</link>
    <atom:link href="http://jasonamyers.github.io//feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Mon, 13 Jun 2022 01:28:58 +0000</pubDate>
    <lastBuildDate>Mon, 13 Jun 2022 01:28:58 +0000</lastBuildDate>
    <generator>Jekyll v3.9.2</generator>
    
      <item>
        <title>HP Dev One: a fantastic linux laptop</title>
        <description>&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-open.jpg&quot; alt=&quot;HP Dev One Laptop&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Recently, HP released a new Linux laptop called the HP Dev One. It ships with System 76’s POP OS. I’ve been a long-time Linux user and have loaded it on a ton of other computers. I’ve also purchased a few systems from System 76 and the Dell XPS Developer Edition myself. I’ve enjoyed the System 76 machines just fine, but I’ve been on the look out for something that felt a bit more premium.&lt;/p&gt;

&lt;p&gt;This machine fills well put together and is a great daily driver in my opinion. The order process was a dream. There is only one SKU and no build to order options. This initially seemed like a bummer, but all I wanted was more then the 16GB of RAM… more on that later. I ordered it on Saturday and had it by Tuesday, which in the current delays of shipping and availability felt stunning. Let’s take a look at the unboxing experience.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-outer-box.jpg&quot; alt=&quot;HP Dev One Outer Box&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-box.jpg&quot; alt=&quot;HP Dev One Box&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-box-side.jpg&quot; alt=&quot;HP Dev One Box Side&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-box-open.jpg&quot; alt=&quot;HP Dev One Box Open&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-docs.jpg&quot; alt=&quot;HP Dev One Docs&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-accessories.jpg&quot; alt=&quot;HP Dev One Accessories&quot; /&gt;&lt;/p&gt;

&lt;p&gt;As you can see this is more like the unboxing experience of higher end laptops, and while common in Apple, HP Omen, Microsoft Surface and Alienware laptops, this magnetically closed flap box is very well done. Additionally, everything is firmly held in place and has it’s spot. It lacks the charm of the System 76 art inside boxes, but this thing is a nice touch in a world of kinda boring boxes. I was disappointed that it didn’t have any stickers or extras in the box given it’s kinda niche and target market. It includes a small fold-out document and a barrel charger.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-ext-monitor.jpg&quot; alt=&quot;HP Dev One External Monitor&quot; /&gt;
So far, I’ve gotten roughly 7 hours of mixed-use for web development, browsing and writing with 20% charge left. I’ve yet to run it out in one sitting, and I usually run down my Macbook Pro 16” Intel during that time. Additionally, my HP Omen gaming laptop dies super quick in that time. I need to do a few Zoom calls on it to give it a proper workout, but that normally really eats the battery on anything I’m using. I am disappointed that it came with a barrel charger, as I want USB-C to just be used everywhere. In HP’s defense, this machine charges just fine over USB-C and that’s how I’ve charged it each time.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-open.jpg&quot; alt=&quot;HP Dev One Open&quot; /&gt;
I’m really enjoying the keyboard on this laptop. All the keys feel in the right place to me and I find the board to be firm and springy, not spoungy like some other laptops I’ve used.  Additionally, It has a trackpoint built-in and I LOVE THOSE! So for me, this is a big win, but this is a highly subjective assessment, and you will need to form your own opinion. Keyboard and mouse preferences are so personal. Another feature I love is the manual switch for the webcam that slides a cover over the webcam.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-webcam.jpg&quot; alt=&quot;HP Dev One Webcam Switch&quot; /&gt;&lt;/p&gt;

&lt;p&gt;An area that I wasn’t sure about was the screen. I’ve gotten pretty used to high end retina and 4K laptop screens; however, at this size the resolution hasn’t bother me at all. I was really worried about blurry fonts or artifacts, but text is tight and pretty crisp. It’s not retina for sure, but it’s very serviceable, and I’m not noticing any eye fatigue from using it for an extended period of time. I am really enjoying the overall size of the system.  Here it is compared to a 16” Macbook Pro M1.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-top-comp.jpg&quot; alt=&quot;HP Dev One Top Compare&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-side-comp.jpg&quot; alt=&quot;HP Dev One Side Compare&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’ve also enjoyed the port availability on this laptop, while I use USB-C for most everything, I’m often looking for a USB-A or HDMI to hook up quickly and both those are available on this machine. There is also a headphone jack.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-right.jpg&quot; alt=&quot;HP Dev One Right&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-left.jpg&quot; alt=&quot;HP Dev One Left&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Finally, this machine only ships in one spec with 16GB of RAM. Right after getting the system I knew I wanted to upgrade it so I would have more resources for containers and running services. This also allowed me a chance to reach out to support as I couldn’t find any documentation about how to do the upgrade. So I opened a case via the HP Dev One website, and I immediately noticed the customized experience. It took them about 20 minutes to answer me, and they supplied both the docs and a video covering how to perform the upgrade. Blowing my mind, he even followed up the next to see if I had any issues. I had ordered the RAM, and had zero issues with the install. It was so painless I forgot to take pictures of that part.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-support.png&quot; alt=&quot;HP Dev One Support&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-memory-1.png&quot; alt=&quot;HP Dev One Memory 1&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-memory-2.png&quot; alt=&quot;HP Dev One Memory 2&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/hp-one-memory-3.png&quot; alt=&quot;HP Dev One Memory 3&quot; /&gt;
&lt;a href=&quot;https://www.youtube.com/watch?v=RkAOS9f5p1I&quot;&gt;HP Video&lt;/a&gt;
&lt;a href=&quot;http://h10032.www1.hp.com/ctg/Manual/c07067671.pdf&quot;&gt;HP Manual&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So in conclusion:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;it’s fast&lt;/li&gt;
  &lt;li&gt;feels solidly built&lt;/li&gt;
  &lt;li&gt;I like the keyboard&lt;/li&gt;
  &lt;li&gt;I miss having a fingerprint sensor&lt;/li&gt;
  &lt;li&gt;It charges great over USB C&lt;/li&gt;
  &lt;li&gt;Has had 0 lag driving my external display 40” 5K/2K ultrawide&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I really liked buying my own memory to put in there much cheaper than I’ve seen from choosing it at the time of purchase from other vendors.&lt;/p&gt;

&lt;p&gt;So far I’d recommend this to anyone looking for a Linux first laptop with Pop OS.&lt;/p&gt;

&lt;p&gt;Want more speeds and feeds like info checkout &lt;a href=&quot;https://www.phoronix.com/scan.php?page=article&amp;amp;item=hp-dev-one&amp;amp;num=1&quot;&gt;Phoronix’s article&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Sat, 11 Jun 2022 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2022/hp-dev-one/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2022/hp-dev-one/</guid>
        
        <category>linux</category>
        
        <category>dev</category>
        
        <category>hp</category>
        
        <category>one</category>
        
        
      </item>
    
      <item>
        <title>MINI Cooper SE: our second electric</title>
        <description>&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/joules.jpeg&quot; alt=&quot;Joules&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Recently we picked up a MINI Cooper SE for my wife, who is a huge MINI fan.  We bought it as part of our move as a family to driving mostly electric vehicles. I also enjoyed the look of MINIs and gave up a MINI Countryman when I got my Model 3.  We’ve had the MINI Cooper SE for about a week and have put a few hundred miles on it, and wanted to share a bit about what I’ve learned in that time.&lt;/p&gt;

&lt;p&gt;First, the MINI is built for a different person than the Tesla is. To me, the MINI is for drivers and Tesla for tech people and those who want to let the car drive them. Let’s start with the elephant in the room first, range. The first thing people often talk about on the MINI is the range, which is 100miles or so in our experience this week. There hasn’t been a trip yet in our week that hasn’t been easily doable with this range, including a 30 mile one-way trip home from the dealer, and a trip there and back later in the week to get a feature added. Range is often touted as the main factor in a lot of people’s electric car decisions. I really which people would consider their actual driving habits when considering their range needs. Each day starts with a full battery, so you don’t need days at a time of range.  With that said, 100miles feels right at the bottom end of a commuter car to me and a sweet spot for a city car for my wife. I drive about 60 miles a day, and if we consider winter range losses, it might be around my number (I’ll share that once it gets cold again). However, my wife drives 15 miles to work each day, which is well within the range in any weather.&lt;/p&gt;

&lt;p&gt;Tesla has made a name for itself with its quick 0-60 speeds around 4.4 or so in my Model 3 in regular mode. I drive around in my Tesla most of the time in the chill mode because I prefer the smoother acceleration in stop and go traffic and when using autopilot. The MINI does 0-60 is around 7.5 seconds, which is pretty much what chill mode does.  It’s quick enough and vigorous enough to make slicing through city traffic or highway merging a breeze. The handling in the MINI is much like its predecessors and feels like a go-cart, which I love. My Tesla feels a bit like a shark knifing through waters, smooth and easy. The driving experience is a matter of preference, but I enjoy driving the MINI a bit more. A huge drawback for me in the MINI is the lack of Adaptive Cruise Control and Lane Keep Assist. Tesla’s standard AutoPilot makes quick work of a morning interstate traffic flow. The MINI’s close cousin, the BMW i3, has excellent ACC/LKA features as well. But when you put Tesla’s Navigate on AutoPilot on there as well, and all other systems feel outdated.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/seats.jpeg&quot; alt=&quot;MINI Seats&quot; /&gt;
Also, I think I enjoy the driving experience because of the seats in the MINI as well. While not as fancy as the seats in my model 3, which are fully adjustable and memorized each driver, the MINI seat is comfortable. It hugs you in without making you feel trapped and is much cushier under you as well. BMW (who builds MINI) has a long history of proper car seating and finishing inside touches. That continues to be right in the MINI Cooper SE.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/mini-interior.jpeg&quot; alt=&quot;Joules&quot; /&gt;
MINI has chosen to retain the standard button and control setup typical in their F series cars, and that is awesome for people who prefer physical buttons over touchscreens; however, they have a friendly touch screen system in the vehicle as well. 
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/mini-hud.jpeg&quot; alt=&quot;Useful Heads up Display&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/mini-screen.jpeg&quot; alt=&quot;Beautiful Behind Steering wheel screen&quot; /&gt;
Telsa owns in this area for me, though. The Tesla system is more responsive, intuitive, and modern. I do wish it had a few buttons as well for specific settings.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/mini-car-play.jpeg&quot; alt=&quot;Joules&quot; /&gt;
Tesla talks a lot about their entertainment options (Hulu, Netflix, etc.); however, I rarely use these, and I don’t consider them an attractive feature for me. Nonetheless, I can imagine that some parents love it. What I miss in my Tesla is SiriusXM, I enjoy it and do use my phone’s Bluetooth connection to stream it to my Tesla, but the MINIs built-in Sirius is both more comfortable and safer to use. The MINI also has full CarPlay support, which adds some quality features to the entertainment system overall if you are in the Apple ecosystem.&lt;/p&gt;

&lt;p&gt;So for our family, the MINI Cooper SE is a perfect electric car. It can handle most anything our days throw at it and be a fun daily driver. For longer trips, it’ll be more difficult. A typical trip for us is to the Smokey mountains and around 230 or so miles. That means roughly three charging stops in the MINI vs. one in the Tesla. These charging trips aren’t long, and even in the Tesla, I end up stopping twice because of my travel habits (My god, why did I drink that massive bottle of water), but it does mean you can’t hide most of the charging over a meal with the MINI on a trip like that. The charging process is quick, and in my area, Level 3 high-speed chargers are plentiful along the way to my most common travel destinations for both vehicles. 
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/mini-quick-charge.jpeg&quot; alt=&quot;MINI DC Fast Charge&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/joules-and-teddy.jpeg&quot; alt=&quot;Joules and Teddy&quot; /&gt;
So I’d recommend either one of these cars to someone interested in electric vehicles, both are winners for different reasons and have a place in the EV market.  If I could have anything I wanted, I would take the Audi E-Tron or Tesla Model Y today. However, if you want a small city car, then the MINI Cooper SE is a delight, and if you want a mid-size sedan, then the Tesla Model 3 is also enjoyable.  I want MINI to make a fully electric Countryman (SUV) with around 250 miles of range or so, that would make the switch my next dream car from the Audi to the MINI. In the more realistic future, I’ll likely consider the Model Y.&lt;/p&gt;
</description>
        <pubDate>Mon, 23 Mar 2020 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2020/mini-cooper-se-second-eletric-car/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2020/mini-cooper-se-second-eletric-car/</guid>
        
        <category>MINI</category>
        
        <category>EV</category>
        
        <category>electric</category>
        
        <category>Tesla</category>
        
        <category>Model 3</category>
        
        
      </item>
    
      <item>
        <title>SICP with Dave Beasley</title>
        <description>&lt;p&gt;He creates a space and invites you to explore it with him.  That’s how I describe taking a class from Dave Beasley.  I view Dave as an inquisitive soul with a devilishly sharp mind and the heart of an explorer.&lt;/p&gt;

&lt;h2 id=&quot;act-i-recursive-iteration-accumulation&quot;&gt;Act I: Recursive Iteration Accumulation&lt;/h2&gt;

&lt;p&gt;His SICP class gives him the space to do just that, and take you along for the ride.  The course opens with an exploration of computing and programming in scheme (racket lang); however, this class isn’t about that. This class is about exploring the composition of programs, how you can design them, and ultimately how you can create an interpreter.&lt;/p&gt;

&lt;p&gt;This class has quite a bit of math in it, but not in an overwhelming way. It provides the basis for examples and allows for reviewing different solutions to a similar problem. You’ll learn how to solve the cases recursively and iteratively. All of this is building over the first two days leading towards creating a scheme interpreter in Python. This exercise ties together the first couple of days and is such a treat to see the way all the prior efforts can be composed to build a language.&lt;/p&gt;

&lt;h2 id=&quot;the-second-act-owning-the-staging&quot;&gt;The Second Act: Owning the staging&lt;/h2&gt;

&lt;p&gt;Next, there is a lovely trip through lambda calculus (don’t worry about the math, you got this.) and a peek at the y combinator. There is a discussion of church numerals and functions generating functions. Here is where things can get interesting. Once you can generate functions with other functions, you are at the foundation of this course.&lt;/p&gt;

&lt;p&gt;Building a scheme interpreter in scheme, and here, Dave shines more brilliantly than at any other point in this class. (To be clear, Dave does a fantastic job throughout the course, but he steps it up here.) He began with a simple evaluator function, moved into a beautiful message passing evaluator, and then it was time for lunch. At lunch, he asked us how far we wanted to descend into madness. This class asked him to take us off the deep end and after a coffee Dave 100% delivered.&lt;/p&gt;

&lt;h2 id=&quot;the-third-act-a-decent-into-madness&quot;&gt;The Third Act: A decent into madness&lt;/h2&gt;

&lt;p&gt;We began by exploring lazy evaluation in our interpreter and metacircular evaluation. Then Dave took us way off the deep end by exploring Nondeterministic computing and the Amb evaluator. This exploration of Amb was fantastic, first off I’ve always been fascinated by nondeterministic computing, and Dave explained that he hadn’t done this part of the class before. Dave continued to explore this area with us. It was clear he was thinking through the problem, and he spoke out loud as he pondered the solution. Watching Dave chew on something that is still not fully known to him is a rare glimpse into the deep parts of how Dave attacks problems.  For me this was the absolute best part of the class.&lt;/p&gt;

&lt;p&gt;The class ended with us lost in the middle of a problematic part of the evaluator looking at the lambda special form. It wasn’t a clean break, and honestly I’m not sure what would have been one with our demand for taking us off the deep end. Dave always delivers, and we awoke the next morning to a message from Dave with a solution to the Amb evaluator problem. Truly the close to the week that Dave deserved. (I also think this reveals a part of Dave’s true self. He had to finish the problem. He had to share what he found.)&lt;/p&gt;

&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;/h2&gt;

&lt;p&gt;I’m always amazed at how Dave runs a class. They are small classes, and he humors each person’ questions in the class. He is playfully batting some of them away, giving them space to talk along through some, and diving into the details of others. It takes a true educator to meet people on their terms. We had a mix of people with a wide array of backgrounds, feelings about functional languages,  and in my opinion Dave gave all of us a robust set of take aways and a wonderful experience.&lt;/p&gt;

&lt;p&gt;This class isn’t something you immediately take back to work; nonetheless, it is a class that will affect your work. For me, I’m going to be thinking a lot more about different ways I can explore and understand a problem. Additionally, this class solidified some concepts I had been mulling over since I took Dave’s compilers class. I always ask myself after each one of the classes I pay for I ask myself “would I do this again?” And for the fourth time after one of Dave’s classes, I’ve had a resounding yes. It’s time to save up to take the rafting trip class.&lt;/p&gt;
</description>
        <pubDate>Sun, 04 Aug 2019 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2019/beasley-sicp-class/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2019/beasley-sicp-class/</guid>
        
        <category>Beasley</category>
        
        <category>class</category>
        
        <category>SICP</category>
        
        
      </item>
    
      <item>
        <title>Tesla Model 3 Trip: Kitty Pickup</title>
        <description>&lt;p&gt;So today, the wife and I headed back to GA to pick up our new British Shorthair kittens. Well, it was supposed to be just one, but I got my wife her own and kept it a secret until yesterday.  This time, we were heading to Suwanee, GA, which is near Alpharetta/Roswell. That meant we had a long stretch without a supercharger in our path. Teddy is the name of our Long Range All Wheel Drive Tesla Model 3.&lt;/p&gt;

&lt;p&gt;We began this morning at 5 AM. I raised Teddy’s max charge to 100% and let him continue to charge while we got ready. About 16 minutes later, we were packed and ready to go, and Teddy was at 94%. Our trip is a pretty long one, broken into two stretches. The first stretch is from our house to the Manchester, TN supercharger, a common stopping point for us. Our next step was to be the Alpharetta Supercharger, or so we thought…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-1-home-quick-charge.png&quot; alt=&quot;Teddy Trip top up&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;up-and-at-em&quot;&gt;Up and At ‘Em&lt;/h1&gt;

&lt;p&gt;We made the roughly 32-mile drive to Manchester with no problem. 
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-2-to-manchester-sc.png&quot; alt=&quot;To the Manchester SC&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The supercharger is in the back of a Dunkin’ Donuts parking lot. YEAH, BREAKFAST! We pulled in Teddy and popped inside for a quick bite. We finished eating in about 20 minutes and walked back to the car which has charged from 77% to 96% in that time. That’s amazingly quick charge time. Reduced charge times are due to the new 150A charging that Model 3’s can get.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-3-manchester-sc.png&quot; alt=&quot;Charging at the Manchester SC&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;a-bit-of-knowledge-about-supercharging&quot;&gt;A Bit of Knowledge about Supercharging&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-3-manchester-sc-irl.jpeg&quot; alt=&quot;Empty Manchester SC&quot; /&gt;
Additionally, the supercharger was empty, and while you don’t get all the juice from the whole place, it does mean that you aren’t sharing a charging circuit with anyone else.  You see the Tesla superchargers have several stations at them and they have labels, for example, we charged at 2A here this morning. There is also a 2B at this station, and it would share a charging circuit with me if someone would have plugged in there.  I learned this not that long ago, and it was something I didn’t know about charging the car initially.  You should always try to find an unused circuit when you pull up to a supercharger, and if one isn’t available, then share one with someone else.&lt;/p&gt;

&lt;h1 id=&quot;to-the-next-stop&quot;&gt;To the next stop&lt;/h1&gt;

&lt;p&gt;After giving teddy an electron high, we headed off to our next destination.  I used abettertripplanner.com to help plan our charging for this trip, and it suggested the Alpharetta supercharger.  I had enjoyed great luck with their trip plans before, so I blindly trusted it.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-4-abetterrouteplanner.png&quot; alt=&quot;A Better Trip Planner&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I tried to enter that into the cars GPS, and it didn’t come up, but the Alpharetta Tesla showroom and service center did come up.  I thought it might be like ours in Franklin, TN, a combo center and supercharger. Off we went…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-5-alpharetta-showroom.png&quot; alt=&quot;To Alpharetta!&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;i-am-so-dumb-like-so-so-dumb&quot;&gt;I am… so dumb… like so so dumb…&lt;/h1&gt;
&lt;p&gt;On the way there, I got in a spot where I wanted to get around a tractor-trailer to get back into the right-hand lane to let someone who was very close to the rear of my car to pass. I hit the gas going downhill, and Teddy gives me his rollercoaster-like acceleration instantly as always… then I heard it. BEEP BEEP BEEP (red steering wheel on the screen) my wife freaked a tiny bit, but I knew what was up. I had entered autopilot jail.&lt;/p&gt;

&lt;p&gt;You can only go so fast with autopilot engaged before it will disable it for the rest of the drive! There was no way I was driving to Alpharetta from Jasper. I use autopilot as much as I can. I’ve not been in autopilot jail before as I’m a rule follower; however, here I was squarely in it. I tried rebooting the software (you can drive the car like a normal car while doing this!), and that didn’t get me out of jail either. I gave up and stopped at a rest station near there and put the car in park and I was released from autopilot jail. I’ve become dependent (read as addicted) to autopilot. The wife had a good laugh at me, and off we went again.&lt;/p&gt;

&lt;h1 id=&quot;youve-arrived-at-your-destination-maybe&quot;&gt;You’ve arrived at your destination maybe&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-5-alpharetta-showroom-irl.jpeg&quot; alt=&quot;To Alpharetta!&quot; /&gt;
Photo Credit: Reddit user u/BlargyMcBlargFace&lt;/p&gt;

&lt;p&gt;We arrived at the Alpharetta service center only to learn that they don’t have chargers for public use there! I was … shocked and confused and panicked for a second; however, the service tech there reminded me how to find additional superchargers in the car, and after stopping to think for a minute I quickly realized two things.&lt;/p&gt;

&lt;h1 id=&quot;you-better-think&quot;&gt;You better Think&lt;/h1&gt;

&lt;p&gt;My car has a ton more range than I typically use, and I can make it all the way to pick up the cats and then down to a different supercharger about 30 minutes away from the cat lady! I had about 26% battery. That’s a metric ton of miles, and my brain forgets that. 100% battery = 310 miles for my car at the base usage. We were running at 104% efficiency, so 4% above base was available. Even without that extra boost, we had more than 80 miles left. Range anxiety is a thing that gets mentioned a lot with electric cars, and when I first got my car, I was very nervous about it. It has been several months since I had thought about range, and this was the first time in longer than that in which I was anxious. That quickly subsided once I thought rationally about what I had available vs. some silly percentage. My car had already told me it could make it; nonetheless, I still had a moment because the charger I had wanted didn’t exist. But that didn’t even matter because just a tiny bit away was another one.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-6-suwanee-pickup.png&quot; alt=&quot;To the Pickup Site&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We drove from the Alpharetta service center to the cat lady’s house with no issues. Hung out for a bit, took Mille and Basil (the cats’ names).&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-6-murder-floofs.jpeg&quot; alt=&quot;Murder Floofs&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;targets-aquired-homeward-bound&quot;&gt;Targets Aquired: Homeward Bound&lt;/h1&gt;

&lt;p&gt;Now we were off to the Atlanta Supercharger and to get some food. We made it with 14% battery left. That is the lowest I’ve ever had it, but it goes to show that after I panicked, I completed my trip to my destination and headed to the next supercharger and still had 14% left.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-7-to-atl-sc.png&quot; alt=&quot;To ATL SC&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We plugged into the Atlanta supercharger, which is located in a nice parking garage where are a bunch of food and shopping options.&lt;br /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-8-atl-sc-irl.jpeg&quot; alt=&quot;To ATL SC&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We had the cats in the car, and we turned on dog mode. Dog mode leaves the AC and music on along with putting a message on the screen informing people of the temperature in the car (70 in our case), and we headed up to get some food. We enjoyed a nice meal at BGR and went back to the car where we enjoyed the darkness of the parking garage and the coolness of the car. We charged from 15 to 93% in 1hr and 7 minutes. So basically we ate and hung out for 15 minutes gooing and gawing over our sleeping kittens before heading home. This charging session was the longest ever for us. The supercharger had one open space when we arrived so we did have to split a charging circuit, but the break was welcome after already spending 4 hours on the road.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-8-atl-sc.png&quot; alt=&quot;Electron High at ATL SC&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;smuggle-these-kitties-across-state-lines&quot;&gt;Smuggle these kitties across state lines&lt;/h1&gt;

&lt;p&gt;If you read our last trip to the Georgia Aquarium, you’ll remember I thought we could have made it home.  This time I wanted to give it a shot. Because I didn’t want to go to the Chattanooga supercharger again.  Worst-case scenario, we would have to hit the Manchester one again.  So off we went starting at 93%&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-9-home.png&quot; alt=&quot;Homeward Bound&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We arrived all the way home after a couple of bio breaks with 16% left in the battery; including stopping in traffic from an accident in Manchester near exit 105. These things don’t panic me because of how little energy gets consumed in a traffic jam.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-10-home-charge-up.png&quot; alt=&quot;Recharging at Home&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;got-home&quot;&gt;Got Home&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/kitties-11-trip-overview.png&quot; alt=&quot;Overview map&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In total, we drove 487 miles today, and we paid nothing to make this trip. We had no charging costs (our supercharging is free until October). If we had had to pay for our supercharging, it would have cost $7.18 and still would have saved $38.16 in gas compared to our 2018 MINI Countryman and current gas prices.&lt;/p&gt;

&lt;p&gt;Every time I think I understand what to expect from my car, I’m surprised by something I’ve forgotten or some fear that I made up in my head and didn’t think about it. Having that charger not been there could have gone a different way. I had a backup plan already in mind (however, it would have been so much slower.)  In the end, all I needed to do was think about what that percentage meant and just trust the car. You can view the charge percentage as miles in the car, and I found myself obsessing over it and switched to the percentage to avoid trying to “hyper mile.”  The stop at a nicer supercharger and the break made the rest of the trip a breeze.&lt;/p&gt;

&lt;p&gt;On this trip, we had one phantom breaking, one two-step lane change, and one panic and take over. Oh yeah… and autopilot jail… (eyeroll) Anyway, the phantom breaking was due to a dip in the road that aligned with an overpasses shadow. The two-step lane change was due to it being wet and a car coming up two lanes over. The panic was the most interesting one. Teddy was in the second lane leaving ATL when the lanes all shifted to the right in a construction area, and a truck in the right-hand lane didn’t get over the solid white line. We had a solid white line on the left as well, and Teddy didn’t want to avoid the truck by crossing that line or so it seemed in my head. Either way, we got the super loud beeps and the take over message.&lt;/p&gt;

&lt;p&gt;All in all, I drove about 23 miles of the trip between parkig garages, neighborhoods, stop signs/lights, and sigh… autopilot jail.&lt;/p&gt;
</description>
        <pubDate>Sat, 20 Jul 2019 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2019/tesla-trip-kitty-pickup/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2019/tesla-trip-kitty-pickup/</guid>
        
        <category>Tesla</category>
        
        <category>Trip</category>
        
        <category>Model 3</category>
        
        
      </item>
    
      <item>
        <title>Tesla Model 3 Trip: Atlanta</title>
        <description>&lt;p&gt;Recently, my wife and I were going to make a day trip to go to an event at the Georgia Aquarium. This trip is about 217 miles and is pretty doable no a charge to 100%. We had planned to get up super early (5 am CST) on a Saturday to get there by the 9:30 (EST) time our event started.  The wife and I kept considering going down a day early to avoid all the early morning driving and arriving at our event already tired.&lt;/p&gt;

&lt;h1 id=&quot;about-teddy&quot;&gt;About Teddy&lt;/h1&gt;

&lt;p&gt;Teddy is the name of our Long Range All Wheel Drive Tesla Model 3. We have 19” Sport Wheels, Enhanced AutoPilot, and Full Self Driving. Due to us using a friends referral code, we have free supercharging into next year.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/teddy.jpg&quot; alt=&quot;SC 1&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;a-change-of-plans&quot;&gt;A change of plans…&lt;/h1&gt;

&lt;p&gt;We made the decision just shortly after lunch on Friday.  A last-second change might send people unfamiliar with electric cars into a bit of a panic about the battery range. I had charged it to 90% the night before and driven it to work that day. So I was in Nashville with 78% charge when it was time to head home.&lt;/p&gt;

&lt;h1 id=&quot;day-1-of-our-trip-rushing-to-leave-and-stopping-to-charge&quot;&gt;Day 1 of our trip: Rushing to leave and stopping to charge&lt;/h1&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-1-nash-atl.png&quot; alt=&quot;Day 1: Overview Map&quot; /&gt;
As you can see, I came home from work in nashville, we picked up the dogs at home and dropped them off at the vet’s for boarding and started on our trip with about 66%. With the charge at 66%, I get over 150 miles, but not enough to get to Atlanta.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-1-nash-manchester.png&quot; alt=&quot;Day 1: Nashville to Manchester&quot; /&gt;
We decided we would stop for a burger and a car charge in Manchester. It’s got a lovely supercharger behind Dunkin Donuts and near Russell Stovers (aka good ice cream). We went from 49% to 95% in 33 minutes at the supercharger for free!  This level of charge left us with more than enough to get to Atlanta and the hotel we had selected.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-1-manchester-sc.png&quot; alt=&quot;Day 1: Manchester Supercharger&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Navigate on Autopilot with no confirmation lane changes was nearly flawless from Manchester to Atlanta. We had one aborted lane change and one episode of phantom breaking due to the way a car crossed in front of us.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-1-manchester-atl.png&quot; alt=&quot;Day 1: Overview Map&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;youve-arrived-at-your-destination&quot;&gt;You’ve arrived at your destination&lt;/h1&gt;

&lt;p&gt;One of the other excellent features of a Tesla charging network besides superchargers is destination chargers. While not as fast as a supercharger, these chargers are where you want to go and spend time in our case that meant a hotel. No not every hotel in Atlanta has a destination charge, a whole bunch did. We found one that had a AAA discount, Aloft Atlanta. We found it using the &lt;a href=&quot;https://www.tesla.com/findus?v=2&amp;amp;search=atlanta&amp;amp;bounds=33.76591081193077%2C-84.38086890535737%2C33.75935506270841%2C-84.39838909464265&amp;amp;filters=destination%20charger&amp;amp;zoom=17&amp;amp;location=dc14470&quot;&gt;Tesla destination charging website&lt;/a&gt; earlier in the day.&lt;/p&gt;

&lt;p&gt;When we arrived with 29% battery, the valets took my car straight to the charger and plugged it up.  They knew exactly what they were doing and made sure all the Tesla and other electric cars at this hotel were ready to go in the morning rotating as needed.  I saw one Model S and two Model 3s plus ours in the hotel parking lot along with a couple of Nissan Leafs.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-1-destination-charge.png&quot; alt=&quot;Aloft Destination Charger&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When we awoke the next morning, the car was charged back up to 90% again for free. I Regularly charge my car to 90%. I only use 100% when I need it for a trip - see the &lt;a href=&quot;http://www.jasonamyers.com/2019/tesla-trip-gatlinburg/&quot;&gt;Gatlinburg trip&lt;/a&gt;.&lt;/p&gt;

&lt;h1 id=&quot;play-with-the-fishes&quot;&gt;Play with the fishes&lt;/h1&gt;

&lt;p&gt;We made the short drive over to the aquarium and enjoyed our visit there. The aquarium had a bunch of level-2 chargers, but thanks to the full charge via the destination charger at the hotel, we left those spots for other vehicles that might need them and parked in a regular place.&lt;/p&gt;

&lt;p&gt;Famished, after all the behind the scenes and walking the rest of the aquarium with our reef club, we headed to get some food nearby.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2-aquarium-food.png&quot; alt=&quot;Day 2: Aquarium and food&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;part-2-of-our-trip-north-by-north-west&quot;&gt;Part 2 of our trip: North by North-West!&lt;/h1&gt;

&lt;p&gt;After that quick stop, we set off towards home. It’s worth noting that we likely had enough charge to get home, but I had never been to the Chattanooga supercharger before, so off we went.
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2-atl-chattanooga.png&quot; alt=&quot;Day 2: Atlanta to Chattanooga&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This was the first time I’ve ever been disappointed at a supercharger location. It at the Chattanooga airport, and when we arrived on Sunday all of the food, snack, whatever places outside of security were all closed.  We did manage to find a vending machine and use the bathroom, but overall, it was a disappointment. We went from 45% to 90% in 25 minutes. 
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2-chattanooga-sc.png&quot; alt=&quot;Day 2: Chattanooga Supercharger&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Navigate on Autopilot with no confirmation lane changes was flawless from Atlanta to Murfreesboro! We finished off our trip back to Murfreesboro and grabbed a bit to eat. After it was all said and done, we got home with 47% charge. 
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2-chattanooga-murfreesboro.png&quot; alt=&quot;Chattanooga to Murfreesboro&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2-food-home.png&quot; alt=&quot;Resturant to Home&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2-home-charge.png&quot; alt=&quot;Recharging at Home&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2-atl-murf.png&quot; alt=&quot;Day 2 - Overview map&quot; /&gt;
This was the first full long trip I had done with Navigate on Autopilot with the lane change in a city as complex at Atlanta. It worked wonderfully both going and coming. I never felt nervous for a moment about how much range we had left at any point in the trip.  In total, we spent 58 minutes charging on the whole trip. Both times it was when we wanted a break or food. We paid nothing, as in $0.00, for charging on this entire trip as I still have free supercharging on my car!&lt;/p&gt;

&lt;p&gt;I’d love to make a more extended trip and really test out how that changes the impact of my charging.&lt;/p&gt;
</description>
        <pubDate>Tue, 25 Jun 2019 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2019/tesla-trip-atlanta/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2019/tesla-trip-atlanta/</guid>
        
        <category>Tesla</category>
        
        <category>Trip</category>
        
        <category>Model 3</category>
        
        
      </item>
    
      <item>
        <title>First Tesla Model 3 Trip: Gatlinburg</title>
        <description>&lt;p&gt;Just got back from my first trip in my Tesla Model 3. I was a bit nervous, but mostly because my first trip also included my in-laws riding with us. I get along with them great but I knew if the car became a burden during the trip, it wouldn’t just be me affected or me and my wife, but all of us. Two of which didn’t care about the mission or vision of electric vehicles; they just wanna go on vacation and have fun. (to be fair… so did I.) We went from our home to Gatlinburg and back. It’s right at 239 miles one way with a rough overall elevation change of 917ft.&lt;/p&gt;

&lt;h1 id=&quot;about-teddy&quot;&gt;About Teddy&lt;/h1&gt;
&lt;p&gt;Teddy is the name of our Long Range All Wheel Drive Tesla Model 3. We have 19” Sport Wheels, Enhanced AutoPilot, and Full Self Driving. Due to us using a friends referral code, we have free supercharging into next year.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/teddy.jpg&quot; alt=&quot;SC 1&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;day-1-to-the-mountains-frodo&quot;&gt;Day 1: To the Mountains Frodo!&lt;/h1&gt;
&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/there-1.png&quot; alt=&quot;Overview&quot; /&gt;
We took off in clear, crisp weather and drove a few hours until we need a restroom break. Not sure why you always start off a trip by eating, but it sure ensures you’ll need a break.  We put in our destination address in Gatlinburg, and it suggested that we’d need to hit the Knoxville supercharger to ensure we had all the charge we’d need to get there. We made it to Crossville (about 2 hours) before needing a break. We got 2019.8.5 right before we left. I didn’t realize we’d need to enable the Navigate on AutoPilot No Confirmation setting before the trip. Even so, we have 0 aborted lane changes, and 0 weird two or three step lane changes. (that’s what I call it when it starts the lane change, changes its mind, then completes it after all.) I did enable the No Confirmation NoA at our break and then we were off to the supercharger.&lt;/p&gt;

&lt;p&gt;We rolled up to supercharger with about 20 percent left, and I never got nervous about making it. Everything was so smooth, and No Confirmation NoA was just amazing. I had 0 aborted lane changes, and 0 stepped lane changes. I was just stunned at how much easier this trip was.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/leg-1.png&quot; alt=&quot;Leg 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The Knoxville Supercharger was located just off the interstate in a mall. We hooked up Teddy and off we went to get some food at the O’Charleys that was right beside the supercharger. I upped the charge level to trip level (100%). We didn’t adjust anything about our meal. We just ate, and went back to the car. (To be fair, I did check the stats IOS app about 100 times during the meal, but I didn’t tell them to slow down or take longer or anything.) It took us about 50 minutes or so eat, and that got us back to 95% charged.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/sc-1.png&quot; alt=&quot;SC 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now it was time to finish off the trip to the cabin. It was also perfect via NoA until we got to the little roads that I had to drive on that go up into the mountains. We had a cabin that was perched pretty high up on the side of a mountain. The car handled wonderfully on the way up the narrow, twisty, steep roads heading up to the cabin.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/leg-2.png&quot; alt=&quot;Leg 2&quot; /&gt;
&lt;img src=&quot;http://jasonamyers.github.io//assets/images/the-view.jpg&quot; alt=&quot;The View&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I tried charging using the outside 120v outlets at the cabin, and this didn’t work. It seems like the porch outlets were just not working at all. Oh well. Once the whole family got there, it was time to get back down the mountain to get some grub and supplies.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/night-1-dinner-groceries.png&quot; alt=&quot;Supply Run&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Back to the cabin and call it a day!&lt;/p&gt;

&lt;h1 id=&quot;day-2-what-if-we-just-chill-and-grill&quot;&gt;Day 2: What if we just chill and grill?&lt;/h1&gt;

&lt;p&gt;I got up and wanted coffee, and thought about using one of the destination chargers. The Inn at Christmas Place has a Tesla destination charger and is across the street from Starbucks and Mellow Mushroom… Pizza and Coffee make for a happy geek.  Anyway, down the mountain I went.  I spent roughly an hour reading and sipping on my coffee. Then went back up the mountain to join the family.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/charge-trip-1.png&quot; alt=&quot;Coffee and Electrons&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So this charging trip only netted me about 5% battery after you take out the up and down on the mountain, and this kinda… bleh. The destination chargers are just like the Tesla home wall chargers so while they are faster than a level 2 charger, they are nowhere near a supercharger’s capabilities. This is fine, you just need to consider that when you are making plans. (keep reading to day 3 for more one destination chargers). If I were going to spend more time near this charger or stay the Inn, this would have been totally epic!&lt;/p&gt;

&lt;p&gt;So after rejoining the family, they decided it would be a good day to grill. They were right. We made another supply run, and that completed the day.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2-groceries.png&quot; alt=&quot;Supply Run #2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now, I decided I would try charging at the cabin again. I had brought a nice outdoor extension cord and ran from an inside outlet out the front door to the car. I got about 8% in 6.5 hours. So this would work for nice overnight charges, but it’s not effective at all for short durations, and 100% matched my expectations.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/cabin-charge-2.png&quot; alt=&quot;Cabin Charge&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That ended the day and here is our overview map.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-2.png&quot; alt=&quot;Day 2 overview&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;day-3-lets-get-out-of-this-pine-box&quot;&gt;Day 3: Let’s get out of this pine box!&lt;/h1&gt;

&lt;p&gt;On Day 3, we decided we would go roam around The Island and go to the track for some go-cart racing, putt putt golf and arcade gaming. This was awesome because The Island is where another destination charger is located. (I didn’t prompt the family to go here, it’s just a popular shop, eat and drink spot.) Down the mountain again…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-3-outing.png&quot; alt=&quot;Day 3 Outing&quot; /&gt;&lt;/p&gt;

&lt;p&gt;When you get to The Island you go to the Margaritaville hotel valet and ask them to use the chargers. They can park it for you or you can park yourself… I drove it myself. :P The parking is closer to all the shops at The Island than the normal parking lot, and it’s easy to get into and out of.  We stayed at the island for quite a while, and the charging was great!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-3-dest-charge.png&quot; alt=&quot;Day 3 Charging&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We got a significant charge in here, and this is the real power of the destination chargers. They are where you want to go already, and surrounded by things you likely will spend some time at. We walked around all the shops, did a moonshine tasting, and grabbed a snack at the Timberwood Grill. The whole time we had fun Teddy was getting an electron high. Now off to the Track and dinner!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-3-more-fun-dinner.png&quot; alt=&quot;Day 3 fun&quot; /&gt;&lt;/p&gt;

&lt;p&gt;And back up the mountain…&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-3-done.png&quot; alt=&quot;Day 3 home&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That ended the day and here is our overview map.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-3-overview.png&quot; alt=&quot;Day 3 Overview&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;day-4-teddy-goes-west-i-mean-shopping-okay-both&quot;&gt;Day 4: Teddy goes west… I mean shopping… okay both&lt;/h1&gt;

&lt;p&gt;Now it was time to go home, but hitting up the Tanger outlets on the way. But first… breakfast at the Old Mill Restaurant. About 10 pounds heavier it was time to walk it off at the outlet.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-4-shopping.png&quot; alt=&quot;Day 4 Shopping&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Tanger has some free level 2 chargers that are in great shape, and we hooked Teddy up while we shopped.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-4-shop-charge.png&quot; alt=&quot;Day 4 Charging&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This was also awesome. We shopped for quite a while; dipping in and out of shops throughout the outlets. We arrived back at a nearly fully charged Teddy. Okay, time to drive home.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-4-leg-1.png&quot; alt=&quot;Day 4 leg 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Several times on the way home I checked to see if we could make it all the way, and Teddy thought we would make it with 18% battery. We had one two step lane change, and in Teddy’s defense, it was overcast and in a curve. We also had a phantom breaking event right at an overpass shadow. I’ve had this happen a few times, and I reacted fairly quickly to fix it. However, events like these did cause my in-laws to respond in a confused and mildly-shocked manner, and that makes total sense. I mean… these events do feel super random if you aren’t driving. Ultimately, we decided to stop at the Cookeville supercharger for a break and some food. The Cookeville supercharger is also in a shopping area, but not as close to the interstate. It was easy to get to, and there was quite a bit of food nearby. We just walked to Sonic for a quick bite, and left Teddy to charge.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-4-sc.png&quot; alt=&quot;Day 4 SC&quot; /&gt;&lt;/p&gt;

&lt;p&gt;High on tater tots and electrons, we took off towards home.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-4-leg-2.png&quot; alt=&quot;Day 4 Leg 2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We had 0 bad lane changes or other random events on the way home.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://jasonamyers.github.io//assets/images/day-4-overview.png&quot; alt=&quot;Day 4 Overview&quot; /&gt;&lt;/p&gt;

&lt;h1 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h1&gt;
&lt;p&gt;This first trip was way more comfortable than I expected and I was the cause of the worry far more than the car. After the second day, I quit worrying about the car at all. Truth be told, I should have known better after reading other’s trip reviews.  However, it hard to truly grasp things until you’ve experienced them first hand. No Confirmation NoA is a game changer, and it makes every part of driving feel more comfortable on the interstate. It’s better at lane changes than ever before and if this is a sign of where the future is headed… holy cow is life about to get awesome.&lt;/p&gt;

&lt;p&gt;Charging is more natural than I expected on the road. Superchargers were at great places for us, and provided a welcome break in the trip. If you wanna “power through” it’s likely not going to make you happy, but I’m about enjoying the journey to the vacation as well. I asked our in-laws how they felt about it, and they didn’t feel it got in the way at all. They didn’t seem to be bothered and enjoyed the food breaks as well.&lt;/p&gt;

&lt;p&gt;Charging in Gatlinburg (Pigeon Forge) is pretty easy with several Level 2 and destination chargers. Gatlinburg proper has a much lighter selection of chargers, and the state park is very VERY barren when it comes to charging. Our trip won’t be your trip so you’re milage may vary.&lt;/p&gt;

&lt;p&gt;I’d love to do a trip about twice this long… and hopefully, I’ll get to soon.&lt;/p&gt;
</description>
        <pubDate>Mon, 08 Apr 2019 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2019/tesla-trip-gatlinburg/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2019/tesla-trip-gatlinburg/</guid>
        
        <category>Tesla</category>
        
        <category>Trip</category>
        
        <category>Model 3</category>
        
        
      </item>
    
      <item>
        <title>Thank you</title>
        <description>&lt;p&gt;We’ve drawn to a close on PyTN 2017, and I’ve passed the torch on to Bill to
lead it to the next level.  I wanna to share a few parting words.&lt;/p&gt;

&lt;p&gt;To Denise, thank you for being a constant blessing in my life and being so
willing to share in all my crazy ideas. I couldn’t ask for a better, more
supportive wife. Thank you for keeping me sane. I love you.&lt;/p&gt;

&lt;p&gt;To William, thanks for helping me step outside my bounds and do something no
hermit would do alone. You made this final year possible, and I’m grateful for
your friendship and kind soul.&lt;/p&gt;

&lt;p&gt;To Fernando, thank you for always lending a hand and stepping in to doing
anything we need however, simple it is. Your support has meant a lot to me.&lt;/p&gt;

&lt;p&gt;To Eric, thank you for your constant cheerleading and always stepping up to be
the first sponsor year after year. It kept me going when I needed it.
JASON MYERS IS IN DA HOOOOUUUUSSSSSSSSSSEEEEE!&lt;/p&gt;

&lt;p&gt;To Jacques and Cal, thank you for building the Nashville Community and showing
me how to put together a conference in the Nashville way. For keeping me going
when the tough moments came, and for support, guidance and advice for every
tough moment. I miss you both and your impact on our community everyday.&lt;/p&gt;

&lt;p&gt;To the PyOhio Organizers (Brian, Catherine, and crew), thank you for setting fantastic
examples for us to follow and answering our silly questions. I never got PyTN to
the level of PyOhio, but I know it’s better because we tried.&lt;/p&gt;

&lt;p&gt;To every PyTN Keynoter, thanks for making my dreams come true of seeing my heros
present. You all have truly been wonderful and delivered the messages we all
needed to hear. It’s so rare to have people you look up to turn out to be such
wonderful humans.&lt;/p&gt;

&lt;p&gt;To every PyTN Speaker, thank you for being the reason people come to the
conference. You’ve made PyTN a place of learning, growth, kind spirits and
laughter. You made the conference everything it is!&lt;/p&gt;

&lt;p&gt;To Emma, thank you for always providing space for whatever crazy community thing
we are trying this time. From PyNash to sprints to game nights you’ve always
provided a wonderful place to make that happen.&lt;/p&gt;

&lt;p&gt;To every Sponsor, thank you for support our event and believing in us when you
really had no reason too. Your kind words and support allowed world class talent
to share their awesome. That shows us your awesome.&lt;/p&gt;

&lt;p&gt;To Jessica, Thank you for leading the volunteers, and making my final year as
easy as could be. Your organization and communication skills made this year
wonderful!&lt;/p&gt;

&lt;p&gt;To all the crew and volunteers thanks for every bag of garbage, schedule check,
talk review, cup of coffee, speaker encouragement and making the magic happen.
You’re an unsung, but critical part of our event. And it is OUR event as your
actions, attitude, and service shaped it!&lt;/p&gt;

&lt;p&gt;To every PyTN Attendee, thank you for buying tickets, showing kindness, and
creating the community we have at PyTN. It has always felt comfortable to me,
and I hope it has for you. You’ve made the “hallway track” a place to ask
questions about many different things and demonstrated the powerful effect of
sharing. Your cheers and support have made every single year worth it.&lt;/p&gt;

&lt;p&gt;To Bill, I know that the rest of the PyTN community joins me in pledging our
support to you as you take the helm of the ship. You’ve been a wonderful
collaborator and confidant. I know you’ll take us to a whole new level, and set
a new standard for our event. I can’t wait to give you the standing ovation
you’ll deserve next year! Thank you for leading us forward.&lt;/p&gt;

&lt;p&gt;It has been an honor to serve!&lt;/p&gt;

&lt;p&gt;So Long Till Next Year,&lt;/p&gt;

&lt;p&gt;Jason&lt;/p&gt;

</description>
        <pubDate>Sun, 05 Feb 2017 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2017/so-long-and-thanks/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2017/so-long-and-thanks/</guid>
        
        <category>Python</category>
        
        <category>PyTN</category>
        
        
      </item>
    
      <item>
        <title>Making the Python REPL output Pretty</title>
        <description>&lt;p&gt;Recently, there was a &lt;a href=&quot;https://twitter.com/nedbat/status/817827164443840512&quot;&gt;tweet by Ned Batchelder&lt;/a&gt;
that illustrated how to make Python REPL output prettier. I went to implement it,
and wanted to put together some instructions for the future.&lt;/p&gt;

&lt;h2 id=&quot;pythonstartup&quot;&gt;PYTHONSTARTUP&lt;/h2&gt;

&lt;p&gt;The PYTHONSTARTUP referenced here is an environment variable that points to a python
file that we can place a series of command into that will be evaluated when we
launch a Python REPL. I have the following code in a file called
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.python-startup.py&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pprint&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ps1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[0;34m&amp;gt;&amp;gt;&amp;gt; &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[0m&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ps2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[1;34m... &lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\033&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;[0m&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;displayhook&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The code above will set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; to a light blue and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;...&lt;/code&gt; to a darker blue,
but this isn’t the part you are here for probably. You want the next line, which
sets the displayhook for output to pretty print.&lt;/p&gt;

&lt;p&gt;Next, you can export the PYTHONSTARTUP environment variable pointing to your
file as shown here.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;export PYTHONSTARTUP=~/.python-startup.py
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can also add this to your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.bashrc&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.zshrc&lt;/code&gt; depending on which shell you
are using, and it will always make your python repl output be pretty.&lt;/p&gt;

&lt;h2 id=&quot;so-what-is-the-difference&quot;&gt;So what is the difference?&lt;/h2&gt;

&lt;p&gt;First let’s look at the normal output:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; dessert &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'cookies'&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'chocolate chip'&lt;/span&gt;: 1, &lt;span class=&quot;s1&quot;&gt;'oatmeal raisin'&lt;/span&gt;: 12, &lt;span class=&quot;s1&quot;&gt;'peanut butter'&lt;/span&gt;: 3&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
    ...     &lt;span class=&quot;s1&quot;&gt;'cake'&lt;/span&gt;: &lt;span class=&quot;s1&quot;&gt;'OMG NO!'&lt;/span&gt;,
    ...     &lt;span class=&quot;s1&quot;&gt;'pie'&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'apple'&lt;/span&gt;: 1, &lt;span class=&quot;s1&quot;&gt;'peach'&lt;/span&gt;: 2, &lt;span class=&quot;s1&quot;&gt;'fudge'&lt;/span&gt;: 0&lt;span class=&quot;o&quot;&gt;}}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; dessert
    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'cookies'&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'chocolate chip'&lt;/span&gt;: 1, &lt;span class=&quot;s1&quot;&gt;'oatmeal raisin'&lt;/span&gt;: 12, &lt;span class=&quot;s1&quot;&gt;'peanut butter'&lt;/span&gt;: 3&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'cake'&lt;/span&gt;: &lt;span class=&quot;s1&quot;&gt;'OMG NO!'&lt;/span&gt;, &lt;span class=&quot;s1&quot;&gt;'pie'&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'apple'&lt;/span&gt;: 1, &lt;span class=&quot;s1&quot;&gt;'peach'&lt;/span&gt;: 2, &lt;span class=&quot;s1&quot;&gt;'fudge'&lt;/span&gt;: 0&lt;span class=&quot;o&quot;&gt;}}&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now let’s see it with the pretty print in place:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-shell&quot; data-lang=&quot;shell&quot;&gt;    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; dessert &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'cookies'&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'chocolate chip'&lt;/span&gt;: 1, &lt;span class=&quot;s1&quot;&gt;'oatmeal raisin'&lt;/span&gt;: 12, &lt;span class=&quot;s1&quot;&gt;'peanut butter'&lt;/span&gt;: 3&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
    ...     &lt;span class=&quot;s1&quot;&gt;'cake'&lt;/span&gt;: &lt;span class=&quot;s1&quot;&gt;'OMG NO!'&lt;/span&gt;,
    ...     &lt;span class=&quot;s1&quot;&gt;'pie'&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'apple'&lt;/span&gt;: 1, &lt;span class=&quot;s1&quot;&gt;'peach'&lt;/span&gt;: 2, &lt;span class=&quot;s1&quot;&gt;'fudge'&lt;/span&gt;: 0&lt;span class=&quot;o&quot;&gt;}}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; dessert
    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'cake'&lt;/span&gt;: &lt;span class=&quot;s1&quot;&gt;'OMG NO!'&lt;/span&gt;,
     &lt;span class=&quot;s1&quot;&gt;'cookies'&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'chocolate chip'&lt;/span&gt;: 1, &lt;span class=&quot;s1&quot;&gt;'oatmeal raisin'&lt;/span&gt;: 12, &lt;span class=&quot;s1&quot;&gt;'peanut butter'&lt;/span&gt;: 3&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
      &lt;span class=&quot;s1&quot;&gt;'pie'&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'apple'&lt;/span&gt;: 1, &lt;span class=&quot;s1&quot;&gt;'fudge'&lt;/span&gt;: 0, &lt;span class=&quot;s1&quot;&gt;'peach'&lt;/span&gt;: 2&lt;span class=&quot;o&quot;&gt;}}&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If your are curious what the colors look like:
&lt;img src=&quot;http://jasonamyers.github.io//assets/python-prompt-example.png&quot; alt=&quot;Output Preview&quot; /&gt;&lt;/p&gt;
</description>
        <pubDate>Sat, 07 Jan 2017 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2017/default-to-pprint-python-repl/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2017/default-to-pprint-python-repl/</guid>
        
        <category>Python</category>
        
        <category>REPL</category>
        
        
      </item>
    
      <item>
        <title>Parallelizing Queries with SQLAlchemy, Gevent, and PostgreSQL</title>
        <description>&lt;p&gt;Recently, we had a need to execute multiple SQLAlchemy queries in a parallel fashion against a PostgreSQL database with Python 2 and &lt;a href=&quot;http://initd.org/psycopg/&quot;&gt;psycopg2&lt;/a&gt;. We didn’t really need a full scale multithreading approach, so we turned to &lt;a href=&quot;http://www.gevent.org/index.html&quot;&gt;gevent&lt;/a&gt;. Gevent is a implementation of &lt;a href=&quot;https://en.m.wikipedia.org/wiki/Green_threads&quot;&gt;green threading&lt;/a&gt; that uses libevent. This post really isn’t about what threading model is better, as that is great subjective and changes based on your use case and needs.&lt;/p&gt;

&lt;h2 id=&quot;making-psycopg2-coroutine-friendly&quot;&gt;Making Psycopg2 Coroutine Friendly&lt;/h2&gt;

&lt;p&gt;So the first thing we need to do to prepare to leverage gevent is make sure psycopg2 is configured properly.  Because the main psycopg2 is a C extension, we can not just take advantage of gevent’s monkey patching. Nonetheless, psycopg2 exposes a &lt;a href=&quot;http://initd.org/psycopg/docs/extensions.html#psycopg2.extensions.set_wait_callback&quot;&gt;hook&lt;/a&gt; that can be use with coroutine libraries to integrate with the event scheduler. There are a few libraries to help with this such as &lt;a href=&quot;https://pypi.python.org/pypi/sqlalchemy-gevent&quot;&gt;sqlalchemy_gevent&lt;/a&gt; or &lt;a href=&quot;https://bitbucket.org/dvarrazzo/psycogreen&quot;&gt;psycogreen&lt;/a&gt; that you can use to automatically set this part up for you. However, the code is fairly short and straight forward. Let’s look at the code from psycogreen, that I use in my applications.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;psycopg2&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;psycopg2&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extensions&lt;/span&gt;

    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gevent.socket&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait_write&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;make_psycopg_green&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;Configure Psycopg to be used with gevent in non-blocking way.&quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hasattr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'set_wait_callback'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;&quot;support for coroutines not available in this Psycopg version (%s)&quot;&lt;/span&gt;
                &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;psycopg2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__version__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_wait_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gevent_wait_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gevent_wait_callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;&quot;&quot;&quot;A wait callback useful to allow gevent to work with Psycopg.&quot;&quot;&quot;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;poll&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;POLL_OK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;POLL_READ&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;wait_read&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;elif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;extensions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;POLL_WRITE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;wait_write&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fileno&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;timeout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;psycopg2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OperationalError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                    &lt;span class=&quot;s&quot;&gt;&quot;Bad result from poll: %r&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The code above will block the calling thread with a callback if we are busy reading or writing, which will return control back to the event loop that could start working on another thread if one needs to be worked on. The wait_read function blocks the current green let until the connection is ready to read from, and the wait_write does the same thing for writing to the connection.&lt;/p&gt;

&lt;p&gt;With psycopg2 ready to work with gevent, we can start writing the code to execute our queries. I’m going to use a few different elements from gevent to control how the queries are executed, how many queries can be run at once, and how the query results are handled.  There are many ways to use gevent and workers to accomplish this tasks, and some are quite simpler. My structure is set for future options and growth. I call this structure a QueryPool.&lt;/p&gt;

&lt;h2 id=&quot;building-our-gevent-based-querypool&quot;&gt;Building our Gevent based QueryPool&lt;/h2&gt;
&lt;p&gt;The QueryPool consists of an input queue to hold the queries we want to run, an output queue to hold the results,  an overseer to load up the input queue, workers to actually get the queries and run them, and finally a function to drive the process.&lt;/p&gt;

&lt;p&gt;The central element of our QueryPool, is the input queue. It is a special kind of FIFO queue called a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;JoinableQueue&lt;/code&gt;, which has a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.join()&lt;/code&gt; method that blocks until all items in the queue have been acknowledged as processed with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task_done()&lt;/code&gt;. The input queue is loaded by an overseer as the first step of running the QueryPool. Then workers grab tasks one at a time from the input queue and when they finish their work they use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;task_done()&lt;/code&gt; method to inform the queue that the item has been processed.&lt;/p&gt;

&lt;p&gt;Let’s look at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__init__()&lt;/code&gt; for our Query pool:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gevent&lt;/span&gt;
    &lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;gevent.queue&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JoinableQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Queue&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;QueryPool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool_size&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;queries&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;queries&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;POOL_MAX&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pool_size&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JoinableQueue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_queue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So in our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__init__()&lt;/code&gt; method, we start by storing the queries. Next we set a POOL_MAX which is maximum number of workers we are going to use. This controls how many queries can be executed in parallel in our QueryPool. Then we setup the tasks queue, which is where are workers will pick up work from. Finally we setup the output queue that workers will publish the query results.&lt;/p&gt;

&lt;h3 id=&quot;defining-worker-methods&quot;&gt;Defining worker methods&lt;/h3&gt;
&lt;p&gt;Now we can look at the workers, I use two methods in the QueryPool calls. The first one contains the logic to prepare a database connection and execute the SQLAlchemy query.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;engine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchall&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For the workers method within the QueryPool class, we start a loop that is going to run until their are not tasks left in the tasks (input) queue. It will get one task, call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;__query()&lt;/code&gt; method with the details from the task, handle any exceptions, add the results to the output queue, and then mark the task as done. When adding the results to the output queue, we use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;put&lt;/code&gt; method of gevent queues to add the results without blocking. This allows the event loop to look for the next thing to work on.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;executor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output_queue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exc_info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exc_info&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Query failed :('&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;task_done&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;building-an-overseer-method&quot;&gt;Building an overseer method&lt;/h3&gt;
&lt;p&gt;Now that we have a something to handle the work, we need to load the task (input) queue. I use an overseer method that iterates over the supplied recipes and puts them on the task (input) queue.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;overseer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;query&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;queries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;building-the-run-method&quot;&gt;Building the run method&lt;/h3&gt;

&lt;p&gt;Finally, we are ready to build the run method that ties everything together and makes it work. Let’s look at the code first and then cover it step by step.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;running&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;gevent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spawn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;overseer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;POOL_MAX&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;runner&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gevent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spawn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;executor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;runner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;running&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;runner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tasks&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;runner&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;running&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;runner&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;kill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
      &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The runner first spawn the overseer and immediately calls join on it, which blocks until the overseer is done loading items into the tasks (input) queue. This is overkill, but provides more options and would allow up to load asynchronously in the future. Next, we start a number of workers up to the POOL_MAX we defined earlier, and add them to a list so we can control them later. When we start them, they immediately begin working. Then we call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.join()&lt;/code&gt; on the tasks (input) queue which will block execution until all the queries in the queue has been execute and acknowledge as completed. Finally, we clean up by using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.kill()&lt;/code&gt; method on all of the workers.&lt;/p&gt;

&lt;h2 id=&quot;using-the-querypool&quot;&gt;Using the QueryPool&lt;/h2&gt;

&lt;p&gt;Now we are ready to use our QueryPool class! I’ve created an Jupyter notebook available on &lt;a href=&quot;https://github.com/jasonamyers/gevent-sqlalchemy/blob/master/Gevent%20SQLAlchemy.ipynb&quot;&gt;GitHub&lt;/a&gt; with some example queries against a benchmarking database. I created my test database using the pgbench command to create a 5Gb database.&lt;/p&gt;

&lt;h3 id=&quot;execution-results&quot;&gt;Execution Results&lt;/h3&gt;

&lt;p&gt;I setup 6 queries of varying complexity and execution time. I then executed those queries in a traditional serial execution style and then with our QueryPool using different worker counts.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Serial: 24 seconds&lt;/li&gt;
  &lt;li&gt;QueryPool - 5 workers: 8 seconds&lt;/li&gt;
  &lt;li&gt;QueryPool - 3 workers: 9 seconds&lt;/li&gt;
  &lt;li&gt;QueryPool - 2 workers: 15 seconds&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;history&quot;&gt;History&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;2016-04-28 Added missing return thanks to Mike B.&lt;/li&gt;
  &lt;li&gt;2016-04-29 Updated information about &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.put()&lt;/code&gt; method based on feedback from David S.&lt;/li&gt;
  &lt;li&gt;2016-04-30 Updated while 1 to while True based on feedback from /u/Asdayasman&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 28 Apr 2016 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2016/gevent-postgres-sqlalchemy/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2016/gevent-postgres-sqlalchemy/</guid>
        
        <category>SQLAlchemy</category>
        
        <category>Postgresql</category>
        
        <category>Postgres</category>
        
        <category>Gevent</category>
        
        
      </item>
    
      <item>
        <title>Python 2.X ImportError with PyEnv</title>
        <description>&lt;p&gt;If you use &lt;a href=&quot;https://github.com/yyuu/pyenv/&quot;&gt;pyenv&lt;/a&gt;, and have installed or updated Pyenv and built Python 2.x after Feb 17 or rolled your own Python 2.x by hand, you may experience an issue where some packages will fail to run with an error message like the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Traceback (most recent call last):

File &quot;/Users/jasonmyers/.virtualenvs/test2/bin/jupyter-notebook&quot;, line 7, in 
from notebook.notebookapp import main
File &quot;/Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/notebook/
notebookapp.py&quot;, line 32, in 
from zmq.eventloop import ioloop
File &quot;/Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/zmq/
__init__.py&quot;, line 66, in 
from zmq import backend
File &quot;/Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/zmq/backend/
__init__.py&quot;, line 40, in 
reraise(*exc_info)
File &quot;/Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/zmq/backend/
__init__.py&quot;, line 27, in 
_ns = select_backend(first)
File &quot;/Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/zmq/backend/
select.py&quot;, line 27, in select_backend
mod = __import__(name, fromlist=public_api)
File &quot;/Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/zmq/backend/cython/
__init__.py&quot;, line 6, in 
from . import (constants, error, message, context,
ImportError: dlopen(/Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/zmq/
backend/cython/constants.so, 2): Symbol not found: _PyUnicodeUCS2_DecodeUTF8
Referenced from: /Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/zmq/backend/
cython/constants.so
Expected in: flat namespace
in /Users/jasonmyers/.virtualenvs/test2/lib/python2.7/site-packages/zmq/backend/cython/constants.so
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is due to the fact that recently python wheel packages switched to “wide” unicode (ucs4) via &lt;a href=&quot;https://www.python.org/dev/peps/pep-0513/&quot;&gt;PEP-513&lt;/a&gt;. Since not all of the wheel packages have been updated, you can end up with package that use “narrow” unicode (ucs2). I’ve seen this in jupyter, ipython, Pillow, and other Python packages. To fix this you need to install the packages without using the wheels until they release an update. For example: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install --no-use-wheel jupyter&lt;/code&gt; 
This will take much longer to do the install; however, jupyter will work properly after being installed this way. More details at &lt;a href=&quot;https://github.com/yyuu/pyenv/issues/257&quot;&gt;https://github.com/yyuu/pyenv/issues/257&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Mon, 04 Apr 2016 00:00:00 +0000</pubDate>
        <link>http://jasonamyers.github.io//2016/pyenv-importerror-flatnamespace/</link>
        <guid isPermaLink="true">http://jasonamyers.github.io//2016/pyenv-importerror-flatnamespace/</guid>
        
        <category>pyenv</category>
        
        <category>error</category>
        
        
      </item>
    
  </channel>
</rss>
