<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kim Diep</title>
    <description>The latest articles on DEV Community by Kim Diep (@thekimmykola).</description>
    <link>https://dev.to/thekimmykola</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F173584%2F46332a2e-d55f-4dc1-a0f8-4f72518058f5.jpg</url>
      <title>DEV Community: Kim Diep</title>
      <link>https://dev.to/thekimmykola</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thekimmykola"/>
    <language>en</language>
    <item>
      <title>Don’t Forget ‘You’! Top Tips on Self-Advocacy &amp; Guide to Nominating Yourself &amp; Others for an Award</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Mon, 08 Aug 2022 07:42:52 +0000</pubDate>
      <link>https://dev.to/thekimmykola/dont-forget-you-top-tips-on-self-advocacy-guide-to-nominating-yourself-others-for-an-award-8pg</link>
      <guid>https://dev.to/thekimmykola/dont-forget-you-top-tips-on-self-advocacy-guide-to-nominating-yourself-others-for-an-award-8pg</guid>
      <description>&lt;p&gt;&lt;strong&gt;This post was originally written for &lt;a href="https://www.curiouslycode.com/being-human/career-advice/dont-hestitate-to-put-forward-yourself-forward-for-an-award"&gt;Curiously Code&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  My not-so secret ‘secret’
&lt;/h3&gt;

&lt;p&gt;I’ll let you into a not-so secret ‘secret’. Out of the 5 awards I have received from the tech community since I made my career switch into the technology industry, one of those awards, more specifically, the 2022 FDM EveryWoman in Technology awards, I actually submitted a nomination for myself.&lt;/p&gt;

&lt;p&gt;It was the first time I supported myself through something like this and even to this day, I still feel a bit weird about it, but I hope that by putting my thoughts down on a blog post, I can encourage you to be kinder to yourself and be your own advocate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Awards, accolades and job titles aren’t everything…
&lt;/h3&gt;

&lt;p&gt;First of all, I just wanted to open this post by saying that if you put the main goal of your career success solely on winning awards, achieving certifications, accolades or fancy job titles, you will find that this is simply not enough.&lt;/p&gt;

&lt;p&gt;This is not to say that these things are bad, they’re pretty good stuff and opens up so many opportunities. Awards help to amplify the things that you’re doing and encourages others too! The keyword here is ‘amplify’. This suggests that there is already something that you’re doing that is unique to you and even without the awards, you feel very content with what you have, as what you have is everything.&lt;/p&gt;

&lt;p&gt;At the end of the day, people will remember you as the person that helped them, brought them joy, made an impact and left a legacy. Sometimes as human beings, we always seek more, but we often forget to look back at how far we have come and what we have already to appreciate the journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don’t Forget ‘You’! Kim’s Top Tips on Self-Advocacy
&lt;/h3&gt;

&lt;p&gt;For those who know me personally, I’m still growing and trying to speak to myself more positively. I put a lot of pressure on myself to succeed quickly and that’s a pretty vicious cycle. I don’t naturally like to draw attention to myself and would just prefer to blend into the crowd. This means that if I have done a good job of a task and people say ‘well done, good job’, I would just say something like ‘hey, thank you, but yeah it was no biggie anyways’ or ‘thanks, yeah, I guess you could say it’s good, but I did receive some help’. I hope you can relate to this tendency to wash down achievements somewhat for fear of standing out.&lt;/p&gt;

&lt;p&gt;Here’s the thing though, if we invert this logic, it doesn’t make sense because unless you speak something out into existence, not many people would notice.&lt;/p&gt;

&lt;p&gt;I’m naturally a heads down and get stuck in sort of person, but I realised how important it is to take a step back and advocate for myself that bit more!&lt;/p&gt;

&lt;p&gt;Self-advocacy is really powerful because it helped me to speak more positively about myself and talk about my accomplishments (not in a narcissistic way but to give form/life to the things that people cannot see). This is not to say that speaking up is equivalent to being arrogant. You can speak up with respect for others and yourself and in a kind way. To borrow the phrase that’s used from the Google #IamRemarkable initiative workshops, “It’s not bragging if it’s based on facts!”.&lt;/p&gt;

&lt;p&gt;You don’t have to sell your soul in order to advocate for yourself. You can still advocate for yourself and be authentic too!&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a Highlights Log
&lt;/h3&gt;

&lt;p&gt;I have recently started logging my highlights on a Google Sheets and this has served me in multiple ways. It has built my confidence, enabled me to view my highlights objectively, supported me in organising my log, so that it makes things a lot easier when it came to updating my website or CV, or just for a positive boost.&lt;/p&gt;

&lt;p&gt;Be sure to read on to the very end of this post for a free template you can use to start your very own highlights log.&lt;/p&gt;

&lt;h3&gt;
  
  
  Guide to Nominating Yourself for an Award
&lt;/h3&gt;

&lt;p&gt;When I started my technology career, I was fortunate enough to have had a lot of support from the community to help me grow in my skills and confidence. I remembered the first time I saw a call for nominations for a technology award on LinkedIn and I clicked on the website and stared at the words ‘Nominate Yourself’; I just laughed and thought ‘I would like to be considered for an award, but no flipping chance’. There’s so much that’s not spoken about this mentality and I think it stems from the following thoughts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If I nominate myself, will people…&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Laugh at me?&lt;/p&gt;

&lt;p&gt;Judge me?&lt;/p&gt;

&lt;p&gt;Think that the award is worthless because I nominated myself anyway?&lt;/p&gt;

&lt;p&gt;Think that it’s unfair and others deserve it more?&lt;/p&gt;

&lt;p&gt;Somehow, the feelings of guilt and embarrassment come into play here and it’s completely natural, no one wants to stick out of the crowd and especially not in this way.&lt;/p&gt;

&lt;p&gt;I’m here to challenge thoughts on this and here are the reasons why you should put forward a nomination for yourself for anything you like. Keep these phrases in mind in your head:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I ‘can’ put forward a nomination for myself because:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I can convey my passions, missions and values to others because they define who I am and my identities;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I know and can articulate my achievements, successes and failures in a clear way;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I would like to practise self-advocacy and use the opportunity to learn;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Putting forward a nomination does not equate to winning the award. There are several rounds of interviews / shortlisting after the initial nomination.&lt;/p&gt;

&lt;p&gt;Even if you don’t want to put forward a nomination for yourself, you can help someone else by nominating on their behalf. Here’s 5 top tips for putting together a nomination for yourself/others:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Identity one goal you will learn/achieve from this process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write down some bullet points of the values you firmly believe in - this can be anything from ‘respect’, to ‘curiosity’, to ‘charity’ etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What are you passionate about or enjoy doing? What is authentically you? Don’t be afraid to bring some personality here, it can be something career/work-related or outside of work. The worst thing you can do is to create a ‘fake’ nomination that you yourself cannot stand by / be proud of;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use a highlights log to filter any notable things you would like to highlight in more detail - a sentence or two for each highlight is more than enough.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Situation - Describe the context / set the scene&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Task - What problem/issue were you trying to solve? Who was involved and what was your role?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Action - What did you do? How were you involved?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Result - What did you achieve and what impact did this have?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enjoy the process and have some fun. Don’t worry if you didn’t get shortlisted or win anything, through this process, you have built up a set of mission, vision and values for yourself, as well as a lovely log, increased self-advocacy skills and self-confidence and learnt something new.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Please nominate another person who deserves to be recognised but may not have had the courage to speak up for themselves yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank you
&lt;/h3&gt;

&lt;p&gt;Thanks for reading my post! As promised, here’s the link to the &lt;a href="https://docs.google.com/spreadsheets/d/1GFN9S9bznv_Fn-hXmEwMwduZRAyDVJFnBs9Y2eZhtSE/edit?usp=sharing"&gt;free Curiously Code - Highlights Log template&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>curiouslycode</category>
      <category>careeradvice</category>
      <category>career</category>
      <category>selfadvocacy</category>
    </item>
    <item>
      <title>Things I Wished I Knew About DevOps Practices and Cloud Technologies When I Started my First Role in Tech</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Thu, 15 Apr 2021 08:54:57 +0000</pubDate>
      <link>https://dev.to/thekimmykola/things-i-wished-i-knew-about-devops-practices-and-cloud-technologies-when-i-started-my-first-role-in-tech-160o</link>
      <guid>https://dev.to/thekimmykola/things-i-wished-i-knew-about-devops-practices-and-cloud-technologies-when-i-started-my-first-role-in-tech-160o</guid>
      <description>&lt;p&gt;It’s 2021 and I’m just over a month into my third role as a Software Engineer &amp;amp; Tech Coach. It’s been a whirlwind of a journey so far! Here’s some things I wished I knew about DevOps practices and cloud technologies when I started my first role in tech.&lt;/p&gt;

&lt;h3&gt;
  
  
  My role wasn’t just about full-stack Software Engineering in C#, but also involved DevOps practices and Cloud technologies
&lt;/h3&gt;

&lt;p&gt;During my career switch into tech, I thought that DevOps practices and Cloud technologies were utilised solely by DevOps Engineers and Cloud Engineers. I under appreciated how much of my role involved DevOps practices and Cloud.&lt;/p&gt;

&lt;p&gt;When I spoke to people in my network and especially those who have recently started their first roles in technology; it seemed like there was a mixed bag. Some people were not involved in DevOps and Cloud at all, though they mentioned some of their colleagues were. Others, like myself had more of a hybrid role and some people were doing DevOps and Cloud every single day!&lt;/p&gt;

&lt;h3&gt;
  
  
  What is DevOps in a nutshell?
&lt;/h3&gt;

&lt;p&gt;AWS states, "DevOps is the combination of...philosophies, practices, and tools that increases an organisation's ability to deliver applications and services…". The infrastructure and process that sits behind software ensures a smoother experience for building code, testing it, shipping it out and monitoring it.&lt;/p&gt;

&lt;h3&gt;
  
  
  DevOps and Cloud is there to help Developers
&lt;/h3&gt;

&lt;p&gt;Some Software Engineers would say that DevOps and Cloud is not part of their role, so why should they bother; they do have a point there. It’s a massive world, recently, product offerings like AWS Amplify for example, help those who major on the front-end and API domains build mobile/web apps quickly. However, there's value in learning some of the key concepts on how DevOps and cloud is helpful.&lt;/p&gt;

&lt;p&gt;In my first role in tech, I wanted to learn some fundamentals of DevOps and Cloud that would support me in my role as a C# Full-Stack Software Engineer.&lt;/p&gt;

&lt;p&gt;In my team at the time, one of the projects we were tasked with was re-writing a legacy Excel application into a .NET Core 3.1 C# web application (at the time of writing this post, it’s .NET 5). I really liked the way my team worked together on this, all the developers/testers, business analysts, our product owner and scrum master mobbed on this.&lt;/p&gt;

&lt;p&gt;Something popped into my head at the time: “Why can’t we just build the web application and then just deploy it to production for the users, easy right? I can just click around on the Azure Portal and just manually make my resources there and then manually deploy.”&lt;/p&gt;

&lt;p&gt;Well, when we started mob programming on the cloud infrastructure process, I realised there was more to just ‘making something work’.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automated Continuous Integration &amp;amp; Continuous Deployments Using Azure Repos &amp;amp; Pipelines
&lt;/h3&gt;

&lt;p&gt;One of the things that stuck with me was CI/CD (Continuous Integration / Continuous Deployment). According to the AWS DevOps &lt;a href="https://aws.amazon.com/blogs/devops/complete-ci-cd-with-aws-codecommit-aws-codebuild-aws-codedeploy-and-aws-codepipeline/#:~:text=An%20integral%20part%20of%20DevOps,from%20development%20to%20production%20environments."&gt;blog&lt;/a&gt;, “An integral part of DevOps is adopting the culture of continuous integration and continuous delivery/deployment (CI/CD), where a commit or change to code passes through various automated stage gates, all the way from building and testing to deploying applications, from development to production environments.”&lt;/p&gt;

&lt;p&gt;I got to appreciate this by learning about git, git repositories on Azure repos, managing branches and creating pipelines to build and deploy our C# solution.&lt;/p&gt;

&lt;p&gt;During my learning process, I had a sneak peak at how different teams were utilising Azure Pipelines. At first I was hard-coding things in and this sort of worked, but then I found myself copying and pasting all the time. I then realised parameterisation was helpful to ensure I could supply different values for the same pipeline variables. This helped me as a developer and for other developers on my team because it meant we could replicate the same setup across the development environments, testing environments, pre-production and production environments of the pipeline. We could configure things to be switched ‘on’ and ‘off’ through code.&lt;/p&gt;

