[{"data":1,"prerenderedAt":788},["ShallowReactive",2],{"/en-us/blog/hiring-in-the-deep-end-of-the-talent-pool":3,"navigation-en-us":37,"banner-en-us":436,"footer-en-us":446,"blog-post-authors-en-us-PJ Metz":686,"blog-related-posts-en-us-hiring-in-the-deep-end-of-the-talent-pool":701,"assessment-promotions-en-us":738,"next-steps-en-us":778},{"id":4,"title":5,"authorSlugs":6,"body":8,"categorySlug":9,"config":10,"content":14,"description":8,"extension":25,"isFeatured":12,"meta":26,"navigation":27,"path":28,"publishedDate":20,"seo":29,"stem":33,"tagSlugs":34,"__hash__":36},"blogPosts/en-us/blog/hiring-in-the-deep-end-of-the-talent-pool.yml","Hiring In The Deep End Of The Talent Pool",[7],"pj-metz",null,"careers",{"slug":11,"featured":12,"template":13},"hiring-in-the-deep-end-of-the-talent-pool",false,"BlogPost",{"title":15,"description":16,"authors":17,"heroImage":19,"date":20,"body":21,"category":9,"tags":22},"DevOps hiring from the deep end of the talent pool","Time to broaden your search beyond four-year tech degrees to candidates with life experience, self-taught/bootcamp chops, and soft skills.",[18],"PJ Metz","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749663743/Blog/Hero%20Images/three-things-i-learned-in-my-first-month-at-gitlab.jpg","2022-02-01","\n\nWhen it comes to DevOps hiring, many companies have only waded into the shallow end of the pool to find talent. They’ve relied on a steady stream of university graduates rather than being a little more creative in their search and realizing that many DevOps professionals are created outside of traditional four-year institutions. So let’s explore the DevOps hiring opportunities that await in the deep end of the talent pool. \n\n## Non-traditional paths\n\nWhile four-year degrees are wonderful – the dream of a college education should be available to all who want it – the reality is there are a variety of barriers to attending college. For instance, many people don’t realize the opportunity within tech until later in their life, after they’ve already earned a different degree or have been working for several years in a different field. To get their DevOps skills, they pursue an alternative route such as bootcamps or teaching themselves. In fact, non collegiate paths are increasingly common; according to a report by Hired, 45% of software engineers have a computer science degree, but 24% are self-taught, and another 10% learned how to code through a bootcamp program.\n\n### DevOps bootcamps\n\nBootcamps offer rigorous and thorough training on a very specific set of tech-related skills such as full-stack web development, data science, and UX/UI design. These virtual or in-person programs are full-time or part-time, and there are many bootcamps available all over the world. Bootcamps are appealing because of their affordable cost and shorter time investment, compared to earning a four-year degree.\n\nOrganizations aiming to train their engineering teams like bootcamps because they can focus exclusively on skills needed for the job, modern frameworks and languages, and real-world applications, making their graduates well-versed in building today’s apps. \n\n### Self-taught DevOps\n\nDevelopers often learn to code while working in another career. Former educators, EMTs, and office managers everywhere are dedicating time outside of their professions to learning to write code and build apps.\n\nSelf-taught developers are an asset to a company because they have the discipline to learn tough concepts on their own and find ways to apply them. This is something that many other avenues of learning don’t offer. Because they had to find their own way, self-taught developers often have unique perspectives and the ability to problem-solve that are valuable to teams at all levels of tech. \n\nDevOps is a unique career in that proving what you know is incredibly important. So when it's time for DevOps hiring, don’t exclude these other paths. Where someone learned isn’t as important as what they learned — or what they can build. So when you’re hiring, or creating a bot that chooses which resumes and applications to move forward with, make sure you’re not [getting rid of qualified candidates](https://www.forbes.com/sites/jackkelly/2021/09/07/harvard-business-school-study-says-software-overlooks-millions-of-qualified-job-candidates-heres-how-to-fight-back-against-the-bots/?sh=5a0f1ff813d3). \n\n## Why non-traditional?\n\nWorkers with non-tech backgrounds bring a lot to the table that should be considered along with their skill sets.\n\n### Diversify the knowledge\n\nPeople who choose non-traditional routes to tech are often people who have already been working at a professional level in another career. When you hire someone who took a different path to tech than college, you can benefit from their expertise as well as their experience from their former career. For instance, a former teacher brings the ability to present information and explain new concepts – both skills are essential in DevOps. Similarly, an office manager would know how to manage several different projects at once and understand how to work well within teams. \n\nIf diversity is important to your company, as it should be to every company, then looking beyond hiring only candidates with computer science degrees will help you to find that talent. Statistically speaking, [women and people of color are currently heavily under-represented in computer science programs across the U.S.](https://www.dukechronicle.com/article/2020/06/major-madness-racial-and-gender-equity-in-computer-science), so they are likely to have other experiences such as bootcamps or be self-taught that would still qualify them for some of your DevOps hiring needs.   \n\n### Soft skills \n\nJust as important as technical skills are interpersonal skills, a.k.a. soft skills. [Teamwork, collaboration, and communication](/blog/soft-skills-are-the-key-to-your-devops-career-advancement/) are sometimes dismissed as secondary or unimportant compared to the candidate’s ability to write code. However, these skills are essential when working within a team and across an organization. Because [team-based work is central](/blog/future-proof-your-developer-career/#embrace-the-soft-skills) to implementing DevOps strategies, you should be hiring people with great soft skills to reduce friction. It is beneficial to the company to have a professional who can communicate with the lines of business and the C-suite about projects and goals. A college grad may have had internships and work experience, but a marketing designer or restaurant manager who has been in their respective businesses for 10 years already knows how to navigate a deadline-oriented workplace and communicate requirements to other stakeholders. \n\nAs you assemble your DevOps hiring strategy, don’t close yourself off to the idea of a non-traditional candidate. You might be surprised at how much they will enhance the dynamics of your DevOps team.\n",[23,9,24],"DevOps","community","yml",{},true,"/en-us/blog/hiring-in-the-deep-end-of-the-talent-pool",{"title":15,"description":16,"ogTitle":15,"ogDescription":16,"noIndex":12,"ogImage":19,"ogUrl":30,"ogSiteName":31,"ogType":32,"canonicalUrls":30},"https://about.gitlab.com/blog/hiring-in-the-deep-end-of-the-talent-pool","https://about.gitlab.com","article","en-us/blog/hiring-in-the-deep-end-of-the-talent-pool",[35,9,24],"devops","YTm3klry8eIubbhkhqGBW1AciTvgS7AXqiRPNmWQq5U",{"data":38},{"logo":39,"freeTrial":44,"sales":49,"login":54,"items":59,"search":366,"minimal":397,"duo":416,"pricingDeployment":426},{"config":40},{"href":41,"dataGaName":42,"dataGaLocation":43},"/","gitlab logo","header",{"text":45,"config":46},"Get free trial",{"href":47,"dataGaName":48,"dataGaLocation":43},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com&glm_content=default-saas-trial/","free trial",{"text":50,"config":51},"Talk to sales",{"href":52,"dataGaName":53,"dataGaLocation":43},"/sales/","sales",{"text":55,"config":56},"Sign in",{"href":57,"dataGaName":58,"dataGaLocation":43},"https://gitlab.com/users/sign_in/","sign in",[60,87,182,187,287,347],{"text":61,"config":62,"cards":64},"Platform",{"dataNavLevelOne":63},"platform",[65,71,79],{"title":61,"description":66,"link":67},"The intelligent orchestration platform for DevSecOps",{"text":68,"config":69},"Explore our Platform",{"href":70,"dataGaName":63,"dataGaLocation":43},"/platform/",{"title":72,"description":73,"link":74},"GitLab Duo Agent Platform","Agentic AI for the entire software lifecycle",{"text":75,"config":76},"Meet GitLab Duo",{"href":77,"dataGaName":78,"dataGaLocation":43},"/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":80,"description":81,"link":82},"Why GitLab","See the top reasons enterprises choose GitLab",{"text":83,"config":84},"Learn more",{"href":85,"dataGaName":86,"dataGaLocation":43},"/why-gitlab/","why gitlab",{"text":88,"left":27,"config":89,"link":91,"lists":95,"footer":164},"Product",{"dataNavLevelOne":90},"solutions",{"text":92,"config":93},"View all Solutions",{"href":94,"dataGaName":90,"dataGaLocation":43},"/solutions/",[96,120,143],{"title":97,"description":98,"link":99,"items":104},"Automation","CI/CD and automation to accelerate deployment",{"config":100},{"icon":101,"href":102,"dataGaName":103,"dataGaLocation":43},"AutomatedCodeAlt","/solutions/delivery-automation/","automated software delivery",[105,109,112,116],{"text":106,"config":107},"CI/CD",{"href":108,"dataGaLocation":43,"dataGaName":106},"/solutions/continuous-integration/",{"text":72,"config":110},{"href":77,"dataGaLocation":43,"dataGaName":111},"gitlab duo agent platform - product menu",{"text":113,"config":114},"Source Code Management",{"href":115,"dataGaLocation":43,"dataGaName":113},"/solutions/source-code-management/",{"text":117,"config":118},"Automated Software Delivery",{"href":102,"dataGaLocation":43,"dataGaName":119},"Automated software delivery",{"title":121,"description":122,"link":123,"items":128},"Security","Deliver code faster without compromising security",{"config":124},{"href":125,"dataGaName":126,"dataGaLocation":43,"icon":127},"/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[129,133,138],{"text":130,"config":131},"Application Security Testing",{"href":125,"dataGaName":132,"dataGaLocation":43},"Application security testing",{"text":134,"config":135},"Software Supply Chain Security",{"href":136,"dataGaLocation":43,"dataGaName":137},"/solutions/supply-chain/","Software supply chain security",{"text":139,"config":140},"Software Compliance",{"href":141,"dataGaName":142,"dataGaLocation":43},"/solutions/software-compliance/","software compliance",{"title":144,"link":145,"items":150},"Measurement",{"config":146},{"icon":147,"href":148,"dataGaName":149,"dataGaLocation":43},"DigitalTransformation","/solutions/visibility-measurement/","visibility and measurement",[151,155,159],{"text":152,"config":153},"Visibility & Measurement",{"href":148,"dataGaLocation":43,"dataGaName":154},"Visibility and Measurement",{"text":156,"config":157},"Value Stream Management",{"href":158,"dataGaLocation":43,"dataGaName":156},"/solutions/value-stream-management/",{"text":160,"config":161},"Analytics & Insights",{"href":162,"dataGaLocation":43,"dataGaName":163},"/solutions/analytics-and-insights/","Analytics and insights",{"title":165,"items":166},"GitLab for",[167,172,177],{"text":168,"config":169},"Enterprise",{"href":170,"dataGaLocation":43,"dataGaName":171},"/enterprise/","enterprise",{"text":173,"config":174},"Small Business",{"href":175,"dataGaLocation":43,"dataGaName":176},"/small-business/","small business",{"text":178,"config":179},"Public Sector",{"href":180,"dataGaLocation":43,"dataGaName":181},"/solutions/public-sector/","public sector",{"text":183,"config":184},"Pricing",{"href":185,"dataGaName":186,"dataGaLocation":43,"dataNavLevelOne":186},"/pricing/","pricing",{"text":188,"config":189,"link":191,"lists":195,"feature":274},"Resources",{"dataNavLevelOne":190},"resources",{"text":192,"config":193},"View all resources",{"href":194,"dataGaName":190,"dataGaLocation":43},"/resources/",[196,229,247],{"title":197,"items":198},"Getting started",[199,204,209,214,219,224],{"text":200,"config":201},"Install",{"href":202,"dataGaName":203,"dataGaLocation":43},"/install/","install",{"text":205,"config":206},"Quick start guides",{"href":207,"dataGaName":208,"dataGaLocation":43},"/get-started/","quick setup checklists",{"text":210,"config":211},"Learn",{"href":212,"dataGaLocation":43,"dataGaName":213},"https://university.gitlab.com/","learn",{"text":215,"config":216},"Product documentation",{"href":217,"dataGaName":218,"dataGaLocation":43},"https://docs.gitlab.com/","product documentation",{"text":220,"config":221},"Best practice videos",{"href":222,"dataGaName":223,"dataGaLocation":43},"/getting-started-videos/","best practice videos",{"text":225,"config":226},"Integrations",{"href":227,"dataGaName":228,"dataGaLocation":43},"/integrations/","integrations",{"title":230,"items":231},"Discover",[232,237,242],{"text":233,"config":234},"Customer success stories",{"href":235,"dataGaName":236,"dataGaLocation":43},"/customers/","customer success stories",{"text":238,"config":239},"Blog",{"href":240,"dataGaName":241,"dataGaLocation":43},"/blog/","blog",{"text":243,"config":244},"Remote",{"href":245,"dataGaName":246,"dataGaLocation":43},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":248,"items":249},"Connect",[250,255,259,264,269],{"text":251,"config":252},"GitLab Services",{"href":253,"dataGaName":254,"dataGaLocation":43},"/services/","services",{"text":256,"config":257},"Community",{"href":258,"dataGaName":24,"dataGaLocation":43},"/community/",{"text":260,"config":261},"Forum",{"href":262,"dataGaName":263,"dataGaLocation":43},"https://forum.gitlab.com/","forum",{"text":265,"config":266},"Events",{"href":267,"dataGaName":268,"dataGaLocation":43},"/events/","events",{"text":270,"config":271},"Partners",{"href":272,"dataGaName":273,"dataGaLocation":43},"/partners/","partners",{"backgroundColor":275,"textColor":276,"text":277,"image":278,"link":282},"#2f2a6b","#fff","Insights for the future of software development",{"altText":279,"config":280},"the source promo card",{"src":281},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758208064/dzl0dbift9xdizyelkk4.svg",{"text":283,"config":284},"Read the latest",{"href":285,"dataGaName":286,"dataGaLocation":43},"/the-source/","the source",{"text":288,"config":289,"lists":291},"Company",{"dataNavLevelOne":290},"company",[292],{"items":293},[294,299,305,307,312,317,322,327,332,337,342],{"text":295,"config":296},"About",{"href":297,"dataGaName":298,"dataGaLocation":43},"/company/","about",{"text":300,"config":301,"footerGa":304},"Jobs",{"href":302,"dataGaName":303,"dataGaLocation":43},"/jobs/","jobs",{"dataGaName":303},{"text":265,"config":306},{"href":267,"dataGaName":268,"dataGaLocation":43},{"text":308,"config":309},"Leadership",{"href":310,"dataGaName":311,"dataGaLocation":43},"/company/team/e-group/","leadership",{"text":313,"config":314},"Team",{"href":315,"dataGaName":316,"dataGaLocation":43},"/company/team/","team",{"text":318,"config":319},"Handbook",{"href":320,"dataGaName":321,"dataGaLocation":43},"https://handbook.gitlab.com/","handbook",{"text":323,"config":324},"Investor relations",{"href":325,"dataGaName":326,"dataGaLocation":43},"https://ir.gitlab.com/","investor relations",{"text":328,"config":329},"Trust Center",{"href":330,"dataGaName":331,"dataGaLocation":43},"/security/","trust center",{"text":333,"config":334},"AI Transparency Center",{"href":335,"dataGaName":336,"dataGaLocation":43},"/ai-transparency-center/","ai transparency center",{"text":338,"config":339},"Newsletter",{"href":340,"dataGaName":341,"dataGaLocation":43},"/company/contact/#contact-forms","newsletter",{"text":343,"config":344},"Press",{"href":345,"dataGaName":346,"dataGaLocation":43},"/press/","press",{"text":348,"config":349,"lists":350},"Contact us",{"dataNavLevelOne":290},[351],{"items":352},[353,356,361],{"text":50,"config":354},{"href":52,"dataGaName":355,"dataGaLocation":43},"talk to sales",{"text":357,"config":358},"Support portal",{"href":359,"dataGaName":360,"dataGaLocation":43},"https://support.gitlab.com","support portal",{"text":362,"config":363},"Customer portal",{"href":364,"dataGaName":365,"dataGaLocation":43},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":367,"login":368,"suggestions":375},"Close",{"text":369,"link":370},"To search repositories and projects, login to",{"text":371,"config":372},"gitlab.com",{"href":57,"dataGaName":373,"dataGaLocation":374},"search login","search",{"text":376,"default":377},"Suggestions",[378,380,384,386,390,394],{"text":72,"config":379},{"href":77,"dataGaName":72,"dataGaLocation":374},{"text":381,"config":382},"Code Suggestions (AI)",{"href":383,"dataGaName":381,"dataGaLocation":374},"/solutions/code-suggestions/",{"text":106,"config":385},{"href":108,"dataGaName":106,"dataGaLocation":374},{"text":387,"config":388},"GitLab on AWS",{"href":389,"dataGaName":387,"dataGaLocation":374},"/partners/technology-partners/aws/",{"text":391,"config":392},"GitLab on Google Cloud",{"href":393,"dataGaName":391,"dataGaLocation":374},"/partners/technology-partners/google-cloud-platform/",{"text":395,"config":396},"Why GitLab?",{"href":85,"dataGaName":395,"dataGaLocation":374},{"freeTrial":398,"mobileIcon":403,"desktopIcon":408,"secondaryButton":411},{"text":399,"config":400},"Start free trial",{"href":401,"dataGaName":48,"dataGaLocation":402},"https://gitlab.com/-/trials/new/","nav",{"altText":404,"config":405},"Gitlab Icon",{"src":406,"dataGaName":407,"dataGaLocation":402},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":404,"config":409},{"src":410,"dataGaName":407,"dataGaLocation":402},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":412,"config":413},"Get Started",{"href":414,"dataGaName":415,"dataGaLocation":402},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/compare/gitlab-vs-github/","get started",{"freeTrial":417,"mobileIcon":422,"desktopIcon":424},{"text":418,"config":419},"Learn more about GitLab Duo",{"href":420,"dataGaName":421,"dataGaLocation":402},"/gitlab-duo/","gitlab duo",{"altText":404,"config":423},{"src":406,"dataGaName":407,"dataGaLocation":402},{"altText":404,"config":425},{"src":410,"dataGaName":407,"dataGaLocation":402},{"freeTrial":427,"mobileIcon":432,"desktopIcon":434},{"text":428,"config":429},"Back to pricing",{"href":185,"dataGaName":430,"dataGaLocation":402,"icon":431},"back to pricing","GoBack",{"altText":404,"config":433},{"src":406,"dataGaName":407,"dataGaLocation":402},{"altText":404,"config":435},{"src":410,"dataGaName":407,"dataGaLocation":402},{"title":437,"button":438,"config":443},"See how agentic AI transforms software delivery",{"text":439,"config":440},"Watch GitLab Transcend now",{"href":441,"dataGaName":442,"dataGaLocation":43},"/events/transcend/virtual/","transcend event",{"layout":444,"icon":445},"release","AiStar",{"data":447},{"text":448,"source":449,"edit":455,"contribute":460,"config":465,"items":470,"minimal":675},"Git is a trademark of Software Freedom Conservancy and our use of 'GitLab' is under license",{"text":450,"config":451},"View page source",{"href":452,"dataGaName":453,"dataGaLocation":454},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":456,"config":457},"Edit this page",{"href":458,"dataGaName":459,"dataGaLocation":454},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":461,"config":462},"Please contribute",{"href":463,"dataGaName":464,"dataGaLocation":454},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":466,"facebook":467,"youtube":468,"linkedin":469},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[471,518,570,614,641],{"title":183,"links":472,"subMenu":487},[473,477,482],{"text":474,"config":475},"View plans",{"href":185,"dataGaName":476,"dataGaLocation":454},"view plans",{"text":478,"config":479},"Why Premium?",{"href":480,"dataGaName":481,"dataGaLocation":454},"/pricing/premium/","why premium",{"text":483,"config":484},"Why Ultimate?",{"href":485,"dataGaName":486,"dataGaLocation":454},"/pricing/ultimate/","why ultimate",[488],{"title":489,"links":490},"Contact Us",[491,494,496,498,503,508,513],{"text":492,"config":493},"Contact sales",{"href":52,"dataGaName":53,"dataGaLocation":454},{"text":357,"config":495},{"href":359,"dataGaName":360,"dataGaLocation":454},{"text":362,"config":497},{"href":364,"dataGaName":365,"dataGaLocation":454},{"text":499,"config":500},"Status",{"href":501,"dataGaName":502,"dataGaLocation":454},"https://status.gitlab.com/","status",{"text":504,"config":505},"Terms of use",{"href":506,"dataGaName":507,"dataGaLocation":454},"/terms/","terms of use",{"text":509,"config":510},"Privacy statement",{"href":511,"dataGaName":512,"dataGaLocation":454},"/privacy/","privacy statement",{"text":514,"config":515},"Cookie preferences",{"dataGaName":516,"dataGaLocation":454,"id":517,"isOneTrustButton":27},"cookie preferences","ot-sdk-btn",{"title":88,"links":519,"subMenu":528},[520,524],{"text":521,"config":522},"DevSecOps platform",{"href":70,"dataGaName":523,"dataGaLocation":454},"devsecops platform",{"text":525,"config":526},"AI-Assisted Development",{"href":420,"dataGaName":527,"dataGaLocation":454},"ai-assisted development",[529],{"title":530,"links":531},"Topics",[532,537,542,545,550,555,560,565],{"text":533,"config":534},"CICD",{"href":535,"dataGaName":536,"dataGaLocation":454},"/topics/ci-cd/","cicd",{"text":538,"config":539},"GitOps",{"href":540,"dataGaName":541,"dataGaLocation":454},"/topics/gitops/","gitops",{"text":23,"config":543},{"href":544,"dataGaName":35,"dataGaLocation":454},"/topics/devops/",{"text":546,"config":547},"Version Control",{"href":548,"dataGaName":549,"dataGaLocation":454},"/topics/version-control/","version control",{"text":551,"config":552},"DevSecOps",{"href":553,"dataGaName":554,"dataGaLocation":454},"/topics/devsecops/","devsecops",{"text":556,"config":557},"Cloud Native",{"href":558,"dataGaName":559,"dataGaLocation":454},"/topics/cloud-native/","cloud native",{"text":561,"config":562},"AI for Coding",{"href":563,"dataGaName":564,"dataGaLocation":454},"/topics/devops/ai-for-coding/","ai for coding",{"text":566,"config":567},"Agentic AI",{"href":568,"dataGaName":569,"dataGaLocation":454},"/topics/agentic-ai/","agentic ai",{"title":571,"links":572},"Solutions",[573,575,577,582,586,589,593,596,598,601,604,609],{"text":130,"config":574},{"href":125,"dataGaName":130,"dataGaLocation":454},{"text":119,"config":576},{"href":102,"dataGaName":103,"dataGaLocation":454},{"text":578,"config":579},"Agile development",{"href":580,"dataGaName":581,"dataGaLocation":454},"/solutions/agile-delivery/","agile delivery",{"text":583,"config":584},"SCM",{"href":115,"dataGaName":585,"dataGaLocation":454},"source code management",{"text":533,"config":587},{"href":108,"dataGaName":588,"dataGaLocation":454},"continuous integration & delivery",{"text":590,"config":591},"Value stream management",{"href":158,"dataGaName":592,"dataGaLocation":454},"value stream management",{"text":538,"config":594},{"href":595,"dataGaName":541,"dataGaLocation":454},"/solutions/gitops/",{"text":168,"config":597},{"href":170,"dataGaName":171,"dataGaLocation":454},{"text":599,"config":600},"Small business",{"href":175,"dataGaName":176,"dataGaLocation":454},{"text":602,"config":603},"Public sector",{"href":180,"dataGaName":181,"dataGaLocation":454},{"text":605,"config":606},"Education",{"href":607,"dataGaName":608,"dataGaLocation":454},"/solutions/education/","education",{"text":610,"config":611},"Financial services",{"href":612,"dataGaName":613,"dataGaLocation":454},"/solutions/finance/","financial services",{"title":188,"links":615},[616,618,620,622,625,627,629,631,633,635,637,639],{"text":200,"config":617},{"href":202,"dataGaName":203,"dataGaLocation":454},{"text":205,"config":619},{"href":207,"dataGaName":208,"dataGaLocation":454},{"text":210,"config":621},{"href":212,"dataGaName":213,"dataGaLocation":454},{"text":215,"config":623},{"href":217,"dataGaName":624,"dataGaLocation":454},"docs",{"text":238,"config":626},{"href":240,"dataGaName":241,"dataGaLocation":454},{"text":233,"config":628},{"href":235,"dataGaName":236,"dataGaLocation":454},{"text":243,"config":630},{"href":245,"dataGaName":246,"dataGaLocation":454},{"text":251,"config":632},{"href":253,"dataGaName":254,"dataGaLocation":454},{"text":256,"config":634},{"href":258,"dataGaName":24,"dataGaLocation":454},{"text":260,"config":636},{"href":262,"dataGaName":263,"dataGaLocation":454},{"text":265,"config":638},{"href":267,"dataGaName":268,"dataGaLocation":454},{"text":270,"config":640},{"href":272,"dataGaName":273,"dataGaLocation":454},{"title":288,"links":642},[643,645,647,649,651,653,655,659,664,666,668,670],{"text":295,"config":644},{"href":297,"dataGaName":290,"dataGaLocation":454},{"text":300,"config":646},{"href":302,"dataGaName":303,"dataGaLocation":454},{"text":308,"config":648},{"href":310,"dataGaName":311,"dataGaLocation":454},{"text":313,"config":650},{"href":315,"dataGaName":316,"dataGaLocation":454},{"text":318,"config":652},{"href":320,"dataGaName":321,"dataGaLocation":454},{"text":323,"config":654},{"href":325,"dataGaName":326,"dataGaLocation":454},{"text":656,"config":657},"Sustainability",{"href":658,"dataGaName":656,"dataGaLocation":454},"/sustainability/",{"text":660,"config":661},"Diversity, inclusion and belonging (DIB)",{"href":662,"dataGaName":663,"dataGaLocation":454},"/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":328,"config":665},{"href":330,"dataGaName":331,"dataGaLocation":454},{"text":338,"config":667},{"href":340,"dataGaName":341,"dataGaLocation":454},{"text":343,"config":669},{"href":345,"dataGaName":346,"dataGaLocation":454},{"text":671,"config":672},"Modern Slavery Transparency Statement",{"href":673,"dataGaName":674,"dataGaLocation":454},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":676},[677,680,683],{"text":678,"config":679},"Terms",{"href":506,"dataGaName":507,"dataGaLocation":454},{"text":681,"config":682},"Cookies",{"dataGaName":516,"dataGaLocation":454,"id":517,"isOneTrustButton":27},{"text":684,"config":685},"Privacy",{"href":511,"dataGaName":512,"dataGaLocation":454},[687],{"id":688,"title":689,"body":8,"config":690,"content":692,"description":8,"extension":25,"meta":696,"navigation":27,"path":697,"seo":698,"stem":699,"__hash__":700},"blogAuthors/en-us/blog/authors/pj-metz.yml","Pj Metz",{"template":691},"BlogAuthor",{"name":18,"config":693},{"headshot":694,"ctfId":695},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659488/Blog/Author%20Headshots/gitlab-logo-extra-whitespace.png","PjMetz",{},"/en-us/blog/authors/pj-metz",{},"en-us/blog/authors/pj-metz","SgW84Gu-lPq0zFzhy1aT23bZjx9kWViDG_WXzCPn04E",[702,716,728],{"content":703,"config":714},{"title":704,"description":705,"authors":706,"heroImage":708,"date":709,"body":710,"category":9,"tags":711},"Shadow programs give employees a peek into leadership roles","Shadow programs are a great resource if you’re looking to explore new roles, expand your skill set, or learn how decisions are made.",[707],"Fatima Sarah Khalid","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749683055/Blog/Hero%20Images/ideaabstract.jpg","2023-07-17","\nHave you ever wished you could see into your manager's mind or understand the nitty-gritty details that make your organization run smoothly? Well, that's exactly what corporate shadow programs can do for you. They enable you to tag along with senior colleagues during regular workdays. You can witness how they tackle tasks, make decisions, and interact with various stakeholders. It's like getting a peek behind the scenes of your organization.\n\nAt GitLab, we host several shadow programs, including one that lets you [learn from GitLab CEO and co-founder Sid Sijbrandij](https://handbook.gitlab.com/handbook/ceo/shadow/). Each program aims to give team members a deeper understanding of different parts of our company's operations and processes. The experience empowers individuals to connect their work to the company's broader goals and gain valuable skills for their professional growth. Shadow programs benefit mentees, mentors, and organizations.\n\nThe following are some benefits of a shadow program:\n* [Insight into decision-making processes](#insight-into-decision-making-processes)\n* [Collaboration with leadership teams](#collaboration-with-leadership-teams)\n* [Personalized learning opportunities](#personalized-learning-opportunities)\n* [Cross-functional interactions](#cross-functional-interactions)\n\n## Insight into decision-making processes\nShadow programs can act as your backstage pass to the operational aspects of your organization. As you gain more insight into how your organization works and how decisions are made, you may start to appreciate the complexity that goes into keeping things running. Knowing how all the pieces work together will improve how you collaborate. At GitLab, shadows are able to observe [GitLab values](https://handbook.gitlab.com/handbook/values/) in action: Collaboration, Results, Efficiency, Diversity, Inclusion & Belonging, and Transparency.\n\n> From the perspective of operating the company on a daily basis, I was witness to how decisions were made at the leadership level of the organization. There were e-group meetings in which different topics were discussed, from mergers and acquisitions and sales compensation plans to hiring and team member morale. I was impressed by the camaraderie, collaboration, and great rapport among members of the e-group. Decisions were taken only after a thorough discussion had taken place and everyone was encouraged to participate.\n- *[Cesar Saavedra](https://gitlab.com/csaavedra1), [Being a GitLab CEO Shadow](https://www.linkedin.com/pulse/being-gitlab-ceo-shadow-cesar-saavedra/)*\n\n## Collaboration with leadership teams\nMembers of your executive team can sometimes feel like distant figures in your organization. Shadow programs put employees together with executives and other leaders, making them feel more approachable. This connection not only strengthens bonds across various departments and cultivates a positive work environment, but it can also inspire the shadowing employees to feel confident enough to pursue leadership positions themselves.\n\n> The CEO shadow program is such a great way to give team members insight into how the company works, while also making the company feel more inclusive, and its top-level team members feel more approachable. While I’ve always found Sid to be friendly and down to earth, I know that some people are afraid of approaching their manager with something, let alone someone at or near the top. I somewhat jokingly said to someone that it’s a good reminder that our executives are 'real' people.\n- *[Cynthia Ng](https://gitlab.com/cynthia), [Reflection on my CEO shadow rotation at GitLab](https://cynthiang.ca/2022/01/07/reflection-on-my-ceo-shadow-rotation-at-gitlab/)*\n\n## Personalized learning opportunities\nShadow programs at GitLab offer personalized learning opportunities. You can learn on the job from experienced team members, oftentimes from those with roles above yours. The experience is incredibly valuable, as seen from many of the reflections that GitLab team members have written about their shadow program experiences. The program fosters open communication, creating a pathway for better knowledge sharing across teams.\n\nShadowing also provides an opportunity for employees to be exposed to new situations and learn new skills.\n\n> In this meeting, a variety of different vice presidents and engineering managers discussed error budgets, reliability, and security. The [service-level agreement] requirements, security issues, and corrective actions were discussed. We went over what issues are currently affecting our error budgets and must be remediated. Root causes were analyzed and then a plan was made for remediation. This has shown me the efficiency of having all the information on a single document and then discussing proposals to correct. This makes the meeting flow much easier than not having any data beforehand.\n- *[Fernando Diaz](https://gitlab.com/fjdiaz), [What I learned as a Development Director Shadow at GitLab](https://awkwardferny.medium.com/what-i-learned-as-an-engineering-director-shadow-at-gitlab-1a783cb564d0)*\n\n## Cross-functional interactions\nWith a shadow program in another department or role, you will get the opportunity to experience work outside of your immediate team circle. The exposure can help broaden your understanding of the overall organization and how other teams work. You can develop new skills that prepare you for future opportunities. The relationships you build as a shadow across different groups will also stay with you after the program.\n\n> As an open-source contributor, I had some understanding of how GitLab worked. But during the shadowing week, I got to see the inner workings of the company, how teams collaborate, and how the company operates at scale.\n- *[Siddharth Asthana](https://gitlab.com/edith007), [My experience as a GitLab Hero in Developer Director Shadow Program](https://www.linkedin.com/pulse/my-experience-gitlab-hero-developer-director-shadow-program-asthana/)*\n\n## How to start a shadow program\nHere are some tips to help you start a shadow program at your organization:\n* Set clear expectations and guidelines for the program\n* Arrange flexible schedules that suit both the mentee and the mentor\n* Encourage open discussion and feedback\n* Ensure the program is tailored to meet the needs of participants\n* Implement confidentiality guidelines to protect sensitive information\n* Define the tasks for the participants, such as note-taking or updating the handbook\n* Determine the time commitment of rotations\n* Create opportunities for shadows to contribute such as helping to complete tasks\n\nCheck out our shadow programs for examples of how to structure them:\n* [CEO Shadow Program](https://handbook.gitlab.com/handbook/ceo/shadow/)\n* [Support Shadow Program](https://handbook.gitlab.com/handbook/support/#support-shadow-program)\n* [Director of Development Shadow Program](https://handbook.gitlab.com/handbook/ceo/shadow/)\n* [CFO Shadow Program](https://handbook.gitlab.com/handbook/finance/growth-and-development/cfo-shadow-program/)\n\nMore resources:\n* [15 tips to succeed at GitLab's CEO Shadow program](https://about.gitlab.com/blog/get-the-most-out-of-a-ceo-shadow-program/)\n* [CEO Shadow program impressions and takeaways](https://about.gitlab.com/blog/ceo-shadow-impressions-takeaways/)\n* [The engineering director shadow experience at GitLab](https://about.gitlab.com/blog/engineering-director-shadow/)\n\n\n\n\n",[9,712,713],"growth","inside GitLab",{"slug":715,"featured":12,"template":13},"benefits-of-corporate-shadow-programs",{"content":717,"config":726},{"title":718,"description":719,"authors":720,"heroImage":721,"date":722,"body":723,"category":9,"tags":724},"Learn Python with Pj! Part 5 - Build a hashtag tracker with the Twitter API","Our Education Evangelist Pj Metz wraps up his five-part series with this penultimate tutorial.",[18],"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749664962/Blog/Hero%20Images/python.jpg","2022-06-01","\nThis is the fifth and final installment in the Learn Python with Pj! series. Make sure to read:\n- [Part 1 - Getting started](/blog/learn-python-with-pj-part-1/)\n- [Part 2 - Lists and loops](/blog/learn-python-with-pj-part-2/)\n- [Part 3 - Functions and strings](/blog/learn-python-with-pj-part-3/)\n- [Part 4 - Dictionaries and Files](/blog/learn-python-with-pj-part-4-dictionaries-and-files/)\n\n## Putting it all together\nI’ve completed my Python course on [Codecademy](https://codecademy.com/), and am excited to put the skills I learned into building something practical. I’ve worked with the Twitter API before; I wrote a few bots in Node.js to make them tweet and respond to tweets they’re tagged in. I thought it’d be fun to work with the API again, but this time do it in Python. I didn’t just want to make another bot, so I had to figure out something else. In this case, I made a bot that can track hashtags being used in real time on Twitter.\n\nHere’s [my repo](https://gitlab.com/MetzinAround/python-hashtagger) containing a few different files, but `live_tweets.py` is what we’ll focus on for this blog. Let’s talk about how I built it and what it does. \n\n```python\nimport tweepy\nimport config\n\nauth = tweepy.OAuth1UserHandler(config.consumer_key, config.consumer_secret, config.access_token, config.access_token_secret\n)\n\napi = tweepy.API(auth) \n\n#prints the text of the tweet using hashtag designated in stream.filter(track=[])\nclass LogTweets(tweepy.Stream):\n        def on_status(self, status):\n                date = status.created_at\n                username = status.user.screen_name\n                \n                try:\n                        tweet = status.extended_tweet[\"full_text\"]\n                except AttributeError:\n                        tweet = status.text\n\n                print(\"**Tweet info**\")\n                print(f\"Date: {date}\")\n                print(f\"Username: {username}\")\n                print(f\"Tweet: {tweet}\")\n                print(\"*********\")\n                print(\"********* \\n\")\n\n              \n\nif __name__ == \"__main__\":         \n        #creates instance of LogTweets with authentication\n        stream = LogTweets(config.consumer_key, config.consumer_secret, config.access_token, config.access_token_secret)\n\n\n        #hashtags as str in list will be watched live on twitter. \n        hashtags = []\n        print(\"Looking for Hashtags...\")\n        stream.filter(track=hashtags)\n\n```\n\nHere’s how this all works. First, we import two modules: [Tweepy](https://www.tweepy.org/) and config. Tweepy is a wrapper that makes using the Twitter API very easy. Config allows us to use config files and keep our secrets safe. This is important since using the Twitter API involves four keys that are specific to your Twitter developer account. Getting these keys is covered in this Twitter [documentation](https://developer.twitter.com/en/docs/twitter-api/getting-started/getting-access-to-the-twitter-api). We’ll talk about what’s in the config file and how it works later. \n\nThe next line defines the variable `auth` using tweepy’s built in authorization handler. Normally, you’d put in the keys directly here, but since we’re trying to keep secrets safe, we handle those through the config file. In order to call those variables hosted in the config file, we type `config.variable_name`. Finally, in order to access the tweepy api, we create the variable `api` with the auth variable from the line above passed into `tweepy.API()`. Now, the variable `api` will give us access to all the features in Tweepy’s Twitter API library. \n\n> You’re invited! Join us on June 23rd for the [GitLab 15 launch event](https://page.gitlab.com/fifteen) with DevOps guru Gene Kim and several GitLab leaders. They’ll show you what they see for the future of DevOps and The One DevOps Platform.\n\nFor our purposes, we want to find a hashtag being used, then collect the tweet that used it and print some information about the tweet to the console. To make this happen, we’ve created a class called `LogTweets` that takes an input `tweepy.Stream`. Stream is a Twitter API term that refers to all of the tweets being posted on Twitter at any given moment. Think of it as opening a window looking out onto every single tweet as it’s posted. We have to make this open connection in order to be able to find tweets that are using our hashtag. Inside `LogTweets`, we define a function called `on_status` with the parameters `self` and `status`. `On_status` will be called when a status is detected in the stream. `Self` is required as the first parameter in any class function, and `status` in this function will be referring to the status posted by a Twitter user, often called a tweet.\n\nIn our case, we’re going with status because `tweet` will represent the text of the status itself. We define `date` and `username` using Tweepy documentation: `created_at` is the date and `user.screen_name` is the username of the person who posted the status.\n\nNext is a `try/except` block. Try/except is a concept that works similarly to an if statement, but it allows for error handling a little bit better. It essentially says, “Try this, but if there’s a problem, do this instead.” In this case, we try to define the variable `tweet` as `.extended_tweet[“full_text”]`. This checks if the status we’re working with has the `extended_tweet` attribute. Twitter used to be limited to 140 characters, and when they increased the limit to 280, the `extended_tweet` became necessary.\n\nNow, if you want to capture the full tweet, you need the `extended_tweet` attribute. Inside of that attribute is the key `full_text`. Longer tweets will need that full_text or it will cut off at the 140 character limit. This `try` command checks if that key exists; if it does, `tweet` is equal to that full text.\n\nHowever, if an `AttributeError` happens, we just grab the regular text and set it equal to the variable `tweet`. Next, we print some info to the terminal. Whenever this function is called, the six lines will print to the console with the variables created above replaced by whatever status info was passed in. This makes it easier to keep track of what we’re looking at in the terminal. \n\nNext, we have an important if statement: `if __name__ == \"__main__\":`. This is used to indicate what happens when the file is run. Basically, files in Python receive a property called `__name__` from the compiler. The file that is called to be run directly is called `__main__`. Other files not run are given names equal to the file name. Therefore, anything under this if statement will only run if the file is being called directly by the compiler. \n\nNext, we create an instance of `LogTweets` called `stream`. We pass in the authentication information from the config file just like we did for the `auth` variable in the beginning of the code. This “opens up” the stream and we are now looking at all the tweets being sent in real time. In order to narrow our search, we need something to look for. The variable `hashtags` is an empty list that must be populated with strings of the hashtags we’re looking to track. This list will be put into the keyword `track` in a few lines. \n\n`Track` is an important keyword for the stream. It tells the instance what word we are looking for, input as a list of strings. These words can show up in any form, so it’s very broad.  If we didn’t put the hashtag in front of it, it would simply look for that word no matter where it showed up, so we might have too many results. By looking for hashtags, we narrow our search only to people using that specific hashtag, not just the word wherever it is. To search for terms, you have to put them into the list as a string before running the code. \n\nWhen the code is run by typing `python3 live_tweets.py` into the terminal, this is what the output looks like in the terminal.\n\n![Output in terminal](https://about.gitlab.com/images/blogimages/pythonwithpj5.png){: .shadow}\n\n\nThat’s it! That’s how the bot works, but we still need to talk about `config.py` and why we used it before. Here’s the contents of the file: \n\n```python\nimport os\nfrom dotenv import load_dotenv\n\nload_dotenv()\nconsumer_key = os.getenv(\"consumer_key\")\nconsumer_secret = os.getenv(\"consumer_secret\")\naccess_token = os.getenv(\"access_token\")\naccess_token_secret = os.getenv(\"access_token_secret\")\n```\n\nI tricked you! This doesn’t have the keys there either! Using `import os` and `import dotenv import load_dotenv` gives us access to something very important to keep secret keys safe: environmental variables. An environmental variable can be set in many different places, but in this case, our local repo has a file called `.env` that holds the actual keys.\n\nThis is there so I can test the app and run it on my machine. To use it somewhere else, you’d have to have environmental variables set up to hold the keys for the Twitter API. When I run my bots on Heroku, I keep the keys in the settings so it has access to the keys it needs to run. I use a `.gitignore` file that keeps my `.env` file from being committed to GitLab. \n\nAs you can see, the variables in `config.py` are set to `os.getenv(“name_of_key”)`. When we import `config.py` as `import config`, we gain access to these variables by calling `config.name_of_variable` in our main file. \n\nSo, for now, that’s what I built! It’s not much and I pieced it together using a lot of documentation from Twitter and Tweepy as well as a few tutorials and plenty of Stackoverflow, but it got built and it works the way I want it to!\n\nI’ve really enjoyed learning Python online and writing about it for everyone who has been reading it. I encourage anyone learning a new language or skill to write about it; it has really helped solidify my learning, and who knows, maybe I’ve helped someone else understand something in Python as well. \n\n",[9,725,712],"tutorial",{"slug":727,"featured":12,"template":13},"learn-python-with-pj-part-5-building-something-with-the-twitter-api",{"content":729,"config":736},{"title":730,"description":731,"authors":732,"heroImage":721,"date":733,"body":734,"category":9,"tags":735},"Learn Python with Pj! Part 4 - Dictionaries and Files","Our education evangelist Pj Metz continues his journey to learn how to code in Python.",[18],"2022-05-05","This is the fourth installment in the Learn Python with Pj! series. Make sure to read:\n- [Part 1 - Getting started](/blog/learn-python-with-pj-part-1/)\n- [Part 2 - Lists and loops](/blog/learn-python-with-pj-part-2/)\n- [Part 3 - Functions and strings](/blog/learn-python-with-pj-part-3/)\n- [Part 5 - Build a hashtag tracker with the Twitter API](/blog/learn-python-with-pj-part-5-building-something-with-the-twitter-api/)\n\nI’ve learned a lot with Python so far, but when I learned dictionaries (sometimes shortened to dicts), I was really excited about what could be done. A dictionary in Python is a series of keys and values stored inside a single object. This is kind of like a super array; one that allows you to connect keys and values together in a single easily accessible source. Creating dictionaries from arrays can actually be very simple, too.\n\nIn this blog, I'll dig into how to create dictionaries and how to read and write files in the code.\n\n## Dictionaries\n\nDictionaries in Python are indicated by using curly braces, or as I like to call them, mustaches. `{ }` indicates that the list you’re looking at isn’t a list at all, but a dictionary. \n\n```python\nshows_and _characters = {\n    \"Bojack Horseman\": \"Todd\",\n    \"My Hero Academia\": \"Midoriya\"\n    \"Ozark\": \"Ruth\"\n    \"Arrested Development\": \"Tobias\",\n    \"Derry Girls\": \"Sister Michael\",\n    \"Tuca & Bertie\": \"Bertie\"\n    }\n\n```\n\nThis is a dictionary of my favorite TV shows and my favorite characters in that show. In this example, the key is on the left and the value is on the right. To access dictionaries, you use a similar call like you would for a list, except instead of an element number, you would put the key. `print(shows_and_characters[“Ozark”])` would print `Ruth` to the console. Additionally, both the key and value in this example are strings, but that’s not a requirement. Keys can be any immutable type, like strings, ints, floats, and tuples. Values don’t have this same restriction, therefore values can be a nested dictionary or a list, in addition to the types mentioned for keys. For instance, the following dictionary is a valid dictionary.\n\n```python\nshows_with_lists = {\n    \"Bojack Horseman\": [\"Todd\", \"Princess Carolyn\", \"Judah\", \"Diane\"],\n    \"My Hero Academia\": [\"Midoriya\", \"Shoto\", \"All Might\", \"Bakugo\", \"Kirishima\"],\n    \"Ozark\": [\"Ruth\", \"Jonah\", \"Wyatt\"],\n    \"Arrested Development\": [\"Tobias\", \"Gob\", \"Anne\", \"Maeby\"],\n    \"Derry Girls\": [\"Sister Michael\", \"Orla\", \"Erin\", \"Claire\", \"James\"],\n    \"Tuca & Bertie\": [\"Bertie\", \"Speckle\", \"Tuca\", \"Dakota\"]\n    }\n\n```\nIn this example, each value is a list. So if we tried to print the value for the key `”Derry Girls”`, we would see `[“Sister Michael”, “Orla”, “Erin”, “Claire”, “James”]` printed to the console. However, if we wanted the last element in the value list, we’d write `shows_with_lists[“Derry Girls”] [-1]`. This would print the last element in the list, which in this case is `James`. \n\nDictionaries can be written manually, or, if you have two lists, you can combine the `dict()` and `zip()` methods to make the lists into a dictionary. \n\n```python\nlist_of_shows = [\"Bojack Horseman\",\n                 \"My Hero Academia\",\n                 \"Ozark\",\n                 \"Arrested Development\",\n                 \"Derry Girls\",\n                 \"Tuca & Bertie\"]\nlist_of_characters = [[\"Todd\", \"Princess Carolyn\", \"Judah\", \"Diane\"],\n                      [\"Midoriya\", \"Shoto\", \"All Might\", \"Bakugo\", \"Kirishima\"],\n                      [\"Ruth\", \"Jonah\", \"Wyatt\"],\n                      [\"Tobias\", \"Gob\", \"Anne\", \"Maeby\"],\n                      [\"Sister Michael\", \"Orla\", \"Erin\", \"Claire\", \"James\"],\n                      [\"Bertie\", \"Speckle\", \"Tuca\", \"Dakota\"]]\n\ncombined_shows_characters = dict(zip(list_of_shows, list_of_characters))\n\nprint(combined_shows_characters)\n```\n\nThis is one way to create a dictionary. Another is called Dictionary Comprehension. This one is a little more work, but can be used in a variety of different ways, including using a bit of logic on a single list to generate a dictionary using that original list. Here’s how with two examples: one based on the above lists, and one with a single list and some logic. \n\n```python\nimport math\n\n#This is doing the same work as the above example, but using Dict Comprehension instead. \ncomprehension_shows_characters = { shows:characters for shows, characters in zip(list_of_shows, list_of_characters)  }\n\nhip_to_be_square = [4, 9, 16, 25, 36, 49]\n\nno_longer_hip_to_be_square = { key:math.sqrt(key) for key in hip_to_be_square }\n\nprint(no_longer_hip_to_be_square)\n```\n\nIn the `no_longer_hip_to_be_square` dictionary, the key is found in the `hip_to_be_square` list. The value for each key is its own square root, brought in with the import math function. There are plenty more useful methods for dealing with dictionaries [here](https://realpython.com/python-dicts/). \n\n## Reading and writing files\n\nThis one is a pretty cool part of Python: reading and writing other files right in the code. With Python, you’re able to take the contents of certain types of files and use it in your code, or even create a new file based on some input. This is useful for data handling and can be used with a  variety of file types. The two I’ll be covering here are .csv and .txt.\n\n### Reading from a file\n\nImagine a .txt file named `best-ever.txt` containing the line `My favorite tv show is Derry Girls`. We can use Python to take that line and turn it into a variable. Running the following code would print the contents of the .txt file to the terminal. \n\n```python\nwith open(\"best-ever.txt\") as text_file:\n  text_data = text_file.read()\n\n#This will print the contents of the .txt file. \nprint(text_data)\n```\n\nBy using `with open(NAME OF FILE) as VARIABLE_NAME:`, we can examine the contents of files as a single string. If the document has multiple lines, you can even separate those by iterating over them by using a for loop and the `.readlines()` method. Using an imaginary .txt document called `buncha-lines` we could use the following to print out each line individually.\n\n```python\nwith open(\"buncha-lines.txt\") as lines_doc:\n  for line in lines_doc.readlines():\n    print(line)\n\n``` \n### Writing a new file\n\nCreating a new file is also easy with Python. The `open()` function can take an additional argument in order to create a new file. In fact, there’s a default argument that’s been being passed each time without us knowing! `r` is the default argument for `open()` and puts it in read mode. To turn on write mode, pass in a `w` as the second argument. The following code will write a brand-new file called `best_tv_character.txt` with the contents `Peggy Olson from Mad Men`. \n\n```python\nwith open(\"best_tv_character.txt\", \"w\") as best_character:\n  best_character.write(\"Peggy Olson from Mad Men\")\n\n```\n### Working with .csv files\n\nYou can read a .csv file with Python by using `import csv` at the beginning of the file, and then using some of its built-in methods in the code. However, even though .csv files are plain text, treating a .csv file the same as you treat .txt files can lead to difficult to read outputs; after all, the point of a spreadsheet is to table information. Without that table, the output can be chaotic. A way around this is to use the `dictreader()` method. This method allows you to map the information in each row to a dictionary with field names you can create. The default field names are collected from the first row of the .csv if no field names are given. Imagine a .csv file with columns labeled, “Network”, “Show name”, “Seasons”. Maybe we just want to print the number of seasons from this .csv. \n\n```python\nimport csv \n\nwith open(\"shows.csv\") as shows_csv:\n  shows_dict = csv.DictReader(shows_csv)\n  for row in shows_dict:\n    print(row[\"Seasons\"])\n\n```\n\nThis would print to the console, on a new line, the number of seasons for each row that exists in the .csv. \n\nJust like with .txt files, you can also create .csv files with Python. It’s a bit more complicated since you need to define the headers, or column names, but it is still a quick process. This can be used to take lists and turn them into .csv files. Let’s check out the following example:\n\n```python\nimport csv\n\nworking_list = [{\"Network\": \"Netflix\", \"Show Name\":\"Bojack Horseman\", \"Seasons\":6}, {\"Network\":\"Channel 4\",\"Show Name\":\"Derry Girls\", \"Seasons\": 3}, {\"Network\":\"HBO Max\", \"Show Name\":\"Our Flag Means Death\", \"Seasons\": 1}]\n\n\nwith open(\"shows.csv\", \"w\") as shows_csv:\n    fields = [\"Network\", \"Show Name\", \"Seasons\"]\n    shows_w = csv.DictWriter(shows_csv, fieldnames = fields)\n\n    shows_w.writeheader()\n    for item in working_list:\n        shows_w.writerow(item)\n\n```\n\nThis previous code block creates a brand-new csv file by using the `”w”` parameter in `open()`. We manually name the fields in the order they appear in a separate list, then pass that list into the `DictWriter` parameter `fieldnames`. Finally, we use the `writeheader()` and a for loop with the `writerow()` methods to create a header row and to iterate over the `working_list` and turn each entry into a row in the .csv. \n\nThese are only a few ways to work with .csv and .txt files; Python is very versatile and more information [can be found here](https://realpython.com/working-with-files-in-python/).\n",[9,725,712],{"slug":737,"featured":12,"template":13},"learn-python-with-pj-part-4-dictionaries-and-files",{"promotions":739},[740,754,766],{"id":741,"categories":742,"header":744,"text":745,"button":746,"image":751},"ai-modernization",[743],"ai-ml","Is AI achieving its promise at scale?","Quiz will take 5 minutes or less",{"text":747,"config":748},"Get your AI maturity score",{"href":749,"dataGaName":750,"dataGaLocation":241},"/assessments/ai-modernization-assessment/","modernization assessment",{"config":752},{"src":753},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":755,"categories":756,"header":758,"text":745,"button":759,"image":763},"devops-modernization",[757,554],"product","Are you just managing tools or shipping innovation?",{"text":760,"config":761},"Get your DevOps maturity score",{"href":762,"dataGaName":750,"dataGaLocation":241},"/assessments/devops-modernization-assessment/",{"config":764},{"src":765},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":767,"categories":768,"header":770,"text":745,"button":771,"image":775},"security-modernization",[769],"security","Are you trading speed for security?",{"text":772,"config":773},"Get your security maturity score",{"href":774,"dataGaName":750,"dataGaLocation":241},"/assessments/security-modernization-assessment/",{"config":776},{"src":777},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"header":779,"blurb":780,"button":781,"secondaryButton":786},"Start building faster today","See what your team can do with the intelligent orchestration platform for DevSecOps.\n",{"text":782,"config":783},"Get your free trial",{"href":784,"dataGaName":48,"dataGaLocation":785},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/","feature",{"text":492,"config":787},{"href":52,"dataGaName":53,"dataGaLocation":785},1772652072443]