 Okay, welcome to our talk, good luck with that. Tag teaming civic data. I'm Liz Rush. And I'm Sing Wei Su, and we're both recent graduates of the first cohort of Ada Developers Academy. We wanna share the story of our year-long road to becoming real developers, and some of the lessons that we learned along the way. Presented through the lens of a case study of our ongoing project, we'll show you how we learn how to get unstuck from common problems new developers make. And throughout the talk, we'll present seven takeaways that we came up with over the course of this project. So for the senior devs in the room, we think you'll recognize the experiences we had and the lessons we learned. And for the less experienced here today, we hope that you will walk away from this talk with more tools to help you bridge the gap from beginner to professional developer. So a bit about ourselves. I graduated college with a degree in clarinet performance, and also French by accident. This allowed me to work in France, which was really just a way to fund my ultimate Frisbee habit. And this proved to be such a successful strategy that I went on to learn a few other languages. And at that point, talking to computers is probably even more interesting than talking to humans. So I decided to go into programming. And I also have a language background. Before learning to code, I worked in digital marketing and then moved into technical and legal translation. Eventually, I found my way to translating apps and got myself roped into manual regression testing. After beginning to automate some of those tests and seeing the parallels between translation and code, I decided to pursue programming. Luckily for both of us, a new unproven experimental program called Ada Developers Academy was just beginning to take shape, so we decided to jump in. For those of you who haven't heard of Ada before, it's a nonprofit tuition-free code school in Seattle focusing on training women making career shifts into tech. The program is industry-driven with professionals, companies, and community members all contributing to the open source curriculum. It focuses on web development using Ruby on Rails, as well as general software engineering principles such as software architecture, test-driven development, and agile. The program's a year long, separated into two six-month phases. The first six months consists of in-class instruction. And the second six months is spent in an internship with a local tech company in Seattle. Our six-month classroom experience started with one month of learning pure Ruby, followed by Rails projects in short one to two weeks sprints that we completed in pairs or in teams of four. The classroom portion culminated in a final four-week-long self-directed capstone project. Singh Wei and I had previously worked together on a two-week Rails app, and that's when we discovered where our individual interests and strengths lie. Yeah, Liz likes front-end JavaScript frameworks, UX, and mobile, whereas I'm one client towards databases, APIs, and back-end work, and we both really enjoy the challenge of architecting a project together. So we decided to pair on our capstone, which was an app that would make use of the City of Seattle's Open Data Initiative to provide users with a way to discover street parking restrictions in their area. So our project is very much an example of the scratch your own itch principle. About three months before even beginning to think about capstone projects, I had borrowed my brother's car and needed to park it near my apartment. Not only did it take me 20 minutes of prowling just to find a spot, but once I did, I got out of the car and found the nearest pole with parking signs. Then I realized there were multiple different and conflicting rules, and I was left more confused than before. We're both car-free cyclists, but we knew intuitively that this was a problem that would need solving for more than just ourselves. Parking in Seattle is polemic, but everybody agrees that the parking signs themselves are basically gibberish. So here's a particularly egregious example. It appears as if every sign contradicts the one before it, and as a final cruel joke, they tacked on west of here. When the direction this photo was taken, we're all east of all of these signs. So where does that leave us? We had been granted a week of free play in Eda before the capstone started, which I spent doing research. Simply enough, I just Googled to find out if somebody had solved the problem for me. And while there were no mobile apps, it turns out the city of Seattle in fact had a parking restrictions map on their website. I investigated the different data sets available through the city's open data initiative and SOCRADA portal, and I also managed to get a contact at the city of Seattle, not in their parking or transportation department, but an engineer on their web team. So this is the way that the city of Seattle government implements the map showing parking information. They use ping overlays on map tiles to show the different parking categories. As you can see, it's a bit hard to read. The categories aren't really very clear and the data is static. We thought we could do better. Our idea was to use the data to display parking information in a simpler, more human friendly way. So for example, rendering just green lines for available street parking and red lines for no parking. So we were pretty excited. There was open data available. We had a contact in the city and we had a starting point to improve on. As newbies to programming, we had picked up on the trick that sometimes the key to solving a difficult problem was knowing that a solution was possible, or at least deluding yourself into that belief. More out was pretty high, but knowing that this would acquire some help from the city of Seattle government, we called our contact. We explained our idea, what we thought we could do, hoping to get some feedbacks or tips as we embarked on the journey. And he said, well, if you think you can build it, you'll be the first. Good luck with that. Ha, ha, ha, ha. Ha, ha, ha. And then he hung up on us. Yeah, seriously. So yeah, in spite of this ringing endorsement, the guy did provide us with a link to their ArcGIS server, which is what their web application was using to generate the parking maps. Though we had never used an ArcGIS server before, the Esri website told us all about the different tools that ArcGIS provided, including a way to dynamically generate KML files that we needed for our project. So this is perfect, except... It turns out that our perfect resource wasn't so perfect after all. As you can see, there were quite a few implementation problems. Almost every informational link was a four of four, and many of the links produced empty files from which we couldn't extract any data. So at this point, not really knowing what we were doing, we reached out to other developers on Twitter and actually got back a link to a fully implemented demo ArcGIS server from a developer at Esri. We found that there was actually a lot more to an ArcGIS server than what the city had, including projection tools and coordinate conversions. Since we didn't appear to have this on the Seattle Map server, we called up our contact again, who told us that the person who originally implemented the product was no longer working there. They had no idea what was going on with the Map server, and they'd be unable to provide us with any help or guidance. So as we mentioned, the city was using ping overlays, but in order to implement the features that we wanted, we decided to use KML files or keyhole markup language files, which are an XML type formatting for geo data that's used by applications like Google Earth. A KML file contains information that's tied to latitude and longitude and allows you to render shapes, place markers, or lines with different colors and textures to show, for example, the topography of region, points of interest, or in our case, lines with associated parking data that corresponded to block faces on a city street map. Fortunately, ArcGIS servers include an API endpoint that returns these KML files, but when we tried to hit that endpoint on the Seattle's city's Map server, we got back a KML file that rendered like this. So at this point, with no luck getting the KML files from the Map server and two weeks into the four weeks that we had for our project, we were starting to get worried that we wouldn't finish in time. So we compromised on our original idea and decided to use ping overlays instead to get a minimum viable product. We thought that this would be much easier to implement since that was actually the strategy that the Seattle government, that used by the Seattle government. So here's a ping overlay that we managed to generate from the Map server. We were working on this project from downtown Seattle. So after a little bit of struggle to figure out the query parameters, we were excited to see the successful generation of the ping. We forged ahead for the next week, building out our backend and figuring out what to do with all of these overlays when eventually we discovered that the graceful fail looked suspiciously like the success. So faced with this problem, we decided to snoop around the city government's code to see how they handled this issue. And the answer was they didn't. As you can see, they simply put a comment in the else block that says, we didn't get any parking results. So let's just not do anything at all. And here's my favorite comment. What do here? To do. And we realized this is silly and we're not trying to tear down the city's code. But at this stage of our project, after so much frustration, it was actually sort of comforting and validating to realize that even real developers don't always know what they're doing. And one last gem. This caused great grief. Oh, JavaScript. So we eventually forgot to the point where we were getting to the correct map that corresponded to our bounding box queries and we decided to use the Google Maps API as a base layer. However, we ran into the problem of the overlay not lining up with the map. And this was pretty perplexing. We were working under the assumption that whatever Google was using to display their maps, everyone else on the internet must be using it too, right? Turns out there are many different kinds of map projections and different regions often use different systems. We ended up on a choose your own adventure sort of trail researching different kinds of projections and spheroids and learned that many civic map servers actually use flat map projections which are accurate locally but become increasingly inaccurate the further way you get from a central reference point. The Seattle government, for example, sourced their geo information using a flat map projection specific to the Washington North State Plain, whereas the Google Maps API displays their maps using a spherical Mercator projection more suited for global geo data. So basically this meant that we were trying to lay a flat map on top of a round map and we lost a lot of time trying to figure out how these various projections were actually being used. We did find a website that cataloged all the different projections for every region in the world and index them by a spatial reference ID. But even when we got the correct spatial reference ID for the Washington State Plain, we couldn't figure out how to actually use it and solve the skewing when actually querying the map server. After beating our heads against a wall we figured out the solution. By accident. I had just happened to be messing around with the spatial reference codes and one afternoon I typed the wrong number into the right box and somehow we ended up getting exactly what we wanted. But this is despite it being the opposite of what every other example on the internet of a similar query was. So now that we were getting the correct ping files we had to figure out a way to store them. Since we were anticipating building out both a front end web client and an iOS app we didn't want to overload the city's map server with requests. So we decided to separate our project into two separate Rails apps. A backend API that would actually make the request and cache the data from the city which would then serve a front end web client. This forced us to think about optimizing performance and caching requests with the same parameters as previous ones. So for example, we used the carrier wave gem to cache the ping files we were grabbing from the city map server and putting them in an Amazon S3 bucket. But since carrier wave was taking around 14 to 15 seconds to complete the actual upload we set that as a background job and in the meantime sent the client a temp file. That way the client would be able to see the map overlay immediately but then any other request made with the same bounding box parameters would receive the cache file from the cloud. So at this point it's the end of April we've just wrapped up the classroom portion of ADA six months down and only six months to go and we've reached the chimney rock of our journey to becoming developers. Yay. And here's what we came up with for our minimum viable product to show off on our presentation day. As you can see we're using the same ping overlays that the city was using but we made our client mobile responsive and all of the important information that tells you what each of these lines means can be found in touch responsive JavaScript tooltips on the side of the legend. Even though these are small improvements we found that they made the data more accessible to the average user especially since there are explanations of what the categories actually mean. We've even heard back from users that this version has helped them navigate parking in Seattle already. So because we were constrained by our classroom deadline we had to cut features and scale back once we hit unexpected roadblocks. Having the hard deadline helped us scope our work to focusing on building a usable product even if it didn't fulfill everything that we wanted in the app. However this brings us to a common struggle that we've seen in ourselves and in our peers which is that we get so caught up in wanting to build all the things and wanting to perfect our work that we fail to follow the strategies of MVP building after our official capstone was said and done. We decided to continue on this project together with the goal of getting the app in the app store and adding more features but as we transitioned into internships and left the structure of ADA we lost sight of this MVP strategy. We started to think about how to completely revamp the project and all of the millions of features we wanted to add before we felt it would be ready. What actually happened is that we floundered under the weight of all of the work and we made very little progress on anything. Yeah in fact after we started presenting our progress on the project someone submitted a copycat of our iOS MVP to the app store because they stuck to the MVP principle they beat us to it and we lost out on being first to market. Lesson learned don't forget to incrementally build out your project. Building the perfect half of a project isn't as valuable as building as an imperfect whole. So as we wrapped up this MVP and started the transition from students to real developers one thing we found extremely beneficial not just to us as individuals but to the project as a whole was mentorship. We were lucky to have a fantastic iOS contract developer who was extremely enthusiastic about our project. Her brother. Yeah my brother John Rush who we paid solely in donuts and coffee in exchange for his computer science knowledge and experience developing and planning iOS apps. Because we knew that this product is really a mobile product we came into it knowing that we would have this large blind spot when it came to iOS development. John was there to guide us while still letting us decide the direction of the product as well as the design and user experience of the iOS app. Additionally I had two mentors from my internship company Mark and Robin who were mentoring me during the time of the capstone and who remained my mentors for a time during the internship. Having the continuity of mentorship over the course of a larger project turned out to be incredibly valuable. We had experienced developers to whom we could ask questions like how do we use MongoDB but they were also there to put our setbacks in perspective and give us real constructive criticism. Instead of a one-off question that you might ask on say Twitter we had these valuable resources who not only knew what our current skill level was but knew the whole history of the project and how to help push us in the right direction while maintaining distance from the actual code. We believe the support from mentors helped keep us motivated to pursue the project after ADA. So John became our long-term mentor who has seen the project grow from a seed of an idea into our first MVP and also helping us build our first iOS app. He was the mentor who knew our code base taught us about iOS development and could help us troubleshoot our backend but other mentors were also a great resource for guidance and support and providing big picture perspectives into software and product development. So if you don't have a friend or sibling that you can trick into working on your project try reaching out in your local meetup groups or on Twitter to find a developer that will guide you. Find the developers who would love to help beginners and juniors. They are out there in the community. We even suspect that there are several in this room right now. So back to the MVP. We presented this app in front of our ADA sponsors, mentors and future bosses at our internships as well as friends and family. Additionally, we were also invited to present along with two other students who did civic data related projects at a local meetup for civic technology enthusiasts. Unfortunately, we actually didn't have a great experience. While most people responded positively we did get a bit of discouragement from spectators who wanted to tell us about every single thing that we were doing wrong. We also presented at a local Ruby meetup where someone actually tried to break our app in the middle of our presentation, which on the one hand, rude, but on the other hand, it was as if we were being viewed as an equal to this professional developer. It felt like we were in this awkward transition between beginner and junior dev and we were trying to figure out the balance. Another example, one of my coworkers who was trying to learn how to be a good mentor came to a presentation we gave at another meetup and his first response was that was better than I expected. And while this wasn't meant to be malicious, it was an example of how even well-intentioned folks in the community don't always know how to interact with and support us. Oftentimes we ended up being ambassadors of alternative learning paradigms and programs like ADA, but as we tried to find our place in the dev community we had to figure out how to help other people learn how to help us. Through these experiences, we discovered what we believe is a hard lesson for developers. Coda's actually a really small part of what makes development difficult. We had to start to figure out what we wanted our product to look like, what we thought success would look like, how to integrate ourselves into the community and how to work together without a hierarchy. Part of this involves scheduling actual work days to meet and work face-to-face, using Pivotal Tracker to ensure that we were making progress, and the most important lesson of all, don't code when you're hangry. We've learned this the hard way, as you can see in this action shot of me in the same way. So now with Liz firmly established as well my boss and also equipped at the mentality that we might actually be becoming real developers, we wanted to continue phase two of our app following our original idea of manipulating the lines on the actual overlay. We finally found a KML file that contained data for the entire city on the OpenData website and managed to parse it, only to discover that the first rule of parsing KML is pretty much the same as the first rule of parsing XML, which is don't. But we tried anyway, only to discover that it didn't contain all the data that we needed. When we then discovered that there was a different file that did contain all the information that we needed, and these were shapefiles, which are another S3 tool that stores geodata in a digital vector storage format. I don't actually know what that means either, but it isn't human readable and requires some third-party library to decipher. We tried asking around for which gems would be best suited for the job, but the open-source gems, in particular, RGO and Geovruby weren't really sufficient. And while there was a gem being developed by S3, it apparently wasn't ready for release. We found this to be a very frustrating point in the project. We were trying everything we could think of, and it was like throwing spaghetti at the wall and nothing sticking. No one really tells you this as a beginner, but the feeling of spending a million years just trying to get something to work or figure it out, that's always there. Only experienced developers call it spiking. So we exhausted all these ideas, spiking on each one of them until we reached dead ends until we finally found a solution. And it was... Python. Ooh. Woo-hoo. Turns out that Python libraries are really good at math and handled both reading the shapefile and converting the data to the correct projection. Although we wanted to keep our back-end API a Rails app, we thought we could make this work and integrate a Python script as a separate cron job on the server and feed the shapefile data to Rails. SingWay was in an internship working in Python every day, so having this other language to compare to ended up being very valuable. We couldn't find good gems or libraries for what we wanted to do in Ruby, so we started to question if Ruby was even the right tool. This is a lesson that's especially hard for beginners. I mean, you can't know what you don't know, so how do you know if what you know is the right thing to know, you know? This is especially true when you've only begun learning and you only have one tool. You know that idiom, when all you have is a hammer, every problem starts to look like a nail? Well, it can be worth your time to question if you are even using the right tool to get the job done. So in our case, realizing that Python was the better tool for handling shapefile parsing and coordinate conversions, we figured we'd swap out part of our back-end to use that Python script, but turns out the data was bad anyway. We were told that the data from the city was being maintained and updated every day from our contact, but on the open data website, it turns out the last time it was actually updated was in 2011. So, so much for that idea. We decided to go back to the ArcGIS map server. That's right. This guy. So in order to connect the public data to the city's map server, we used some of the information about the geometry objects provided in a CSV on the open data website, such as the unit ID number to actually query the ArcGIS server directly. As Singhway mentioned, we're implementing the solution that uses both the open data and the map server on the government site. This means that even though we started our project trying to architect a way to play nice with the city's server, now we're going to have to get the most up-to-date data by querying until we hit the result limit. This means that we're potentially going to have to hit their server 2,300 times to ensure that we have the newest data for every part of the city. But it should totally work, you know, in theory. So here's a demo of our MVP iOS app in its current state. Oh, is that going? Yeah, okay, it's not going over here. So as you can see, it's just a very simple iOS app using MapKit. The lines have been simplified to be red, yellow, and green. Red obviously means no parking. Green means you can park there. And yellow means that you might have to pay or there are other restrictions that you have to keep in mind. We've also built in filters so that you can adjust your query as you're searching. If you need to park for a longer period of time, you can adjust that, or you can adjust the amount that you're willing to pay. And as you can see, the lines are dynamically updated to reflect your query. We've also added in a feature like a profile system so you can put in default preferences for your filters as well as residential parking permits. So if you live in an area where parking is restricted by having a permit, those lines might appear red to some people, but if you add in your permit, those will turn green for you. We've also added in some other features like a favoriting system so that you can store some of the data locally for quick reference. Or if you're one of those people that can never remember where you parked your car, you can favorite your location and then go back to it easily. So the next step in this app is to kind of wrap up the code in its current state, clean it up and submit it to the app store. We're going to try to do this as soon as possible so we can start getting user feedback. And then over the course of the next few months, we're planning to move over to Swift and move our web client over to Ember to mimic the same type of dynamically updated line rendering for the parking data. So that was the state of our project before presenting at Cascadia Ruby this past August. We decided to take some time off after that because, well, we're pretty burnt out. We're totally sick of parking. And our internships are proving to be pretty challenging. We needed to focus on making it through ADA and preparing for job interviews. This lesson was hard, but we learned that sometimes you have to de-prioritize your side project. Burnout will kill your project before you even realize it. So when you hit milestones like your first conference talk or deploying a new feature, be sure to celebrate your victories, no matter how small. Time off to remember what your goals are and to step back to reevaluate your plan of action are more valuable than 100 hours of half-hearted coding. Plus, it gives you time to revitalize and remember that the person you're working with is hopefully your friend. So even with only a few months of training and having never programmed before starting ADA, writing code was never actually the hardest part. It was working with data that we couldn't control and which had little or no documentation that were the biggest challenges. Not only that, but it became increasingly clear that there's never one straight path to a solution in spite of how simple an idea might seem like from the get-go. Which is how I fooled her into working on this, but I got her back into tricking into giving this talk. So basically we didn't know what we were getting ourselves into and no one else did either. Because of this ambiguity, we had to redefine what success meant to us. Part of this learning process involved the discovery that if you wanna build something new, sometimes it's not as simple as just clicking on the first stack overflow result that comes up. So while this is frustrating, it was also an empowering experience to see that other so-called real developers with real jobs don't always know what they're doing. And now technically, where are those real developers with real jobs who don't always know what we're doing? So originally we wanted to make an app that transformed the way the open data was currently being used. This meant something interactive, human friendly, and mobile. However, we ended up having to settle for an MVP that wasn't exactly what we envisioned due to the deadline of the four week capstone. Which isn't to say that our MVP wasn't something to be proud of, but on the contrary, it was a little bit terrifying that after just five months of learning to code, we could not only build something like this, but we could see a vision and a path to an even better product. Also it was pretty awesome that even though we were so new to coding in the tech scene, we had a great community in Seattle that was willing to support us and help us try to build this. That being said, despite the sometimes awkward or inconsiderate feedback that we got, we did learn quite a bit from presenting our app. It helped us learn how to carve our place out as a newcomer to the tech scene, as well as field some difficult questions that ultimately helped us mature as developers. We learned what features excited the audience the most and heard other citizen stories of parking nightmares. Getting confirmation that we were on the right track, at least in terms of product development, was a big boost to our morale. It's pretty easy as a new developer to get lost when working on a self-directed project. And when we shared our progress, we got to hear from other developers who had worked on similar problems or tried using similar tools. Other people came up to us to share their frustrations and this helped us to know that when a tool didn't work, sometimes it was just that the tool was broken. So for all developers out there, remember, giving presentations and sharing your progress and work with other developers is one of the best ways to get feedback and prevent the feeling that you're never gonna see the end of your project. You'll be able to course correct sooner and check your assumptions faster than if you wait until your project is done. It's never going to be done, so you might as well start sharing it now. And when we spent hours and hours on code that we didn't end up using, we also realized that investigating potential solutions and figuring out why they may not work was just as productive as, could also be counted as a win and could be just as productive as checking in production code. This was actually a really hard lesson to learn. The fact that all of us in ADA were making a sharp turn in a career to go into tech made us feel like we had to play catch up to where other junior developers with maybe more traditional computer science backgrounds were. So anytime we ended up writing code that wasn't used or ended up being the wrong approach, it seemed like we were wasting our time or taking steps backwards somehow. But persisting through even when all roads seemed to lead to a dead end really deep in our mental and emotional stamina and gave us a better idea of how real life code actually evolves. So when first learning how to program, sometimes knowing that a solution existed or that it was possible to solve a problem was enough to get unblocked. When we started on this project, we knew that there was a working version of a parking website that used open data. So we started off pretty optimistic but then quickly ran into obstacles. So for the time when the project was still just a capstone, as we kept getting stuck on different problems, we felt like we were under this slight stress that perhaps we had coded ourselves into a corner or that there really wasn't a way to make this data more accessible. We had this nagging feeling that perhaps if it could be done, somebody would have already done it, right? But actually we found that that wasn't true. Throughout the project, we encountered more and more hurdles with each one seemingly bigger than the last. And we started to think that maybe our goals weren't actually achievable. But as we talked to more and more people, we found that this was actually a pretty common, even normal feeling, and that most developers experienced the same frustrations day to day. So rather than thinking that the best indication for success was knowing that a solution was possible, we came to believe that we still had a chance because no one had yet proved our project to be impossible. Our original fear of impossibility morphed into a belief that it could be done and that even beginners and junior developers are the people to tackle these difficult problems. So before we open this up to questions, we wanted to give some shout-outs to the people who helped get us here today. When we submitted this talk, we were still interns, so we needed, we had a crowdfunding campaign to help get us here. So special thanks to all of our fabulous friends, peers, and community members who contributed. And an extra big thanks to the corporate sponsors who significantly contributed to our travel cost today. So once again, I'm Shing Weisoo. And I'm Liz Rush, and we hope you enjoyed our talk. Thank you for coming.