&lt;p&gt;Separation of concerns was important here. We decided to go with an infrastructure pipeline and an app pipeline. If there were changes to the web application on a branch, CI/CD will automatically detect this and trigger a build and deploy onto the relevant environments using the relevant pipelines. Test suites would also run automatically too. Once the Pull Request (PR) for the branch has been approved and merged, the CI/CD pipeline will build and deploy to the environments. No more arduous manual deployments that we had to deal with for the original Excel application! Great!&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure-as-Code
&lt;/h3&gt;

&lt;p&gt;During my first role, I realised that clicking around the settings on the Azure Portal to create and configure resources was helpful for me, but not helpful for others. It wasn’t repeatable. We had to think as a team how we can define the infrastructure and configure it using a better approach. This was where the Azure Resource Manager (ARM) templates came in handy. It enabled the definition of what infrastructure we wanted to make, how we wanted to make it and configure it.&lt;/p&gt;

&lt;p&gt;The ARM templates were useful as they could be version controlled through git as well; just like we would version control code. There were also helpful extensions on Visual Studio for structuring and validating these templates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most importantly, it enabled a repeatable and testable process for our infrastructure.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Logging &amp;amp; Monitoring
&lt;/h3&gt;

&lt;p&gt;So why do we need logging &amp;amp; monitoring? Let me put it this way, when you release a new feature for your product, that's just the start. Just as a plane has a suite of telemetry to record readings from instruments; it is the same concept for software to ensure everything is operating as it should. Try to think where logging and monitoring makes sense for you.&lt;/p&gt;

&lt;p&gt;We used Azure Monitor to add observability into our applications, infrastructure and network.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;This is just the surface of what DevOps and Cloud technologies can offer to developers, of course there are specialists who go a bit deeper into more concepts that those I've covered here. If you are working in tech, there is some benefit to learning some of the fundamentals about the infrastructure and process that sits behind software to ensure smoother experiences for building code, testing it, shipping it out and monitoring it.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>career</category>
      <category>learning</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Hey Kim, what’s it like being a Software Engineer &amp; Tech Coach? Q&amp;A Session</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Sun, 11 Apr 2021 10:44:20 +0000</pubDate>
      <link>https://dev.to/thekimmykola/hey-kim-what-s-it-like-being-a-software-engineer-tech-coach-q-a-session-424e</link>
      <guid>https://dev.to/thekimmykola/hey-kim-what-s-it-like-being-a-software-engineer-tech-coach-q-a-session-424e</guid>
      <description>&lt;h2&gt;
  
  
  How did you become a Software Engineer &amp;amp; Tech Coach?
&lt;/h2&gt;

&lt;p&gt;I didn’t plan this path; it totally happened by accident! 😂&lt;/p&gt;

&lt;p&gt;It was only back in February 2019 that I received a fully-funded scholarship to attend a 16-week intensive Software Engineering Bootcamp at Makers. I was a career switcher, having at the time spent over 4 years in sustainability and business consulting roles.&lt;/p&gt;

&lt;p&gt;I have since been exposed to full-stack Software Engineering and DevOps practices from a range of roles and industries such as investment management, e-commerce and tech education.&lt;/p&gt;

&lt;p&gt;While in my Software Engineer role at Trainline, which is a FTSE 250 rail and coach ticketing platform, a random advert popped up in my LinkedIn feed in December 2020 and it was for a Software Engineer &amp;amp; Tech Coach role at &lt;a href="https://www.techreturners.com/"&gt;Tech Returners&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When I read the job advert, negative thoughts started coming to my head:&lt;/p&gt;

&lt;p&gt;😥 “Am I doing the right thing? Is it too early in my tech career to do this? I’ll be leaving a FTSE 250 company, will I regret it?”&lt;/p&gt;

&lt;p&gt;😥 “Am I even qualified for this? There’s only some technologies on the job description I know well, those I know enough to get by and those where I don’t have a clue yet!”&lt;/p&gt;

&lt;p&gt;Somehow because these thoughts came into my head, I wanted to pursue this more than ever! I tried to map things out rationally and thought about what I enjoyed doing, which was my experience teaching people to code and creating &lt;a href="https://www.thekimmykola.dev/teaching-workshops"&gt;workshops&lt;/a&gt; for the community alongside my friends, &lt;a href="https://www.thekimmykola.dev/speaking"&gt;speaking&lt;/a&gt; and &lt;a href="https://www.thekimmykola.dev/mentoring"&gt;mentoring&lt;/a&gt; work. However, I still wanted to keep on being an active Software Engineer, so the role was a great blend for me.&lt;/p&gt;

&lt;p&gt;🙌 I applied for the role, did my 2-minute elevator pitch video, had my interviews and landed the job! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you do as a Software Engineer &amp;amp; Tech Coach?
&lt;/h2&gt;

&lt;p&gt;It’s been just over a month since I started my role as a Software Engineer &amp;amp; Tech Coach at &lt;a href="https://www.techreturners.com/"&gt;Tech Returners&lt;/a&gt; - whoop whoop! :) It’s a hybrid role which means I get to do tech coaching and software engineering.&lt;/p&gt;

&lt;p&gt;As a Tech Coach, I help to deliver programmes to upskill individuals at mid-senior levels in technology. Since learners on the programme have prior tech experience, it means I have the opportunity to explore tech concepts in a bit more depth. I’m currently leading sessions, helping with seminars on tech topics, having 1:1s with learners/pair programming with them, recording short videos and providing detailed code review feedback. I onboarded remotely and went straight into all the action. By Day 3, I was already delivering some sessions!&lt;/p&gt;

&lt;p&gt;💜 I remember my first week watching in awe as the other Tech Coaches, James, Ellie and Heather did their thing! They conducted their roles with care, precision and best practice; I honestly wondered why people hadn’t heard of &lt;a href="https://www.techreturners.com/"&gt;Tech Returners&lt;/a&gt; before.&lt;/p&gt;

&lt;p&gt;One of my goals is to design and develop a 5-star curriculum to really innovate tech education.&lt;/p&gt;

&lt;p&gt;As a Software Engineer, I’m working on internal projects across the full software development lifecycle. There’s a project I’m working on which is totally brand new, a great chance for me to be involved with a product from scratch.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you go about teaching technical concepts? What techniques do you use?
&lt;/h2&gt;

&lt;p&gt;👩🏻‍💻 I use plenty of visualisations&lt;/p&gt;

&lt;p&gt;👩🏻‍💻 I explain tech concepts using analogies and relate them to real-life things&lt;/p&gt;

&lt;p&gt;👩🏻‍💻 I record short videos/screen recordings to walkthrough tricky technical concepts, provide thorough code review feedback and help with debugging strategies&lt;/p&gt;

&lt;p&gt;👩🏻‍💻 I conduct 1:1 and group video calls to host sessions, webinars and provide technical and wellbeing support&lt;/p&gt;

&lt;p&gt;👩🏻‍💻 I try to start from the core principles and break down technical jargon as much as I can to make it sound less daunting. Some technologies like git version control use scary words which create a barrier to learning; even though the technology can be very powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you balance learning &amp;amp; coaching?
&lt;/h2&gt;

&lt;p&gt;create and deliver programs to help underrepresented people refresh &amp;amp; upskill in the Software Engineering domain after a career break. I also deliver programs to upskill engineers at existing companies in all things DevOps!&lt;/p&gt;

&lt;h3&gt;
  
  
  That’s a lot of technologies! How can you keep up?
&lt;/h3&gt;

&lt;p&gt;I would say I’m aiming for a T-shaped skillset. This means I have deep expertise in few technologies with supporting, but less-developed skills in others. For example, I am more backend/cloud focused with my primary language being C#; but if I get asked a question about React components and how to test components, though that’s not my area of expertise, I’m able to conduct some research, put the pieces together or reach out to other tech coaches to put technical recommendation together.&lt;/p&gt;

&lt;p&gt;Over time, I develop a skill for spotting patterns in code quickly whatever the tech stack/languages used. Learners think I do some magic! The reality is, I don’t, it’s patterns I see again and again which helps me to spot things quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Developing myself while teaching others
&lt;/h3&gt;

&lt;p&gt;I listened to the egghead.io developer chats podcast episode featuring Ali Spittel on &lt;a href="https://open.spotify.com/episode/3ht64W3jQmd1YKrN60NpgB"&gt;Developing Yourself While Teaching Others&lt;/a&gt; and I found so much inspiration from Ali Spittel’s journey.&lt;/p&gt;

&lt;p&gt;Through going through the cycle of learning &amp;amp; coaching, I found myself solidifying my understanding of tech concepts and technologies at a faster rate than if I were to learn without teaching others. Before being a Tech Coach, I would become impatient and skip over a tech concept quickly just to ‘make things work’; I am now focusing deeper and with higher precision with my learning to enable me to provide the best technical coaching. &lt;/p&gt;

&lt;p&gt;Since I’m not writing production code as often, I set some time aside (25 mins to 1 hour) in the morning before my work commitments to develop myself by building my own projects, practicing my coding skills or researching technical concepts. I don’t code on the weekends and in the evenings after 6pm because I find it’s important to have some time off. I’m trying to learn how to be a more effective and efficient learner every day. I also repeat technical concepts again and again, rather than moving on too quickly.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you enjoy most about being a Software Engineer &amp;amp; Tech Coach?
&lt;/h2&gt;

&lt;p&gt;I love seeing others learn and grow in their technical skills and confidence. It’s not just about the technical journey, but the human one too. &lt;/p&gt;

&lt;p&gt;I also really like the challenge of finding new ways to explain technical concepts and technologies in digestible ways. I like the feeling I get when I get asked a question from the learners and I have the opportunity to go in and explore for myself.&lt;/p&gt;

&lt;p&gt;I like pair programming and mob programming with the other Software Engineers &amp;amp; Tech Coaches so we can all learn together and continue to innovate tech education.&lt;/p&gt;

&lt;h2&gt;
  
  
  What would you say are the most challenging aspects of your role?
&lt;/h2&gt;

&lt;p&gt;From a technical standpoint, there's times where I doubt myself and my abilities and I start to think: “What if I get caught out?” “What if I get asked a question and I don’t have a clue how to answer it yet?” “Surely, I’m the tech coach and I should know everything right?” I always have to remind myself about my T-shaped skillset and that I don’t have to be an expert in everything.&lt;/p&gt;

&lt;p&gt;From an emotional standpoint, I have a duty of care for my learners, which means I provide support from a wellbeing standpoint and ensuring I listen to my learners and help them find ways to move forward and reflect for themselves. Therefore, I have to be more disciplined with the way I use my time more than ever, so that I can focus on providing the best support possible; whilst also making sure I take care of myself and prioritise my own time for my learning before I can support others.&lt;/p&gt;

&lt;h2&gt;
  
  
  How are you continuing to develop yourself? What’s in store for the future?
&lt;/h2&gt;

&lt;p&gt;For my T-shaped skillset, I decided that I would focus on C# as my primary language. In terms of tech stack, I’m focusing on the backend and DevOps side of things. I’m not a specialist in HTML, CSS and React, though I’m able to work with it as best as I can.&lt;/p&gt;

&lt;p&gt;I love creating content, designing, developing and innovating tech education, so would love to continue to create workshops for the community and do some public engagements around technology, such as my most recent collaboration with &lt;a href="https://www.thekimmykola.dev/teaching-workshops"&gt;The National Museum of Computing&lt;/a&gt; and the &lt;a href="https://www.thekimmykola.dev/teaching-workshops"&gt;Codebar Festival&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for reading! :)
&lt;/h2&gt;

&lt;p&gt;My &lt;a href="https://www.thekimmykola.dev/"&gt;website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>learning</category>
      <category>community</category>
      <category>teachingcode</category>
    </item>
    <item>
      <title>C# Repository Design Pattern for Database Operations in a .NET Core 3.1 MVC Web App</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Sat, 06 Jun 2020 15:08:46 +0000</pubDate>
      <link>https://dev.to/thekimmykola/c-repository-design-pattern-for-database-operations-in-a-net-core-3-1-mvc-web-app-5e9d</link>
      <guid>https://dev.to/thekimmykola/c-repository-design-pattern-for-database-operations-in-a-net-core-3-1-mvc-web-app-5e9d</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When building applications, it is important to consider how and where you're conducting database operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Entity Framework Database Context (DbContext) and the Controller
&lt;/h2&gt;

&lt;p&gt;Building a basic template for a .NET Core 3.1 application using a scaffolding approach like the one from this Microsoft &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/start-mvc?view=aspnetcore-3.1&amp;amp;tabs=visual-studio"&gt;tutorial&lt;/a&gt; is a great starting point. Firstly, let's have a look at a small code snippet generated from the scaffolding.&lt;/p&gt;

&lt;p&gt;In this example, the &lt;strong&gt;PusheenController&lt;/strong&gt; class has actions for CRUD (Create, Read, Update and Delete) operations against the database. Here, we are directly interacting with the Entity Framework DbContext class called &lt;strong&gt;PusheenCustomExportCsvContext&lt;/strong&gt; and retrieving data about Pusheens from the database. The &lt;strong&gt;PusheenCustomExportCsvContext&lt;/strong&gt; is injected as a dependency into the &lt;strong&gt;PusheenController&lt;/strong&gt;. In this web app, dependencies are added to the service container in the &lt;strong&gt;ConfigureServices&lt;/strong&gt; method in &lt;strong&gt;Startup.cs&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, it is easy to end up with big controllers; big in the sense that there's a lot of database operations logic built into the controller. Since the &lt;strong&gt;DbContext&lt;/strong&gt; is a dependency of the controller, a further issue faced is if you were to test this, you would have to mock the &lt;strong&gt;DbSet&lt;/strong&gt; and &lt;strong&gt;DbContext&lt;/strong&gt;. It is definitely achieveable to mock we like; but we would have to mock the Provider, Expression, ElementType properties and GetEnumerator() method.&lt;/p&gt;

&lt;p&gt;In larger applications, we would like to separate the concerns out into layers that are responsible for the business logic, presentation, database etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 1: DbContext and PusheenController&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;PusheenCustomExportCsv.Web.Controllers&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PusheenController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Controller&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;PusheenCustomExportCsvContext&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PusheenController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PusheenCustomExportCsvContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_context&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;

        &lt;span class="c1"&gt;// GET: Pusheen/Details/5&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Details&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pusheens&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SingleOrDefaultAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheen&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;View&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// GET: Pusheen/Create&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;View&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// POST: Pusheen/Create&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ValidateAntiForgeryToken&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Id,Name,FavouriteFood,SuperPower"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;Pusheen&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;RedirectToAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Index"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;View&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is the goal of the Repository Design Pattern and why is it useful?
&lt;/h2&gt;

&lt;p&gt;Let's assume we would like a presentation layer made up of controllers and views, and a service layer for the business logic and database operations. We can create a repository (in this case lumped into the service for simplicity) where our database operations and logic can sit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The repository is in charge of interacting with the Entity Framework DbContext class, so the controller doesn't have to.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Repository: Defining and Implementing the Interface
&lt;/h3&gt;

&lt;p&gt;In this interface, we define an &lt;strong&gt;IPusheenService&lt;/strong&gt; and implement the interface in the &lt;strong&gt;PusheenService&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 2: IPusheenService&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;PusheenCustomExportCsv.Web.Services&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IPusheenService&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAllAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;FindPusheenAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;FindPusheenById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;PusheenExists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Below is an example of how &lt;strong&gt;PusheenService&lt;/strong&gt; implements &lt;strong&gt;FindPusheenAsync&lt;/strong&gt; and &lt;strong&gt;FindPusheenById&lt;/strong&gt;. These database operations were originally coded directly into the controller as we saw in &lt;strong&gt;Example 1&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 3: PusheenService&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;FindPusheenAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pusheens&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;FindPusheenById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pusheens&lt;/span&gt;
                &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefaultAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see what our controller looks like now. The key difference is that the &lt;strong&gt;PusheenController&lt;/strong&gt; is a lot slimmer and we don't need to interact with the &lt;strong&gt;DbContext&lt;/strong&gt; directly anymore; that's the job of the repository now! :)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example 4: PusheenController&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;PusheenCustomExportCsv.Web.Controllers&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PusheenController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Controller&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IPusheenService&lt;/span&gt; &lt;span class="n"&gt;_pusheenService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PusheenController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IPusheenService&lt;/span&gt; &lt;span class="n"&gt;pusheenService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_pusheenService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pusheenService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;

        &lt;span class="c1"&gt;// GET: Pusheen/Details/5&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Details&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_pusheenService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindPusheenById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheen&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;View&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// GET: Pusheen/Create&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;View&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// POST: Pusheen/Create&lt;/span&gt;
        &lt;span class="c1"&gt;// To protect from overposting attacks, enable the specific properties you want to bind to, for &lt;/span&gt;
        &lt;span class="c1"&gt;// more details, see http://go.microsoft.com/fwlink/?LinkId=317598.&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ValidateAntiForgeryToken&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Id,Name,FavouriteFood,SuperPower"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;Pusheen&lt;/span&gt; &lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ModelState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsValid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_pusheenService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;RedirectToAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Index&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;View&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheen&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;//Code omitted for brevity :)&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I hope you find this post useful and being part of my coding journey! Thank you for reading my blog! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Link to Github Repo
&lt;/h2&gt;

&lt;p&gt;You can find the link to my Github repo with the simple web app example &lt;a href="https://github.com/kimdiep/pusheen-custom-fileresult-csv-export-aspnetcore"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>C# Unit Testing a Custom FileResult That Exports Data into a CSV file Using Streaming in a .NET Core 3.1 MVC App</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Fri, 29 May 2020 17:16:50 +0000</pubDate>
      <link>https://dev.to/thekimmykola/c-unit-testing-a-custom-fileresult-that-exports-data-into-a-csv-file-using-streaming-in-a-net-core-3-1-mvc-app-3npo</link>
      <guid>https://dev.to/thekimmykola/c-unit-testing-a-custom-fileresult-that-exports-data-into-a-csv-file-using-streaming-in-a-net-core-3-1-mvc-app-3npo</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the past two months at work, I was tasked with learning C#, as well as creating a web app using the .NET Core 3.1 MVC framework. I wanted to document the most interesting concepts in a series of blog posts.&lt;/p&gt;

&lt;p&gt;In my last &lt;a href="https://kimdiep.github.io/kimdiep-gatsby-blog/posts/custom-csvresult-fileresult-dotnetcore-mvc/"&gt;blog&lt;/a&gt;, I demonstrated how to create a custom &lt;em&gt;FileResult&lt;/em&gt; to export data into a CSV file using streaming in a .NET Core 3.1 MVC web app. In this follow on blog post, I will show you how to unit test the custom &lt;em&gt;FileResult&lt;/em&gt; and the controller which produces this &lt;em&gt;FileResult&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Again, the actual code was more complex; this blog was my attempt to abstract the core concepts into a simple web app using Pusheen the Cat as a fun example!&lt;/p&gt;

&lt;h2&gt;
  
  
  Unit Testing Custom FileResult With Streaming in .NET Core 3.1
&lt;/h2&gt;

&lt;p&gt;In my last blog, I had a custom &lt;em&gt;FileResult&lt;/em&gt; called &lt;em&gt;PusheenCsvResult&lt;/em&gt;. To set the scene for unit testing, I used the &lt;em&gt;NUnit&lt;/em&gt; testing framework, along with the &lt;em&gt;FluentAssertions&lt;/em&gt; and &lt;em&gt;FluentAssertions.AspNetCore.Mvc&lt;/em&gt; libraries, which provided a clear way to communicate what I was asserting in my test (i.e. what was the expected result). I applied the &lt;strong&gt;Arrange, Act, Assert&lt;/strong&gt; structure for this and am still learning the best way to do it!&lt;/p&gt;

&lt;p&gt;P.S. Would highly recommend the book &lt;a href="https://www.amazon.co.uk/Agile-Technical-Practices-Distilled-principles/dp/1838980849/ref=pd_lpo_14_t_0/262-2345187-8535340?_encoding=UTF8&amp;amp;pd_rd_i=1838980849&amp;amp;pd_rd_r=3b0ea091-114f-4741-bf68-141b316c4e70&amp;amp;pd_rd_w=j3FEq&amp;amp;pd_rd_wg=QeWz3&amp;amp;pf_rd_p=7b8e3b03-1439-4489-abd4-4a138cf4eca6&amp;amp;pf_rd_r=BQAAG5YRVP90CYHGFSCH&amp;amp;psc=1&amp;amp;refRID=BQAAG5YRVP90CYHGFSCH"&gt;Agile Technical Practices Distilled: A learning journey in technical practices and principles of software design&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  What was the goal?
&lt;/h3&gt;

&lt;p&gt;Let's start off with the goal! When we're working with unit testing, it's helpful to define what it is we're checking for. In this unit testing situation, I wanted a way to check that the &lt;em&gt;PusheenCsvResult&lt;/em&gt;'s method &lt;em&gt;ExecuteResultAsync&lt;/em&gt; was streaming (writing) the response correctly to the &lt;em&gt;HttpContext&lt;/em&gt;'s response body.&lt;/p&gt;

&lt;h3&gt;
  
  
  How did I go about doing it?
&lt;/h3&gt;

&lt;p&gt;Knowing this, I followed some tips in the &lt;a href="https://www.amazon.co.uk/Agile-Technical-Practices-Distilled-principles/dp/1838980849/ref=pd_lpo_14_t_0/262-2345187-8535340?_encoding=UTF8&amp;amp;pd_rd_i=1838980849&amp;amp;pd_rd_r=3b0ea091-114f-4741-bf68-141b316c4e70&amp;amp;pd_rd_w=j3FEq&amp;amp;pd_rd_wg=QeWz3&amp;amp;pf_rd_p=7b8e3b03-1439-4489-abd4-4a138cf4eca6&amp;amp;pf_rd_r=BQAAG5YRVP90CYHGFSCH&amp;amp;psc=1&amp;amp;refRID=BQAAG5YRVP90CYHGFSCH"&gt;Agile Technical Practices Distilled&lt;/a&gt; book to start from the assertion and work backwards (Assert, Act , Arrange). I didn't just magically know what I needed; it took some time to get there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting it up
&lt;/h3&gt;

&lt;p&gt;I created a &lt;em&gt;[TestFixture]&lt;/em&gt; for testing &lt;em&gt;PusheenCsvResult&lt;/em&gt; and within the &lt;em&gt;[SetUp]&lt;/em&gt;, I defined a &lt;em&gt;_httpContext&lt;/em&gt;, &lt;em&gt;_fileDownloadName&lt;/em&gt; and made a fake &lt;em&gt;_fakeActionContext&lt;/em&gt; object.&lt;/p&gt;

&lt;p&gt;The reason I did this was because the &lt;em&gt;PusheenCsvResult&lt;/em&gt;'s method &lt;em&gt;ExecuteResultAsync&lt;/em&gt;, took a parameter which was of type &lt;em&gt;ActionContext&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's recap on my last &lt;a href="https://kimdiep.github.io/kimdiep-gatsby-blog/posts/custom-csvresult-fileresult-dotnetcore-mvc/"&gt;blog&lt;/a&gt; for a second, the job of &lt;em&gt;ExecuteResultAsync&lt;/em&gt; is using &lt;em&gt;StreamWriter&lt;/em&gt; to write to the response body of the &lt;em&gt;HttpContext&lt;/em&gt; of the &lt;em&gt;ActionContext&lt;/em&gt; and the stream sits in between the application and in this case the response body. The data is written to the stream (response body) and then from the stream, it then results in the CSV file being produced.&lt;/p&gt;

&lt;p&gt;In the case of the unit test scope, I wanted to create a &lt;em&gt;_fakeActionContext&lt;/em&gt; object as an instance of &lt;em&gt;ActionContext&lt;/em&gt; and in it's constructor, I set the &lt;em&gt;HttpContext&lt;/em&gt; as the &lt;em&gt;_httpContext&lt;/em&gt; I defined earlier in my test &lt;em&gt;[SetUp]&lt;/em&gt;. This enabled the ability to check what was written to the response body of that &lt;em&gt;_httpContext&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;Code&lt;/span&gt; &lt;span class="n"&gt;omitted&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;brevity&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TestFixture&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PusheenCsvResultShould&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;PusheenCsvResult&lt;/span&gt; &lt;span class="n"&gt;_pusheenCsvResult&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_fileDownloadName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_expectedResponseText&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;DefaultHttpContext&lt;/span&gt; &lt;span class="n"&gt;_httpContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;ActionContext&lt;/span&gt; &lt;span class="n"&gt;_fakeActionContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SetUp&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_httpContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;DefaultHttpContext&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;_fileDownloadName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"pusheen.csv"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="n"&gt;_fakeActionContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ActionContext&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_httpContext&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;GivenActionContext_ExecuteResultAsync_ShouldWriteLineToHttpResponseBody&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="c1"&gt;//Arrange&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Pusheen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FavouriteFood&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Ice cream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SuperPower&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Baking delicious cookies"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Pusheenosaurus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FavouriteFood&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Leaves"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SuperPower&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Roarrrrr!"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Pusheenicorn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FavouriteFood&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Butterfly muffins"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SuperPower&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Making rainbow poop"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;AsQueryable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;PusheenCsvResult&lt;/span&gt; &lt;span class="n"&gt;_pusheenCsvResult&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PusheenCsvResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_fileDownloadName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="n"&gt;_expectedResponseText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAllText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TestContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestDirectory&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;@"/TestData/expectedCsv.txt"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;memoryStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;_httpContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;//Act&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_pusheenCsvResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteResultAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_fakeActionContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;streamText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

            &lt;span class="c1"&gt;//Assert&lt;/span&gt;
            &lt;span class="n"&gt;streamText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_expectedResponseText&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Let's hop over to the test
&lt;/h3&gt;

&lt;p&gt;For the &lt;em&gt;[Test]&lt;/em&gt; itself, I checked that given an &lt;em&gt;ActionContext&lt;/em&gt;, the method &lt;em&gt;ExecuteResultAsync&lt;/em&gt; should WriteLine to the HttpContext response body.&lt;/p&gt;

&lt;p&gt;I needed a &lt;em&gt;PusheenCsvResult&lt;/em&gt; for my test, and that took 2 parameters for it's constructor.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;data (as type &lt;em&gt;IQueryable&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;fileDownloadName (as type &lt;em&gt;String&lt;/em&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I already defined &lt;em&gt;fileDownloadName&lt;/em&gt; earlier in the &lt;em&gt;[SetUp]&lt;/em&gt;, so the next step was to make some data for the test scenario. In this case, a &lt;em&gt;new List&lt;/em&gt; as &lt;em&gt;.AsQueryable()&lt;/em&gt; was created and I passed this into &lt;em&gt;PusheenCsvResult&lt;/em&gt;'s constructor.&lt;/p&gt;

&lt;p&gt;Based on this information, I wanted to make a file containing the expected text I would expect to see as &lt;em&gt;_expectedResponseText&lt;/em&gt;. In my assertion, I checked that the text I got from the stream should match the &lt;em&gt;_expectedResponseText&lt;/em&gt; for the test to pass.&lt;/p&gt;

&lt;h3&gt;
  
  
  Now, this was the tricky bit - how to deal with closed streams?
&lt;/h3&gt;

&lt;p&gt;When I was testing this, I didn't know what was wrong, as the test kept saying that it couldn't access a closed stream. Since I defined the StreamWriter within a &lt;em&gt;using&lt;/em&gt; block; the stream will be closed once it's done its job. This was not a bad thing and is something I recommend doing in your implementation; but it meant I needed another way to access what was written to the stream for the purpose of the unit testing (in this case, the stream was the HttpContext's response body itself).&lt;/p&gt;

&lt;p&gt;I added some comments on the code snippet below to describe what was going on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
            &lt;span class="c1"&gt;// I create a new Memory Stream and set that stream as the Response Body of the _httpContext I'm using in my unit test scope&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;memoryStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;_httpContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;//Act&lt;/span&gt;
            &lt;span class="c1"&gt;// I await and pass the _fakeActionContext to my ExecuteResultAsync method. Reminder that I pointed the HttpContext of ActionContext to the _httpContext I made for testing&lt;/span&gt;
            &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_pusheenCsvResult&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteResultAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_fakeActionContext&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;//I need to make sure that I capture the contents of the memoryStream and store it against the variable streamText which I can access later in my assertion&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;streamText&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Encoding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Default&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;memoryStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Unit testing the Controller
&lt;/h2&gt;

&lt;p&gt;The controller was a bit more straightforward. I used &lt;em&gt;Moq&lt;/em&gt; to mock the &lt;em&gt;PusheenService&lt;/em&gt; and its method &lt;em&gt;GetAllPusheens()&lt;/em&gt; to return some data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="n"&gt;_mockPusheenService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllPusheens&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;Returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, I tested that &lt;em&gt;ExportCsv&lt;/em&gt; on the &lt;em&gt;PusheenController&lt;/em&gt; returned the result of type &lt;em&gt;PusheenCsvResult&lt;/em&gt; and that the &lt;em&gt;fileDownloadName&lt;/em&gt; and &lt;em&gt;contentType&lt;/em&gt; were correct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;been&lt;/span&gt; &lt;span class="n"&gt;omitted&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;brevity&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="p"&gt;:)&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;PusheenCustomExportCsv.Tests.Controllers&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;TestFixture&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PusheenControllerShould&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;PusheenController&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IPusheenService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_mockPusheenService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IConfiguration&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_mockConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;DbContextOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PusheenCustomExportCsvContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_testDbOptions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;PusheenCustomExportCsvContext&lt;/span&gt; &lt;span class="n"&gt;_testDbContext&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SetUp&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_mockPusheenService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Mock&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IPusheenService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
            &lt;span class="n"&gt;_controller&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PusheenController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_mockPusheenService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ExportCsv_Returns_CsvResult&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//Arrange&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;()&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Pusheen"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FavouriteFood&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Ice cream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SuperPower&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Baking delicious cookies"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Pusheenosaurus"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FavouriteFood&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Leaves"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SuperPower&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Roarrrrr!"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Pusheenicorn"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FavouriteFood&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Butterfly muffins"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SuperPower&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Making rainbow poop"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;AsQueryable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="n"&gt;_mockPusheenService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Setup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllPusheens&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;Returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;//Act&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_controller&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExportCsv&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;//Assert&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;BeOfType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PusheenCsvResult&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FileDownloadName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"pusheen.csv"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Should&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;Be&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/csv"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I hope you find this post useful and being part of my coding journey! Thank you for reading my blog! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Link to Github Repo
&lt;/h2&gt;

&lt;p&gt;You can find the link to my Github repo with the simple web app example containing the custom fileresult and test project &lt;a href="https://github.com/kimdiep/pusheen-custom-fileresult-csv-export-aspnetcore"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
    </item>
    <item>
      <title>C# Creating a Custom FileResult to Export Data into a CSV file Using Streaming in a .NET Core 3.1 MVC App</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Fri, 22 May 2020 11:59:04 +0000</pubDate>
      <link>https://dev.to/thekimmykola/c-creating-a-custom-fileresult-to-export-data-into-a-csv-file-using-streaming-in-a-net-core-3-1-mvc-app-2311</link>
      <guid>https://dev.to/thekimmykola/c-creating-a-custom-fileresult-to-export-data-into-a-csv-file-using-streaming-in-a-net-core-3-1-mvc-app-2311</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: What is the goal?
&lt;/h2&gt;

&lt;p&gt;In the past two months at work, I was tasked with learning C#, as well as creating a web app using the .NET Core 3.1 MVC framework. I wanted to document the most interesting concepts in a series of blog posts.&lt;/p&gt;

&lt;p&gt;In this blog, I will show you how to create a custom fileresult to export data into a CSV file using streaming in a .NET Core 3.1 MVC web app. This came about as I was asked to give the user the ability to export their dataset into a CSV file through the web app, but there was a lot of data to deal with. The goal here was to create something to export to a CSV file taking performance into account.&lt;/p&gt;

&lt;p&gt;The actual code was more complex; this blog is my attempt to abstract the core concepts into a simple web app using Pusheen the Cat as a fun example!&lt;/p&gt;

&lt;p&gt;P.S. If you don't know who Pusheen is, I am utterly obsessed with it. You'll probably recognise Pusheen from numerous gifs and stickers on social media.&lt;/p&gt;

&lt;h2&gt;
  
  
  C# Streaming: What is it and why is it useful?
&lt;/h2&gt;

&lt;p&gt;Imagine you had a lot of data to read/write as part of a web app solution; you probably want to break it down into bitesize pieces, as you won't want to read/write a large file in one go! This can be achieved through streaming.&lt;/p&gt;

&lt;p&gt;A stream sits between the application and the file; the benefit of using streaming is the read/write operations are a lot smoother. When you're writing data to somewhere, it is written to the stream and then from the stream, it then goes to your chosen destination, usually a file. When you're reading data, you read to the stream and then your web app can then read from the stream.&lt;/p&gt;

&lt;p&gt;If you like to read on a bit more, this &lt;a href="https://www.guru99.com/c-sharp-stream.html" rel="noopener noreferrer"&gt;article&lt;/a&gt; by Guru99 is particularly helpful.&lt;/p&gt;

&lt;p&gt;"C# provides standard IO (Input/Output) classes to read/write from different sources like a file, memory, network, isolated storage, etc. &lt;strong&gt;System.IO.Stream&lt;/strong&gt; is an abstract class that provides standard methods to transfer bytes (read, write, etc.) to the source. It is like a wrapper class to transfer bytes. Classes that need to read/write bytes from a particular source must implement the Stream class." - Extracted from &lt;a href="https://www.tutorialsteacher.com/csharp/csharp-stream-io" rel="noopener noreferrer"&gt;TutorialsTeacher&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Custom FileResult With Streaming in .NET Core 3.1
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Create a Custom Fileresult in the First Place?
&lt;/h3&gt;

&lt;p&gt;The .NET Core 3.1 MVC framework provides the &lt;strong&gt;ActionResult&lt;/strong&gt; class. Here's the &lt;a href="https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.actionresult?view=aspnetcore-3.1" rel="noopener noreferrer"&gt;link&lt;/a&gt; to the docs for it. It implements the &lt;strong&gt;IActionResult&lt;/strong&gt; interface. ActionResult is essentially the return type of a controller method, it is the base class for lots of result classes to return models to views, file streams and more! There are many derived classes to choose from, but there wasn't one to produce a CSV result. I wanted a &lt;strong&gt;FileResult&lt;/strong&gt; which has streaming and exported to CSV.&lt;/p&gt;

&lt;p&gt;The cool thing was one of the derived classes is &lt;strong&gt;FileResult&lt;/strong&gt;. This class represents an &lt;strong&gt;ActionResult&lt;/strong&gt; that when executed will write a file as the response. We can extend on this class to create a custom &lt;strong&gt;FileResult&lt;/strong&gt; to create a CSV &lt;strong&gt;FileResult&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example of Custom FileResult With Streaming in .NET Core 3.1
&lt;/h2&gt;

&lt;p&gt;Here is an example of a &lt;strong&gt;PusheenCsvResult&lt;/strong&gt; which extends &lt;strong&gt;FileResult&lt;/strong&gt;. As it is specific to exporting data about Pusheen the Cat, we give it some &lt;strong&gt;pusheenData&lt;/strong&gt; as &lt;strong&gt;IEnumerable&lt;/strong&gt;. In it's constructor, we pass in that data along with the &lt;strong&gt;fileDownloadName&lt;/strong&gt; and set the file type to be &lt;strong&gt;"text/csv"&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As we're extending on &lt;strong&gt;FileResult&lt;/strong&gt;, we override &lt;strong&gt;ExecuteResultAsync&lt;/strong&gt; with our implementation. In this example, we're using &lt;strong&gt;StreamWriter&lt;/strong&gt; to write to the response body of the &lt;strong&gt;HttpContext&lt;/strong&gt; of the &lt;strong&gt;ActionContext&lt;/strong&gt;. We write the header row for our CSV file and then iterate through our &lt;strong&gt;_pusheenData&lt;/strong&gt; and write that data. As a reminder, the stream sits in between the application and in this case the response body; the data is written to the stream (response body) and then from the stream, it then results in the CSV file being produced.&lt;/p&gt;

&lt;p&gt;We define the StreamWriter within a &lt;strong&gt;using&lt;/strong&gt; block. We use &lt;strong&gt;StreamWriter.FlushAsync&lt;/strong&gt; method to clear all buffers for the current writer and results in any buffered data to be written to the underlying stream.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.IO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Collections.Generic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Threading.Tasks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Mvc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;PusheenCustomExportCsv.Web.Models&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PusheenCsvResult&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;FileResult&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;_pusheenData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;PusheenCsvResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pusheenData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fileDownloadName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text/csv"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_pusheenData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pusheenData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;FileDownloadName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileDownloadName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;ExecuteResultAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ActionContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Disposition"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"attachment; filename="&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;FileDownloadName&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;streamWriter&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamWriter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;streamWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLineAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="s"&gt;$"Pusheen, Food, SuperPower"&lt;/span&gt;
              &lt;span class="p"&gt;);&lt;/span&gt;
              &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;_pusheenData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;streamWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLineAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                  &lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FavouriteFood&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SuperPower&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
                &lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;streamWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FlushAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
              &lt;span class="p"&gt;}&lt;/span&gt;
              &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;streamWriter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FlushAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using the Custom FileResult in the Controller
&lt;/h2&gt;

&lt;p&gt;Now that we have the &lt;strong&gt;PusheenCsvResult&lt;/strong&gt; class, we can go ahead and use it in the controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt; &lt;span class="n"&gt;has&lt;/span&gt; &lt;span class="n"&gt;been&lt;/span&gt; &lt;span class="n"&gt;omitted&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;brevity&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="p"&gt;:)&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;FileResult&lt;/span&gt; &lt;span class="nf"&gt;ExportCsv&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_pusheenService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAllPusheens&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="s"&gt;"pusheen.csv"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="n"&gt;PusheenCsvResult&lt;/span&gt; &lt;span class="nf"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Pusheen&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pusheenData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fileDownloadName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PusheenCsvResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pusheenData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fileDownloadName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  App Demo
&lt;/h2&gt;

&lt;p&gt;Here's some screenshots of what it looks like from the front-end!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg1z9euq4gwwsqhpfalxu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg1z9euq4gwwsqhpfalxu.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff65oguxkv9sd6784436i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff65oguxkv9sd6784436i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fao0w1wonitnmztlclwl0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fao0w1wonitnmztlclwl0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb519ge6volnaea22dsz0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb519ge6volnaea22dsz0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;I hope you found this useful! I thought an improvement for this &lt;strong&gt;PusheenCsvResult&lt;/strong&gt; class would be to make it &lt;strong&gt;generic&lt;/strong&gt;, so that it can work with all kinds of datasets, not just the Pusheen dataset! That's for another day! :)&lt;/p&gt;

&lt;p&gt;Watch out for my next blog on unit testing the Custom FileResult which Exports Data into a CSV file Using Streaming in a .NET Core 3.1 MVC App. I have a series of .NET Core MVC blogs coming up, so it should be exciting times!&lt;/p&gt;

&lt;p&gt;Thank you for reading my blog! :)&lt;/p&gt;

&lt;h2&gt;
  
  
  Link to Github Repo
&lt;/h2&gt;

&lt;p&gt;You can find the link to my Github repo with the simple web app example containing the custom fileresult &lt;a href="https://github.com/kimdiep/pusheen-custom-fileresult-csv-export-aspnetcore" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>dotnet</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Intro to Docker Containers &amp; Microsoft Azure Part 1 - Beginner's Guide to Containerising a Hello World Python Web App</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Sat, 05 Oct 2019 11:44:51 +0000</pubDate>
      <link>https://dev.to/thekimmykola/intro-to-docker-containers-microsoft-azure-part-1-beginner-s-guide-to-containerising-a-hello-world-python-web-app-5eem</link>
      <guid>https://dev.to/thekimmykola/intro-to-docker-containers-microsoft-azure-part-1-beginner-s-guide-to-containerising-a-hello-world-python-web-app-5eem</guid>
      <description>&lt;h2&gt;
  
  
  Greetings!
&lt;/h2&gt;

&lt;p&gt;Hi everyone, it's great to be back again! This blog is part one of a two-part series on Docker and Microsoft Azure. In Part 1, we will containerise a Hello World Python web app using Docker. In Part 2, we will learn how to build and push the container image using devOps pipelines on Microsoft Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites:
&lt;/h2&gt;

&lt;p&gt;Before we get stuck in, here are some prerequisites:&lt;/p&gt;

&lt;h4&gt;
  
  
  Containers
&lt;/h4&gt;

&lt;p&gt;Here is a useful &lt;a href="https://www.docker.com/resources/what-container" rel="noopener noreferrer"&gt;link&lt;/a&gt; if you would like to have a quick 5 min intro to containers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Docker
&lt;/h4&gt;

&lt;p&gt;Docker is a set of platform-as-a-service products that use OS-level virtualization to deliver software in packages called containers. (Ref: &lt;a href="https://en.wikipedia.org/wiki/Docker_(software)" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Docker_(software)&lt;/a&gt;) &lt;/p&gt;

&lt;p&gt;It mitigates against the classic: "But it works on my machine problem!" and streamlines the development lifecycle by allowing developers to work in standardized environments using local containers which provide the applications and services. (Ref: &lt;a href="https://docs.docker.com/engine/docker-overview/" rel="noopener noreferrer"&gt;https://docs.docker.com/engine/docker-overview/&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Containers are great for continuous integration and continuous delivery (CI/CD) workflows. Did I mention we can even integrate it with Azure? ☁️&lt;/p&gt;

&lt;p&gt;You can get started on the Docker documentation &lt;a href="https://docs.docker.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Docker Desktop
&lt;/h4&gt;

&lt;p&gt;This blog assumes you have Docker Desktop Installed. To install Docker Desktop, you can use this &lt;a href="https://docs.docker.com/docker-for-mac/install/" rel="noopener noreferrer"&gt;link&lt;/a&gt;. I'm using my lovely Macbook Pro 💻 for this - hehe! 😉; but you can choose whether you want to download Docker for Mac or Windows.&lt;/p&gt;

&lt;p&gt;For this tutorial, you will need Python 3.7+ by going to the following &lt;a href="https://www.python.org/downloads/" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pip
&lt;/h4&gt;

&lt;p&gt;You will also need the latest version of pip which is a recommended tool for installing Python packages.&lt;/p&gt;

&lt;p&gt;To check you have the right Python and pip versions, you can use the commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;--version&lt;/span&gt;

pip &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcgi8nhxjr3tn90yx743n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcgi8nhxjr3tn90yx743n.png" alt="Checking Python and Pip Versions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Now, onto the fun stuff! 🏄‍♀️
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Step 1: Project Setup - Create a Project Directory
&lt;/h2&gt;

&lt;p&gt;First, let's create a new project directory called &lt;strong&gt;hi-there-docker&lt;/strong&gt;. Please feel free to call your project directory any name you want, but just remember to reference it throughout this blog.&lt;/p&gt;

&lt;p&gt;Open up the project directory in your favourite code editor. I find &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt; works quite well if you're starting out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Project Setup - File Setup
&lt;/h2&gt;

&lt;p&gt;Next, let's create a &lt;em&gt;requirements.txt&lt;/em&gt; file in the directory; it is good practice in Python projects to have this file to manage packages.&lt;/p&gt;

&lt;h4&gt;
  
  
  Top Tip! 💡
&lt;/h4&gt;

&lt;p&gt;If you are using Windows, you can create a function called 'touch' for the UNIX fans out there which enables you to use the touch command to create a new file in Windows Powershell. Enter the following command in Windows Powershell to enable this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="kr"&gt;function&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;touch&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;set-content&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Value&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;$null&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;em&gt;requirements.txt&lt;/em&gt; file, enter the package 'Flask==1.0.2', as we will need Flask to create the hello world application. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Feyx614wdgk5ytfu15waw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Feyx614wdgk5ytfu15waw.png" alt="requirements.txt"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, enter the following in the terminal to install the packages listed in &lt;em&gt;requirements.txt&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Python - Create a Hello World Flask App
&lt;/h2&gt;

&lt;p&gt;I won't be going into detail on how Flask works, but you should check it out if you're interested.&lt;/p&gt;

&lt;p&gt;We're now onto Step 3, let's move onto creating a new file called &lt;em&gt;main.py&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the main.py file, enter the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;flask&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Flask&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Flask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello World!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
   &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;0.0.0.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a very simple app and has one route with 'Hello world'.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2jovvfmq8sexpun11ees.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2jovvfmq8sexpun11ees.png" alt="main.py"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Create a Dockerfile
&lt;/h2&gt;

&lt;p&gt;Once that's complete, we can move onto Docker! Let's create a Dockerfile. The Dockerfile contains settings such as the base image for the container and Python version, as well as dependencies on build to produce the container image.&lt;/p&gt;

&lt;p&gt;Create a Dockerfile in the root directory of your project folder and enter the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;3.7&lt;/span&gt;
&lt;span class="n"&gt;COPY&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;
&lt;span class="n"&gt;WORKDIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;
&lt;span class="n"&gt;RUN&lt;/span&gt; &lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;txt&lt;/span&gt;
&lt;span class="n"&gt;EXPOSE&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;
&lt;span class="n"&gt;CMD&lt;/span&gt; &lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Dockerfile should look something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6a4vjoy3ll7c5iw63exb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F6a4vjoy3ll7c5iw63exb.png" alt="Dockerfile"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Let's Build the Image
&lt;/h2&gt;

&lt;p&gt;Before we can build the image using Docker, let's confirm the Docker CLI is working by typing the following into your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcmte1dafodjbvirq5v35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fcmte1dafodjbvirq5v35.png" alt="Checking Docker Version"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, check that Docker Desktop is up and running, there should be a cute little icon of the Docker whale on your desktop panel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fk37r63d4mhe94g5we15m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fk37r63d4mhe94g5we15m.png" alt="Docker Whal"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Now we are ready to build the image! 💿
&lt;/h3&gt;

&lt;p&gt;You can tag the image with a name of your choosing, but let's use the name &lt;strong&gt;hi-there-image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ensure you are in the root directory of the project and enter the following into the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;--tag&lt;/span&gt; hi-there-image &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fp43ppk4lu73igadcfpj1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fp43ppk4lu73igadcfpj1.png" alt="Building the Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🎉 You've built your first image using Docker and tagged it with a name - woohoo! 🎉
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Step 6: Running the Image as a Container
&lt;/h2&gt;

&lt;p&gt;Once the Docker image has been built, you are now ready to run the image as a container.&lt;/p&gt;

&lt;p&gt;Our container will be called:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;hi-there-container&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And our image name is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;hi-there-image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To start the application as a container, enter the following into the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; hi-there-container &lt;span class="nt"&gt;-p&lt;/span&gt; 5000:5000 hi-there-image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgawl0hxpypeoqrlqpbwm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fgawl0hxpypeoqrlqpbwm.png" alt="Running the Image as a Container"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🎈That's it! You are now running the image as a container! 🎈
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Step 7: Go to the App
&lt;/h2&gt;

&lt;p&gt;🥳 Now you can go to your app at &lt;a href="http://localhost:5000" rel="noopener noreferrer"&gt;http://localhost:5000&lt;/a&gt; 🥳&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkbtasmwfaozvzgwququp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fkbtasmwfaozvzgwququp.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Step: Viewing and Managing Containers using the Docker CLI
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#To display a list of running containers:&lt;/span&gt;
docker ps

&lt;span class="c"&gt;#To stop running one or more running containers:&lt;/span&gt;
docker container stop &lt;span class="o"&gt;[&lt;/span&gt;container name&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)]&lt;/span&gt;

&lt;span class="c"&gt;#For example, if we wanted to stop running the hi-there-container, we can run the following command in the terminal:&lt;/span&gt;
docker container stop hi-there-container

&lt;span class="c"&gt;#To remove one or more containers:&lt;/span&gt;
docker container &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;container name&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)]&lt;/span&gt;

&lt;span class="c"&gt;#For example, if we wanted to remove the hi-there-container, we can run the following command in the terminal:&lt;/span&gt;
docker container &lt;span class="nb"&gt;rm &lt;/span&gt;hi-there-container

&lt;span class="c"&gt;#To confirm that the container is no longer running, check that it is no longer in the list:&lt;/span&gt;
docker ps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  😊 Congratulations, you have just built and containerised a Hello World App using Docker! 😊
&lt;/h2&gt;

&lt;h2&gt;
  
  
  🤔 What's next?
&lt;/h2&gt;

&lt;p&gt;If you want to explore more on how to build and push the images using Docker as tasks within the Microsoft Azure Pipelines, watch out for Part 2 of this blog series. ☁️&lt;/p&gt;

</description>
      <category>docker</category>
      <category>azure</category>
      <category>devops</category>
      <category>python</category>
    </item>
    <item>
      <title>My First 3 Weeks as a Software Engineer Summarised in 10 Quotes and Emojis!👩‍💻</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Sun, 28 Jul 2019 16:41:37 +0000</pubDate>
      <link>https://dev.to/thekimmykola/my-first-3-weeks-as-a-software-engineer-summarised-in-10-quotes-and-emojis-267i</link>
      <guid>https://dev.to/thekimmykola/my-first-3-weeks-as-a-software-engineer-summarised-in-10-quotes-and-emojis-267i</guid>
      <description>&lt;h2&gt;
  
  
  Hi again! :)
&lt;/h2&gt;

&lt;p&gt;I just finished my first 3 weeks as a Software Engineer. Woohoo! Here is my experience so far in 10 quotes and emojis! 👩‍💻&lt;/p&gt;

&lt;h3&gt;
  
  
  1 👩‍💻🤩 "I'm so excited, I can't sleep!. 😴Hey, get to sleep already! You need to be fresh for tomorrow!" 👩‍💻🤩 "Awwww....but I'm too excited!"
&lt;/h3&gt;

&lt;h3&gt;
  
  
  2 💃"Oooo....how does a Microsoft Surface Pro even work? What's this flappy thing at the back?"
&lt;/h3&gt;

&lt;h3&gt;
  
  
  3 "Hello Microsoft Windows, haven't used you in a while!...Windows Update!!! 😂"
&lt;/h3&gt;

&lt;h3&gt;
  
  
  4 "🤓 C# is so cool!!!! I finally get to use a static programming language!"
&lt;/h3&gt;

&lt;h4&gt;
  
  
  *Goes to build solution = ERROR ; expected
&lt;/h4&gt;

&lt;h4&gt;
  
  
  AHHHHHHHHHHH!!!!!!! 👿
&lt;/h4&gt;

&lt;h3&gt;
  
  
  5 "Let's get this code out! Deployment, what can possibly go wrong with the build and deployment pipeline? 🚀"
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Deployment fails....arghhhhhh!!!!! 😡
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Goes into ultra mode to fix issue 💪
&lt;/h4&gt;

&lt;h4&gt;
  
  
  Deployment passed - yipppeeee!!! 😎
&lt;/h4&gt;

&lt;h3&gt;
  
  
  6 "It works, it actually works!!! Oh yeah!! Ice cream time!" 🍦🙌🏼😃
&lt;/h3&gt;

&lt;h3&gt;
  
  
  7 "I can figure this out....I can figure this out...should I ask for help? 🤔Nah, I can figure this out...I can figure this out....oh man....I NEEEDDD HELP!!! SOMEONE HELP!!"
&lt;/h3&gt;

&lt;h3&gt;
  
  
  8 "How have I not used Visual Studio IDE before? It's A-M-A-Z-I-N-G!!" 💻
&lt;/h3&gt;

&lt;h3&gt;
  
  
  9 "Am I meant to be here? I don't have a clue what's going on. Damn...I'm actually writing code!" 🎊
&lt;/h3&gt;

&lt;h3&gt;
  
  
  10 "Wow, I've learnt so much! How did all of this happen?" 😊
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;h4&gt;
  
  
  As you can see, a lot of ups and downs, but I'm absolutely loving it! :)
&lt;/h4&gt;

&lt;p&gt;Byeeeeeeee,&lt;/p&gt;

&lt;p&gt;Kim&lt;/p&gt;

</description>
      <category>career</category>
      <category>devops</category>
      <category>csharp</category>
    </item>
    <item>
      <title>I got my first ever job as a Software Engineer!!!</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Mon, 08 Jul 2019 06:20:46 +0000</pubDate>
      <link>https://dev.to/thekimmykola/i-got-my-first-ever-job-as-a-software-engineer-4l45</link>
      <guid>https://dev.to/thekimmykola/i-got-my-first-ever-job-as-a-software-engineer-4l45</guid>
      <description>&lt;p&gt;I GOT A JOB AS A SOFTWARE ENGINEER! 🥳🎊🥂🎈&lt;/p&gt;

&lt;p&gt;Today, I am so excited to announce my first ever role as an Associate Software Engineer at M&amp;amp;G Prudential! The career change has been an adventurous ride; dreams really do come true!&lt;/p&gt;

&lt;p&gt;I thought I would never be able to do this without a Computer Science degree, but I was proven wrong by the amazing tech community who supported me!&lt;/p&gt;

&lt;p&gt;If you're interested on hearing more about my career change, check out a Q&amp;amp;A on my Coding Journey &lt;a href="https://dev.to/thekimmykola/my-coding-journey-q-a-geography-graduate-to-software-engineer-fellowship-programme-makers-3c19"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Special Thanks!
&lt;/h2&gt;

&lt;p&gt;Thank you to all those who have been part of my tech journey so far! &lt;/p&gt;

&lt;p&gt;I also want to do a big shout out to EVORA Global, Makers, Codebar, Code First: Girls, Women Who Code, Girls in Tech, Inc., Tech for Good and Rails Girls for supporting my journey into tech!&lt;/p&gt;

&lt;h3&gt;
  
  
  EVORA Global
&lt;/h3&gt;

&lt;p&gt;My friends at the sustainability consultancy are a bunch of fantastic people, who inspired me to come into work everyday to do my best. After a year as a Junior Sustainability Consultant on the consulting team, I was given the opportunity to put forward some ideas to grow the company’s proprietary technology solution, which was focused on the sustainable real estate industry. The solution had a data-driven approach to support on environmental data management and reporting for commercial real estate sector clients.&lt;/p&gt;

&lt;p&gt;I’m so grateful that the company put its trust in me and offered me the chance to be part of their new technology team. It was pretty much a blank slate at the time and something felt ‘right’ about it. &lt;strong&gt;Though I hesitated to leave my sustainability consulting days behind, I was elated at the prospect of being part of something special.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For over 2 years, I grasped with the concept of Agile and engaged with the team on the software development of the sustainability software through the implementation of agile product/project management strategies, business requirements gathering and specification. I learned about scrum iterative software development and how to use Atlassian’s JIRA tool.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thank you EVORA for being part of my tech journey!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you haven’t heard of EVORA, definitely check out their website &lt;a href="https://evoraglobal.com/"&gt;here&lt;/a&gt;!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Code First: Girls
&lt;/h3&gt;

&lt;p&gt;In September 2017, I joined the Code First: Girls Web Development Beginner’s Course and never looked back again. I remembered dashing off after work an evening a week to the Twitter UK HQ, being utter exhausted, but felt so excited and energised to code. I had sessions once a week which covered so many things such as HTML, CSS, JavaScript, jQuery, GIT, GitHub collaboration, development concepts, Twitter Bootstrap and responsive web development and even had the chance to work on a group project.&lt;/p&gt;

&lt;p&gt;As soon as that ended, I enrolled onto the Code First: Girls Advanced Ruby Course, where I was introduced to Ruby programming, Sinatra framework, GET/POST requests, development concepts, automated emails using Mailgun, external APIs and deployments. I got to understand application deployment on Heroku cloud hosting services and explored the Twitter API.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thank you Code First: Girls! You really helped me to find my passion. As a Code First: Girls alumna, I feel like I could change the world!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you haven’t heard of &lt;a href="https://www.codefirstgirls.org.uk/"&gt;Code First: Girls&lt;/a&gt;, definitely check out their courses. They have free community courses and professional courses aimed at getting women into tech.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rails Girls London
&lt;/h3&gt;

&lt;p&gt;The 2-Day &lt;a href="http://railsgirls.com/"&gt;Rails Girls&lt;/a&gt; London Installation Party and event in December 2017 was cool beans! Held at Deliveroo, there were some inspiring lightning talks and coaching. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;There’s plenty of materials online too! Watch out for their next event!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Codebar London
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://codebar.io/"&gt;Codebar&lt;/a&gt; is growing so fast across the UK and the world. I have been a student as part of the Codebar London chapter for a while now. It’s been cool to meet everyone over good food and code! Yummy! &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thank you to all the coaches who have coached me so far, your workshops have been so insightful!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Technology for Good &amp;amp; Women Who Code London
&lt;/h3&gt;

&lt;p&gt;Going to talks through &lt;a href="https://www.meetup.com/"&gt;https://www.meetup.com/&lt;/a&gt; run by &lt;a href="http://www.techforgood.global/"&gt;Tech for Good&lt;/a&gt; and &lt;a href="https://www.womenwhocode.com/london"&gt;Women Who Code London&lt;/a&gt; really got me thinking about the application of coding for specific social causes. I’d recommend checking out their upcoming events!&lt;/p&gt;

&lt;h3&gt;
  
  
  Makers
&lt;/h3&gt;

&lt;p&gt;By the time I encountered &lt;a href="https://makers.tech/"&gt;Makers&lt;/a&gt; in late 2018, I was sure that Software Engineering was for me. I attended the &lt;strong&gt;Demo Day&lt;/strong&gt; events and was blown away by the projects created by the students there. The &lt;strong&gt;Intro Cohort&lt;/strong&gt; was a useful time for me to meet up with like-minded people and code together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entering Makers felt like home to me and I imagined myself there one day.&lt;/strong&gt; I actually looked at several coding bootcamps across the UK, but was deterred by the costs. Luckily, I came across the Fellowship Programme at Makers and applied! It was the best decision I had made. My interview was challenging; though it was one of the most enjoyable interviews I have ever had!&lt;/p&gt;

&lt;h3&gt;
  
  
  Girls in Tech London
&lt;/h3&gt;

&lt;p&gt;I went to a conference organised by &lt;a href="https://london.girlsintech.org/"&gt;Girls in Tech London&lt;/a&gt; during London Tech Week 2019 on the intersections of tech and benevolence. It was a thought-provoking &lt;a href="https://twitter.com/thekimmykola/status/1138907030956204040"&gt;evening&lt;/a&gt; and I left feeling inspired to hack my tech career!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thank you Girls in Tech London!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Onwards and upwards! 👩💻😍&lt;br&gt;
I'm so happpyyyyyy!!!&lt;/p&gt;

&lt;p&gt;Byeeeeeeee,&lt;/p&gt;

&lt;p&gt;Kim&lt;/p&gt;

</description>
      <category>career</category>
      <category>womenintech</category>
    </item>
    <item>
      <title>A Beginner's Checklist to Starting Your First Machine Learning Project</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Sun, 16 Jun 2019 16:38:04 +0000</pubDate>
      <link>https://dev.to/thekimmykola/a-beginner-s-checklist-to-starting-your-first-machine-learning-project-97d</link>
      <guid>https://dev.to/thekimmykola/a-beginner-s-checklist-to-starting-your-first-machine-learning-project-97d</guid>
      <description>&lt;p&gt;Thinking about setting up your first machine learning project and don't know where to start? This beginner's checklist will walk you through a step-by-step thought process to get you started!&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 1: Get a feel for what Machine Learning is all about :)
&lt;/h2&gt;

&lt;p&gt;I'm assuming you arrived on this blog because you've heard of the concept of Machine Learning (ML) and Artificial Intelligence (AI) and watched a couple of videos here and there!&lt;/p&gt;

&lt;p&gt;If you haven't done so already, you can explore more through watching some cool TED talks &lt;a href="https://www.ted.com/playlists/310/talks_on_artificial_intelligen"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can also explore an online course - there are many free courses available. You can check out this &lt;a href="https://eu.udacity.com/course/intro-to-machine-learning--ud120"&gt;one&lt;/a&gt; by Udacity on 'Intro to Machine Learning' 🤖.&lt;/p&gt;

&lt;p&gt;Don't worry about writing the code yet, just get a feel for what's happening in the Machine Learning world. Machine Learning is a concept within Artificial Intelligence (AI), as AI covers many fields. Here's a fantastic &lt;a href="https://medium.com/@chethankumargn/artificial-intelligence-definition-types-examples-technologies-962ea75c7b9b"&gt;blog&lt;/a&gt; if you would like to explore more about 'Machine Learning vs. Artificial Intelligence'. &lt;/p&gt;

&lt;p&gt;Ok, onto the next step! 😊 Don't worry about achieving something perfect the first time round, the best way to learn is to get stuck into a small project.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 2: Try out a small project!
&lt;/h2&gt;

&lt;p&gt;First things first, follow a tutorial to help you get started! Build something small to begin with and ask questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;'What does the data source look like?'&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;'How is the data being formatted?'&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;'What is the function of the code?'&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;'Why is this line of code here?'&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;'How is the machine learning model working?'&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;'How is this implemented in the code?'&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://scikit-learn.org/stable/auto_examples/classification/plot_digits_classification.html"&gt;This&lt;/a&gt; tutorial from Scikit-Learn is a good starting point to help you to get stuck in. The example shows how Scikit-Learn can be used to recognise images of hand-written digits. &lt;/p&gt;

&lt;p&gt;Experiment! Try changing the type of classifier and performance metrics to see if this makes a difference to the ability of your model to identify the handwritten digits.&lt;/p&gt;

&lt;p&gt;Congratulations! 🎉😎 You just built your first machine learning project! Take it easy ok, there's a lot to take in already.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 3: What's the problem you're trying to solve?
&lt;/h2&gt;

&lt;p&gt;Once you tried one or two example projects, you can start to tackle your very own one!  &lt;/p&gt;

&lt;p&gt;Here are some questions to help you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Is Machine Learning the right approach for your project?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Sketch out some ideas on your notebook and refine your idea. What questions are you trying to answer? What is your goal? Start small! Machine Learning may or may not be the right approach for your project, so before you invest a lot of time, share your idea around to sense check it is right for you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Are you trying to work with images? Are you working with numerical data?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Understand what kind of data you will be working with - this will guide you towards the appropriate solution for your problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 4: Data Acquisition and Understanding the Dataset
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Where are you going to get your dataset from?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before you can build the Machine Learning model, you need access to a dataset. For all projects, data acquisition is a very important step.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;How big is your dataset? Is it the best dataset for your project? Are there issues with the data?&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Delve into your dataset; understand it's structure. What is the format of the data? What are the key features of the dataset? Which parts of the dataset do you want to capture? Which bits are relevant? Is your dataset big enough?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;N.B. You may not need all of your dataset. Be aware of biases in the dataset sample itself!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wow! That's a big step out of the way, now onto choosing your model. :)&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 5: Which modelling approach is suitable for the domain you're working in?
&lt;/h2&gt;

&lt;p&gt;Are you going to let the model learn by itself (unsupervised learning), or are you going to guide the ML training through (supervised learning)? Hopefully from the previous steps, you should have a jist of the problem type. Is it a classification, regression, clustering problem or something else?&lt;/p&gt;

&lt;p&gt;Here's a cool &lt;a href="https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html"&gt;Machine Learning Map&lt;/a&gt; to help you decide.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 6: Data Processing and Formatting
&lt;/h2&gt;

&lt;p&gt;Ok, data is never in the form you want it to be...there will be some data processing and formatting to get the data in a form that's suitable for your machine learning project.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 7: Machine Learning
&lt;/h2&gt;

&lt;p&gt;There are so many options out there. Best to explore for yourself and pick what rocks your boat 🚣. &lt;a href="https://www.tensorflow.org/"&gt;Tensorflow&lt;/a&gt; and &lt;a href="https://keras.io/"&gt;Keras&lt;/a&gt; is a good combo, as well as &lt;a href="https://scikit-learn.org/stable/"&gt;Scikit-Learn&lt;/a&gt; :). There are pros and cons for the technologies you choose. If you want, you can even set up an online coding notebook like CoLab notebook 📔 (pretty much a Jupyter notebook for the Python fans out there), so you can experiment a bit. Did I mention you can run your machine learning using a GPU for super speedy stuff?&lt;/p&gt;

&lt;p&gt;If you want a quick run down on the techniques of Machine Learning, check out the &lt;a href="https://developers.google.com/machine-learning/crash-course/"&gt;crash course&lt;/a&gt; from Google.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 8: Data Splitting
&lt;/h2&gt;

&lt;p&gt;Once you have your dataset ready, a consideration is splitting your dataset into a training and a testing dataset. The training dataset is the dataset your ML model will train on; your testing dataset is the dataset your model will be tested against to check how well the model performs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Top Tip!&lt;/strong&gt; It is important to randomise the dataset before you split it, so the order of your dataset doesn't have a major impact on the model training process.&lt;/p&gt;

&lt;p&gt;There are many mathematical approaches to measure model performance; but it is important to be aware of model overfitting. This is when the model is too reliant on the data and biased to the training dataset.&lt;/p&gt;

&lt;p&gt;The rule of thumb for proportions is generally 90% of the dataset for training / 10% of the dataset for testing, but we have also seen 75% / 25% splits as well as 80%/ 20% splits.&lt;/p&gt;

&lt;h2&gt;
  
  
  ☑️ Step 9: Model Training
&lt;/h2&gt;

&lt;p&gt;Model training is the official term to mean "Run the Machine Learning model LOL! It's about time!"&lt;br&gt;
All the hard work so far has paid off! You are ready to train your model! Good luck! 👍&lt;/p&gt;

&lt;p&gt;Here is a non-exhaustive list of the things you may want to consider:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Where are you going to do the model training?&lt;/strong&gt; If your dataset is massive, you may consider how long the training process may take.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Consider doing test runs on a small sample of your dataset to check that your model can actually train!&lt;/strong&gt; Seriously, you don't want to be waiting around for ages and come back to find that there were bugs in the way you interfaced the data to the machine learning model! (Been there and done that LOL 😭)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;How many times is your model going to run through the training dataset?&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  ☑️ Step 10: Model Fitting &amp;amp; Model Tuning
&lt;/h2&gt;

&lt;p&gt;Once you have a trained machine learning model, check how well it performs by testing it against a test dataset (a fancy way of saying the "data your machine learning model has never seen before"). &lt;/p&gt;

&lt;p&gt;Have a think about how you measure the model performance. &lt;/p&gt;

&lt;p&gt;Here are some strategies to improve the performance of your machine learning model, beware of overfitting of course!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Go back to the data source! Is this the best data source for your model? Is there any pitfalls to your selected dataset. If not, maybe you can increase the sample size (how much data you're using).&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Try choosing another machine learning model algorithm and do a exercise to see which one yields the best result&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Play around with the proportion of data you set aside for training and testing&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Refine the training process: see if you can increase the number of times you run through a dataset, although this will slow down the training process&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;h4&gt;
  
  
  You totally rock! Give yourself a pat on the back! Congratulations on doing Machine Learning  🎉🎉🎉🎉🎉🎉🎈🙌
&lt;/h4&gt;

&lt;p&gt;Byeeeeeeee,&lt;/p&gt;

&lt;p&gt;Kim&lt;/p&gt;

</description>
      <category>machinelearning</category>
      <category>beginners</category>
    </item>
    <item>
      <title>My Coding Journey Q&amp;A - Geography graduate to Software Engineer - Fellowship Programme @ Makers</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Thu, 30 May 2019 15:47:21 +0000</pubDate>
      <link>https://dev.to/thekimmykola/my-coding-journey-q-a-geography-graduate-to-software-engineer-fellowship-programme-makers-3c19</link>
      <guid>https://dev.to/thekimmykola/my-coding-journey-q-a-geography-graduate-to-software-engineer-fellowship-programme-makers-3c19</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;“When I was 5, I got my first computer and wanted to be a computer hacker. I imagined myself working undercover as a secret agent, making potions and hacking through computers, like Disney’s Kim Possible saving the world from monsters!”&lt;/p&gt;

&lt;p&gt;This childhood feeling never really left me.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wanted to share my coding journey in the hope that it will inspire you to make your career change.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C9lhHuae--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/lzu5nhnldj8u7vw3fy7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C9lhHuae--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/lzu5nhnldj8u7vw3fy7n.png" alt="" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Kim, what are you up to nowadays?
&lt;/h2&gt;

&lt;p&gt;I’m currently living and working in London and drawing my business-technology role to a close. Psst…I have some amazing news to share; I’m about to become a &lt;strong&gt;Software Engineer as part of the Fellowship Programme at Makers.&lt;/strong&gt; I will be starting my Pre-Course on Monday 4th February 2019. Thanks to the Makers Fellowship Programme, I am about to embark on my childhood dream and being sponsored too! Big shout out to Makers for the fantastic work you guys are doing! &lt;strong&gt;I thought that dream was over a while ago, since I didn’t do a Computer Science degree. How wrong I was! The London tech community has been amazing and quickly debunked that myth.&lt;/strong&gt; Turns out, I never really stopped ‘coding’, it was just hiding within my climate/environmental modelling work during uni, my Microsoft Excel functions at work and my interest in computers waiting to be unlocked.  There is actually a lot in common between Geography and Software Engineering; the ability to break problems down into component parts and systems-thinking has helped me tremendously.&lt;/p&gt;

&lt;p&gt;Being out of my comfort zone for the Fellowship, I’m excited and nervous at the same time. I guess it’s natural given I’ll have new routines, new environments, the chance to meet new people and take on new concepts and ideas. It is quite sad to draw my current business-technology opportunities to a close for now and leave that chapter behind; though I am super hyped up to get stuck into my Software Engineering career!&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did you choose to study Geography at university? What did you do after graduation?
&lt;/h2&gt;

&lt;p&gt;I didn’t know what I wanted to do after college; 18 was a young age to make decisions and yes, it did feel like the end of the world at the time. Growing up, it was drilled into my brain that university was the &lt;em&gt;only&lt;/em&gt; logical option. I flipped between Medicine and Law and felt compelled to fit into the ‘ideal’ of what people expected from me. In the end, I chose Geography because I was curious to learn about what makes the world tick. I felt Geography had a good mix of arts and sciences shedding light to environmental, social, economic and technological interactions. As an alumna of Oxford and UCL, I graduated with my Bachelors in Geography (2014) and Masters of Science in Environmental Modelling (2015).&lt;/p&gt;

&lt;p&gt;After graduation, I still didn’t know what career was right for me; many of my friends took on great Graduate Schemes and were well-remunerated and at the time, I felt like somehow I had ‘failed’.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instead of comparing myself to others, I bounced back to forge my own path.&lt;/strong&gt; I eventually landed a full-time role as an Energy Industry Analyst and wrote loads of reports for a market intelligence company, whilst working at my part-time tutoring job too. My gut felt that job wasn’t for me and after 6 months, I moved onto a sustainability consultancy focused on accelerating the evolution and productivity of sustainable building management in cities, where I have stayed for the past 3 years.&lt;/p&gt;

&lt;h2&gt;
  
  
  When did you first encounter code?
&lt;/h2&gt;

&lt;p&gt;I wrote my first line of code whilst trying to find a better way to extract some climate data for my project in 2011; back then, coding was merely a tool for me to get to the final answer. In the past couple of years, I found myself wanting to know more about how something works rather than just receiving the end output.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does coding mean to you?
&lt;/h2&gt;

&lt;p&gt;Good question. Nowadays, I see coding as an art-form and a way of thinking - a philosophy. I never thought in a million years I would go to the Foyles book store out of curiosity to find “The Agile Samurai: How Agile Masters Deliver Great Software” book by Jonathan Rasmusson, which I used to support the introduction of Agile product and project management strategies to my company. To this day, I have been able to blend my skills from all aspects of life. I love consolidating my knowledge so far, improving my coding everyday and challenging myself! &lt;strong&gt;I am inspired to teach others to code one day and volunteer my skills for diversity and social mobility in the technology industry. I also see myself helping responsible businesses grow which aligns to my mission to use the power of coding and technology for instigating social, environmental and economic change.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What sparked you to make the career change to become a Software Engineer?
&lt;/h2&gt;

&lt;p&gt;Looking back to my quote at the beginning, I wanted to connect with my childhood self to get away from what my &lt;em&gt;mind&lt;/em&gt; thinks I should do, to seek what I &lt;em&gt;really&lt;/em&gt; wanted to do and link it to my passions. I’m passionate about sustainability and smart cities and how technology brings people and the environment together, changing how people perceive and inhabit their environment. At the same time, opportunities at work and curiosity to know more about the inner-workings of technology made me realise that a career in Software Engineering would be a good fit for me.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You can read on more below.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I tried to split it into two sections: opportunities at work and opportunities outside the 9-to-5, as I’m a big believer in enriching myself inside and outside of working hours.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Opportunities at Work
&lt;/h3&gt;

&lt;p&gt;My friends at the sustainability consultancy are a bunch of fantastic people, who inspired me to come into work everyday to do my best. After a year as a Junior Sustainability Consultant on the consulting team, I was given the opportunity to put forward some ideas to grow the company’s proprietary technology solution, which was focused on the sustainable real estate industry. The solution had a data-driven approach to support on environmental data management and reporting for commercial real estate sector clients.&lt;/p&gt;

&lt;p&gt;I’m so grateful that the company put its trust in me and offered me the chance to be part of their new technology team. It was pretty much a blank slate at the time and something felt ‘right’ about it. &lt;strong&gt;Though I hesitated to leave my sustainability consulting days behind, I was elated at the prospect of being part of something special.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For over 2 years, I grasped with the concept of Agile and engaged with the team on the software development of the sustainability software through the implementation of agile product/project management strategies, business requirements gathering and specification. I learned about scrum iterative software development and how to use Atlassian’s JIRA tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  It was awesomeness all round!
&lt;/h3&gt;

&lt;p&gt;With my multi-disciplinary background, I spoke both the language of business and technology. I wore many hats to bring together the details of the technology to something meaningful at the business level. &lt;strong&gt;I secretly enjoyed it whenever a bug appears, as it would mean I could have a chat with the developer to try and debug something and ask them questions.&lt;/strong&gt; I had loads of fun at work, everyone was very supportive and had good ideas to bring to the table. Wearing many hats was challenging but rewarding when you were transforming the way the user approached technology-driven sustainability. &lt;/p&gt;

&lt;p&gt;P.S. I also have a soft toy Angry Bird called ‘Yoda’ and a 'Pusheenosaurus'; they also attended some meetings too!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MCkYNo6o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/mbcm0efkfvfkrwak19ey.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MCkYNo6o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/mbcm0efkfvfkrwak19ey.jpg" alt="" width="800" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Opportunities outside of the 9-to-5
&lt;/h3&gt;

&lt;p&gt;I’m fortunate enough to have access to a lively technology community at my doorstep. There are so many great communities out there, here are some wonderful ones I got to know about:&lt;/p&gt;

&lt;h3&gt;
  
  
  Code First: Girls
&lt;/h3&gt;

&lt;p&gt;In September 2017, I joined the Code First: Girls Web Development Beginner’s Course and never looked back again. I remembered dashing off after work an evening a week to the Twitter UK HQ, being utter exhausted, but felt so excited and energised to code. I had sessions once a week which covered so many things such as HTML, CSS, JavaScript, jQuery, GIT, GitHub collaboration, development concepts, Twitter Bootstrap and responsive web development and even had the chance to work on a group project.&lt;/p&gt;

&lt;p&gt;As soon as that ended, I enrolled onto the Code First: Girls Advanced Ruby Course, where I was introduced to Ruby programming, Sinatra framework, GET/POST requests, development concepts, automated emails using Mailgun, external APIs and deployments. I got to understand application deployment on Heroku cloud hosting services and explored the Twitter API.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thank you Code First: Girls! You really helped me to find my passion. As a Code First: Girls alumna, I feel like I could change the world!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you haven’t heard of &lt;a href="https://www.codefirstgirls.org.uk/"&gt;Code First: Girls&lt;/a&gt;, definitely check out their courses. They have free community courses and professional courses aimed at getting women into tech.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Rails Girls London
&lt;/h3&gt;

&lt;p&gt;The 2-Day &lt;a href="http://railsgirls.com/"&gt;Rails Girls&lt;/a&gt; London Installation Party and event in December 2017 was cool beans! Held at Deliveroo, there were some inspiring lightning talks and coaching. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;There’s plenty of materials online too! Watch out for their next event!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Codebar London
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://codebar.io/"&gt;Codebar&lt;/a&gt; is growing so fast across the UK and the world. I have been a student as part of the Codebar London chapter for a while now. It’s been cool to meet everyone over good food and code! Yummy! &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thank you to all the coaches who have coached me so far, your workshops have been so insightful!&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Technology for Good &amp;amp; Women Who Code London
&lt;/h3&gt;

&lt;p&gt;Going to talks through &lt;a href="https://www.meetup.com/"&gt;https://www.meetup.com/&lt;/a&gt; run by &lt;a href="http://www.techforgood.global/"&gt;Tech for Good&lt;/a&gt; and &lt;a href="https://www.womenwhocode.com/london"&gt;Women Who Code London&lt;/a&gt; really got me thinking about the application of coding for specific social causes. I’d recommend checking out their upcoming events!&lt;/p&gt;

&lt;h3&gt;
  
  
  Makers
&lt;/h3&gt;

&lt;p&gt;By the time I encountered &lt;a href="https://makers.tech/"&gt;Makers&lt;/a&gt; in late 2018, I was sure that Software Engineering was for me. I attended the &lt;strong&gt;Demo Day&lt;/strong&gt; events and was blown away by the projects created by the students there. The &lt;strong&gt;Intro Cohort&lt;/strong&gt; was a useful time for me to meet up with like-minded people and code together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Entering Makers felt like home to me and I imagined myself there one day.&lt;/strong&gt; I actually looked at several coding bootcamps across the UK, but was deterred by the costs. Luckily, I came across the Fellowship Programme at Makers and applied! It was the best decision I had made. My interview was challenging; though it was one of the most enjoyable interviews I have ever had!&lt;/p&gt;

&lt;h2&gt;
  
  
  What advice can you give to someone wanting to change their career?
&lt;/h2&gt;

&lt;p&gt;Take the time to think about &lt;em&gt;why&lt;/em&gt; and &lt;em&gt;how&lt;/em&gt; you would like to change. Changing career is always risky and an opportunity cost; if you think it is worth it, make the jump and take the time you need to ease yourself in. Everyone is different, you know yourself better than anyone else. Change doesn’t happen overnight, you have to have &lt;strong&gt;grit&lt;/strong&gt; and &lt;strong&gt;patience&lt;/strong&gt; to see it through. If you fail at something, it’s natural to get frustrated, but get back up again. If it’s not right for you, then find something that makes you &lt;strong&gt;tick&lt;/strong&gt;. Successes are without failures; they go hand-in-hand. Remember to go easy on yourself and get plenty of rest! I speak from experience of burning out so many times! Most of all, there are some things which don't work out in life; c'est la vie!&lt;/p&gt;

&lt;p&gt;And that’s a wrap to my long-ass blog! I hope you found it useful.&lt;/p&gt;

&lt;p&gt;Byeeeeeeee,&lt;/p&gt;

&lt;p&gt;Kim&lt;/p&gt;

</description>
      <category>career</category>
      <category>womenintech</category>
    </item>
    <item>
      <title>Kim’s Top 5 Hacks for Bridging Business and Technology</title>
      <dc:creator>Kim Diep</dc:creator>
      <pubDate>Thu, 30 May 2019 15:43:16 +0000</pubDate>
      <link>https://dev.to/thekimmykola/kim-s-top-5-hacks-for-bridging-business-and-technology-10ac</link>
      <guid>https://dev.to/thekimmykola/kim-s-top-5-hacks-for-bridging-business-and-technology-10ac</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Yo yo yo, it’s me Kim and I’m here for my first ever techie blog post!&lt;/p&gt;

&lt;p&gt;Here are my top 5 hacks for bridging business and technology:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Hack #1 Assess what ‘value’ means to different people
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;’Value’ means different things to different people, so it’s important to establish a shared goal and vision in a way that everyone can understand.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Try to imagine yourself as a software developer, end-user, project manager, business stakeholder and investor etc. All of these people place emphasis on various types of things. Whilst the investor might be looking at the payback period from initial investment; the developer may be focusing on technology feasibility, executing designs and how data flows work for example. The end-user on the other hand may be drawn to ease of use and a fantastic user experience. &lt;/p&gt;

&lt;p&gt;Something as simple as tweaking the use of language from &lt;strong&gt;‘I’&lt;/strong&gt; to &lt;strong&gt;‘We’&lt;/strong&gt; creates a team mentality where &lt;em&gt;everyone&lt;/em&gt; participates. At the end of the day, there will be trade-offs, but that’s ok as long as everyone is focused on a shared goal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hack #2 Recognise that technology can’t solve everything
&lt;/h2&gt;

&lt;p&gt;Technology is far from perfect! That’s why it’s absolutely fine to feel frustrated when something doesn’t work out according to plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The best solutions are those which blend technology and people; reminding us of the importance of the ‘human’ in technology.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Hack #3 Don’t focus too much on getting a perfect Agile software &amp;amp; product development process. Communication is the key!
&lt;/h2&gt;

&lt;p&gt;Agile is commonplace nowadays and its popularity owing to business requirements to react quickly to changing ideas and concepts across young and growing industries. However, many teams get bogged down by the Agile software &amp;amp; product development process itself. It is natural for teams to create extra structures around Agile in an attempt to have some control and seek reassurance from what is an inherently fast-paced process. Relevant documentation is important in Agile software &amp;amp; product development, but too much irrelevant documentation can be overwhelming and not so useful, the opposite of what Agile is all about. I experienced this myself when I spent a little bit too long perfecting my presentation and doing tweaks here and there at the expense of actually speaking to someone in the first place! When I found the courage to draw a line under my work and take action, it was way more effective. This might seem mind-numbingly obvious, but in practice we all need to be constantly reminded.&lt;/p&gt;

&lt;p&gt;In truth, Agile does not look the same across organisations. The idea here is to look beyond agile and focus on the people. As I mentioned earlier in Hack #2, the best solutions are those which blend technology and people.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M-2hjaUJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/t9z8972xupxwbwf9we3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M-2hjaUJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/t9z8972xupxwbwf9we3d.png" alt="" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Communication doesn’t necessary mean talking until the sun goes down; but being mindful of the context to spark a conversation to bring different personalities and working styles together. This means creating the space for ideas to be fleshed out and enabling everyone to verbalise their thoughts in written and spoken forms.&lt;/p&gt;

&lt;p&gt;Personally, this is something I have been focusing on, as I can be quick to share my ideas. I want to be mindful about what I say and when I say things. The world can be quick to idealise extroverts, but introverts need to be heard too! Definitely, check out Susan Cain’s book, ‘Quiet: The Power of Introverts in a World That Can't Stop Talking’, if you haven’t done so already.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hack #4 Don’t strive for perfection; embrace successes and failures
&lt;/h2&gt;

&lt;p&gt;This is a hard one I know! As a perfectionist myself, this is something I’m getting better at day-by-day. Successes are without failures; they go hand-in-hand. Identify successes and celebrate them with your team. I absolutely love emojis and using &lt;a href="https://slack.com/"&gt;Slack&lt;/a&gt; which is a team messaging platform to say ‘thank you’ and mention successes. You can create your own emojis to personalise things even more! In the same vain, it is cool to talk about failures too, be open about them and take forward key learnings. A good example is the ‘sprint retrospective’ which is a great way for development teams to reflect on: what went well; what didn’t go so well and how the team can improve next time.&lt;/p&gt;

&lt;p&gt;Defining what success means and mapping onto goals is crucial. Something which may appear impossible, might just need breaking down into bitesize chunks. Setting ambitious goals are great, but ensure they’re realistic and achievable. At the end of the day, success is what you make of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hack #5 Get a team plushie! Live out mindfulness &amp;amp; fun as a team!
&lt;/h2&gt;

&lt;p&gt;We’re all humans and not robots, so don’t take things too seriously. Having mindfulness and fun as a team means respecting each other, having humility and looking beyond the status quo by challenging others in a positive and thoughtful way. Positive teams are those where positive thinking manifests itself within human interactions. Seriously, everyone loves a plushie to brighten up their day!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CgZFw_7y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ltgjkg91q1iwnf8uo9gf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CgZFw_7y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/ltgjkg91q1iwnf8uo9gf.png" alt="" width="800" height="547"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That concludes my first blog post on business-technology hacks. I could go on for quite a while, so let’s take it to the floor to hear some of your hacks.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://undraw.co/"&gt;undraw&lt;/a&gt; for providing the awesome images used in this blog post.&lt;/p&gt;

&lt;p&gt;Byeeeeeeee,&lt;/p&gt;

&lt;p&gt;Kim&lt;/p&gt;

</description>
      <category>agile</category>
      <category>womenintech</category>
    </item>
  </channel>
</rss>
