<?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: kaelscion</title>
    <description>The latest articles on DEV Community by kaelscion (@kaelscion).</description>
    <link>https://dev.to/kaelscion</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%2F98953%2F31ea66a0-b34d-4072-8d1f-6f22a24fd29e.jpg</url>
      <title>DEV Community: kaelscion</title>
      <link>https://dev.to/kaelscion</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kaelscion"/>
    <language>en</language>
    <item>
      <title>VIDEO 📺 📽️ Practical Web Scraping | Auto-Upload to DEV | Part 2 - Pushing a Blog Post</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Fri, 02 Aug 2019 22:11:22 +0000</pubDate>
      <link>https://dev.to/kaelscion/practical-web-scraping-auto-upload-to-dev-part-2-pushing-a-blog-post-581p</link>
      <guid>https://dev.to/kaelscion/practical-web-scraping-auto-upload-to-dev-part-2-pushing-a-blog-post-581p</guid>
      <description>&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/qFDU4DbFGV0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h1&gt;
  
  
  What we've learned
&lt;/h1&gt;

&lt;p&gt;We've covered the basics of logging in to DEV with a script, and you've learned the basic skills necessary to reproduce these efforts on any site you wish! &lt;/p&gt;

&lt;h1&gt;
  
  
  So, what's next?
&lt;/h1&gt;

&lt;p&gt;Boy, am I glad you asked! In the video above, we're going to learn how to use environment variables and .env files (so as not to store passwords in the code itself), use selenium webdriver and cleverly placed &lt;code&gt;input()&lt;/code&gt; functions to defeat oAuth device confirmations, and upload and puslih our post on DEV!&lt;/p&gt;

&lt;h1&gt;
  
  
  Anything else?
&lt;/h1&gt;

&lt;p&gt;Of course! At the end, you'll learn where this project is going next. And throughout the video, you can see my quintissential typos, some music, a creepy turn-to-the-camera, and see what happens when I leave the editing of the video to the in-house riffer!! I really hope you enjoy it!&lt;/p&gt;

&lt;p&gt;(by the way, this post was uploaded and published to dev using the script we'll be writing in this video!)&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>webscraping</category>
      <category>learntocode</category>
    </item>
    <item>
      <title>I Passed 3,000 Follows on Dev! 🎉🙌🎊🙌🏿🎆🙌🏾</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Sun, 28 Jul 2019 00:24:19 +0000</pubDate>
      <link>https://dev.to/kaelscion/i-passed-3-000-follows-on-dev-4f5a</link>
      <guid>https://dev.to/kaelscion/i-passed-3-000-follows-on-dev-4f5a</guid>
      <description>&lt;p&gt;Everyone on DEV is lovely, even if you don't think you are. Thank you all so much for your support, comments, reactions, and reads! I have never in my entire development career, met such a wonderful and supportive group of creatives, craftspeople, and innovators! I have tried many many times to get into blogging before and always quite because I felt that nobody cared about the content (yes, I am that insecure 😝). But with DEV, I was continually encouraged and motivated to, not only improve my writing, but my craft as a developer. Thank you all so much to this incredible community, the creators of the platform, maintainers and contributors to its OSS code, moderators who keep trolling to the lowest levels I've ever seen on a similar platform, and everyone else who makes a difference, whether you get paid to or do it for free! I encourage everyone who reads this to please leave a comment talking about their blogging journey, on DEV or off, and whether you are brand new or a seasoned veteran so that we can share our journeys together!&lt;/p&gt;

</description>
      <category>writing</category>
      <category>blogging</category>
      <category>celebrate</category>
      <category>milestone</category>
    </item>
    <item>
      <title>VIDEO 📺📹 Practical Web Scraping | Auto-Upload to DEV | Part 1 - Logging In</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Sat, 20 Jul 2019 21:21:46 +0000</pubDate>
      <link>https://dev.to/kaelscion/video-practical-web-scraping-auto-upload-to-dev-mc6</link>
      <guid>https://dev.to/kaelscion/video-practical-web-scraping-auto-upload-to-dev-mc6</guid>
      <description>&lt;p&gt;Web automation has a lot of uses. But we know that: &lt;strong&gt;Rotten Tomatoes, travel sites, Scraping Hub, Hootsuite&lt;/strong&gt;, etc all use 'em. And another relatively unknown company, &lt;strong&gt;Google&lt;/strong&gt; does too. So what? What can a web scraper do that would help you, in any way, personally? How about auto-uploading blog posts? If you're interested in learning how to auto-upload blog posts to DEV (the example we're using in this video), watch the video below and follow along in the series that it begins!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/W4mxLG6HnFY"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>webscraping</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Best Answers to "Loaded" Interview Questions?</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Fri, 19 Jul 2019 00:31:53 +0000</pubDate>
      <link>https://dev.to/kaelscion/best-answers-to-loaded-interview-questions-5p2</link>
      <guid>https://dev.to/kaelscion/best-answers-to-loaded-interview-questions-5p2</guid>
      <description>&lt;p&gt;Hey all! What are some of the best stories you have about great/clever/funny answers to "loaded" interview questions? The stories don't have to be related to tech or even about you. But let's laugh and tell some stories you've heard (or been apart of on either side of the table) about our favorite answers to near-enough pointless questions like: "Would you consider this your dream job?", "Do you see yourself retiring here?", and other gems that even interviewers don't really get the point of asking. To be fair, I'll start with my favorite.&lt;/p&gt;

&lt;p&gt;My father worked for FedEx for 42 years and just retired last year (SO PROUD OF YOU DAD!!!). In the early days of this company that has since received "utility" status, the company struggled mightily to keep from going under. For that reason, they sought to hire the absolute best salespeople they could find. One of these candidates was a good friend of my dad's. &lt;/p&gt;

&lt;p&gt;In walks this 20-something candidate to interview with the top brass at a young Federal Express. They grilled him on sales for well over an hour and liked what they heard. Near the end, the second-in-command of the company, who had flown from Memphis to oversee interviews pointedly asked: "Would you say that this would be your dream job should you be hired?". &lt;/p&gt;

&lt;p&gt;Without a moment's hesitation he replied, "Heaven's, no! Short-reliever for the Red Sox." (For those who don't know, a short-relief pitcher works about 2-3 hours/wk during the baseball season and is one of the highest-paid players on the roster)&lt;/p&gt;

&lt;p&gt;The table of executives smirked, conferred with each-other, and hired him on the spot. He retired from the company a Senior VP 30 years later.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>VIDEO 🎉📺 |Bye Bye 403 | Building a Filter Resistant Web Crawler in Python | Part IV - Ethics and Throttling</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Wed, 17 Jul 2019 13:51:08 +0000</pubDate>
      <link>https://dev.to/kaelscion/bye-bye-403-building-a-filter-resistant-web-crawler-in-python-part-iv-ethics-and-throttling-1f6l</link>
      <guid>https://dev.to/kaelscion/bye-bye-403-building-a-filter-resistant-web-crawler-in-python-part-iv-ethics-and-throttling-1f6l</guid>
      <description>&lt;p&gt;What's up everybody?! Part 4 is going to be a bit different than previous posts. How you ask? Well, it's a video!! Mainly because the topic of ethics can be really dry and boring. However, especially in a software specialty that is maligned by many, we &lt;strong&gt;must&lt;/strong&gt; keep ethics and proper throttling technique involved in &lt;em&gt;all of our projects&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;But fear not! The following video tries to keep it entertaining. There's baby animals, a ghost hand, and some funky music so give it a watch and we'll have a good time!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/aW2gdPC4pjg"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>python</category>
      <category>discuss</category>
      <category>learntocode</category>
      <category>ethics</category>
    </item>
    <item>
      <title>Attention Web Scrapers and Pen Testers: Slither is now a PyPI package! 🎉</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Fri, 12 Jul 2019 23:10:15 +0000</pubDate>
      <link>https://dev.to/kaelscion/attention-web-scrapers-and-pen-testers-slither-is-now-a-pypi-package-pih</link>
      <guid>https://dev.to/kaelscion/attention-web-scrapers-and-pen-testers-slither-is-now-a-pypi-package-pih</guid>
      <description>&lt;p&gt;Hey data science, web automation, web scraping, and data aggregation folks. Are you tired of needing to purchase proxy IP addresses that get blocked on your goal web asset within a couple of days at most? Do you not yet have your own solution for cycling IP addresses and/or user agents? Do you like super salesy pitches like this one and tend to buy things from QVC after being asked stupid rhetorical questions!?! Well then have I got great news for you!&lt;/p&gt;

&lt;p&gt;All kidding aside, I've finally gotten around to uploading my proxy IP and user-agent cycling library Slither to PyPI! To check out the GitHub repo, go &lt;a href="https://github.com/kaelscion/slither" rel="noopener noreferrer"&gt;here&lt;/a&gt;, for the PyPI page, head &lt;a href="https://pypi.org/project/slitherlib/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Only python 3 is supported and &lt;strong&gt;no support for python 2 is planned&lt;/strong&gt;. This is my small way of doing my part to encourage Python 3 use over Python 2. To install it in your next project in a Python-3-only environment:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install slitherlib&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;for a multi-distro environment:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip3 install slitherlib&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To actually use the library in your scraping projects:&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;slitherlib.slither&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Snake&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Snake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;ip_address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ips&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uas&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://www.google.com&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                 &lt;span class="n"&gt;proxies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
                          &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;http&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ip_address&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
                 &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this time, Slither pulls IP addresses and User-Agents from free sources around the web and dump them into two variables, &lt;code&gt;ips&lt;/code&gt; and &lt;code&gt;uas&lt;/code&gt;. We add new proxy ip:port sources as we can find them and verify, to the best of our ability, that they are not run by hackers looking to steal IP address information. &lt;/p&gt;

&lt;p&gt;As this project grows, we hope to build it into a full web-scraping suite that easily supports concurrency and multi-processing, ROBOTS.txt support, webdriver browser automation, dynamic mouse-moves, and other goodies that will keep the data-collection enthusiast collecting data more and fighting 403 and 404 codes less!&lt;/p&gt;

&lt;p&gt;If you like it, please give us a star on GitHub! I welcome bug reports, feature requests, and any comments or concerns you have so that I can make this library the best it can be! And, as always, I LOVE to collaborate so feel free to open a PR if you have improvements or ideas!&lt;/p&gt;

</description>
      <category>python</category>
      <category>webscraping</category>
      <category>showdev</category>
      <category>datascience</category>
    </item>
    <item>
      <title>I Guess I Kinda Get it...: The Prime Generator Story</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Thu, 13 Jun 2019 21:08:41 +0000</pubDate>
      <link>https://dev.to/kaelscion/i-guess-i-kinda-get-it-the-prime-generator-story-2efk</link>
      <guid>https://dev.to/kaelscion/i-guess-i-kinda-get-it-the-prime-generator-story-2efk</guid>
      <description>&lt;p&gt;Today, we're going to talk about Primes. If you play Horizon: Zero Dawn and think we're talking about the Alpha Prime, Elizabet Sobek, we're not. Nor are we referring to any leader, past or present, of the Autobots. Instead, we're talking about prime numbers.&lt;/p&gt;

&lt;p&gt;More specifically, we're going to talk about the &lt;em&gt;why&lt;/em&gt; behind an exercise that many of us did in CS 101 or in whiteboard interviews or, at the very least, have had to explain on occasion to an interviewer: prime number generators.&lt;/p&gt;

&lt;p&gt;Now, a prime number generator is known mostly for its use in cryptography systems, mathematical applications, and even data science. But, for most of us, its just an excercise that we do when covering the Num Theory part of university CS degrees. &lt;/p&gt;

&lt;p&gt;So why do I decide to talk about them? Well, its because if you follow my content, you know that I like to dig into certain topics and to understand the &lt;em&gt;why&lt;/em&gt;, not just the &lt;em&gt;what&lt;/em&gt;. And, despite my best efforts, prime numbers have come up in my programming more often than I would like to admit. Plus, as engineers, developers and coders, it is our &lt;strong&gt;&lt;em&gt;job&lt;/em&gt;&lt;/strong&gt; to understand as much as we can about the machines we work with every day, and our &lt;strong&gt;&lt;em&gt;duty&lt;/em&gt;&lt;/strong&gt; to try and understand, as best we can, what our colleagues do every day. I, personally, believe that even little tidbits like the topic of today's blog post will help us to be better developers, even if we never write them in production ourselves. I also believe that it will help us to empathize with team members, other teams, or even friends on teams at other companies, which will make the world of software engineering better for everyone!&lt;/p&gt;

&lt;p&gt;So, getting into it, today we're just going to cover a small, yet meaningful, tidbit on how we write efficient prime generators. I'll be using Python, because I love it and its my go-to language, but you can follow along in whatever language you like. &lt;/p&gt;

&lt;p&gt;As we know, a Prime Number is a number that is only divisible by itself and 1. A function that generates all prime numbers between 1 and 1000 would, most often, look like this:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;prime_gen&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="nf"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On my Macbook pro, the run time to print all elements in this generator is 0.564s. But what if I told you we could decrease that bigtime with only a few keystrokes, and not change the structure of the generator at all?&lt;/p&gt;

&lt;p&gt;How? Well, you see this block of code here?&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This block tests to see if any of the numbers between 2 (because 1 is not a prime number and is skipped) and the number we are testing from prime-ness (&lt;code&gt;num&lt;/code&gt;) are factors of &lt;code&gt;num&lt;/code&gt;. If we find some that are, then &lt;code&gt;num&lt;/code&gt; is not a prime number (because Primes are only divisible by themselves and 1), and therefore we can stop testing for prime-ness. &lt;/p&gt;

&lt;p&gt;But this block actually tests twice as many numbers as it needs to, slowing the testing process down. Why is that?&lt;/p&gt;

&lt;p&gt;To put it plainly, if you haven't found a factor of a number (aka, a number that divides evenly into it) by the time you hit that number's square root, you ain't gonna find one at all. &lt;/p&gt;

&lt;p&gt;This is because a number's square root is a smaller number that equals the original number when multiplied by itself. This then means, that half of the factors of a number will be below the square root, and half will be above it. In turn, this means that if we're testing a number for factors and haven't found any that are less than its square root, we won't find any that are above it's square root and can safely conclude that the number is prime!&lt;/p&gt;

&lt;p&gt;Now, armed with such knowledge, we can say with a straight face, &lt;em&gt;why&lt;/em&gt; we only test for a prime's factors up to the square root of the number in question. It also means, that we can add the following code to our original generator:&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="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt;  &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;+&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a side note, in Python, the &lt;code&gt;ceil()&lt;/code&gt; and &lt;code&gt;sqrt()&lt;/code&gt; functions are part of the &lt;code&gt;math&lt;/code&gt; class, so be sure to import them before trying to use them. Your completed generator, with the new code, should look like this:&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;math&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sqrt&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;prime_gen&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt;  &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="o"&gt;+&lt;/span&gt;  &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
                &lt;span class="nf"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt;  &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;break&lt;/span&gt;
                &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="nf"&gt;yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, on the same equipment as our first test, the run time to print the elements for our revised generator is &lt;strong&gt;&lt;em&gt;0.023s&lt;/em&gt;&lt;/strong&gt;. That is only 4% of the run time of our first generator!&lt;/p&gt;

&lt;p&gt;So, I hope this has helped some of those out there to get a better grip on a CS principle that most of us (myself included) had an "I kinda get it..." opinion of at first.&lt;/p&gt;

&lt;p&gt;As always, please keep coding! No matter what you do in this industry. No matter where you come from, what your social status is, what your parents did, what neighborhood/country/district you're from, or &lt;strong&gt;&lt;em&gt;anything else that people try to convince you means you're not cut out for this gig&lt;/em&gt;&lt;/strong&gt;, code on. The world needs those with every possible approach to any problem facing it. Which means they need the diversity that you can provide. Otherwise, we'll always solve the same problems the same way and get the results we've always gotten! Happy coding everybody!!!&lt;/p&gt;

</description>
      <category>python</category>
      <category>computerscience</category>
      <category>code</category>
      <category>learntocode</category>
    </item>
    <item>
      <title>Dynamically Filling in a CSS Grid with JavaScript</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Fri, 17 May 2019 17:59:12 +0000</pubDate>
      <link>https://dev.to/kaelscion/dynamically-filling-in-a-css-grid-with-javascript-5geb</link>
      <guid>https://dev.to/kaelscion/dynamically-filling-in-a-css-grid-with-javascript-5geb</guid>
      <description>&lt;p&gt;Why hello there! Today, I finally submitted. As many of you know, I am a Python developer. However, I have resolved that from now on, I will not outsource my front-end development and am forcing myself to learn JavaScript. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;HOWEVER&lt;/em&gt;&lt;/strong&gt;, I refuse to start by learning a "new hotness" framework or tooling system (React folks, stop typing. I'm just not digging into it yet, I'm sorry. One miracle at a time 😛) and will only be using Javascript to the ES6 standard. Please note, I just started actually writing JS code with any sort of real use today so there will plenty of "Hey, you can do that better!" opportunities in the code samples. But, I sincerely ask that you follow up those cherry-picks with &lt;em&gt;how&lt;/em&gt; it can be better so that I can learn the right way and I thank this wonderful community in advance for any &lt;em&gt;constructive&lt;/em&gt; criticism they might have! With that in mind, let's dive in!&lt;/p&gt;

&lt;p&gt;So, what little project have I decided to try out first? Well, many options came to mind. But in the end, I decided to try and find a practical use for the idiotic matrix and grid traversal algorithms all of us are forced to do in the whiteboard challenge round of the dev interview process. The tiny project that I'm about to share simply creates a CSS Grid with a specified number of equal rows and columns. A separate script then places square blocks of a pseudo-random (but limited) size into the grid at a pseudo-random x and y location. This creates a fun randomized section of a page that changes on every page load. I've had great fun with it and hope you do too! The personal website for my wife and I's development studio will soon feature a version of this on our portfolio page that displays the blocks as thumbnails of our past projects. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This project will also be available on GitHub and free for anybody to modify for their own projects. If you do end up using it, please show us what you've created as we get so much more joy out of seeing what you guys build than what we come up with on our own!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So to start, let's lay out our HTML page which will serve as nothing more than a vessel for our javascript&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"gridTraversal.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty basic. Bare-bones even. With that done, we can get on to the fun stuff. As I am a huge advocate of compartmentalization of code, we are going to write three functions, one to create the div that will hold our grid, one that will lay out the rows and columns of that grid, and a final one to place the blocks. Our grid creation div is created with the following JS code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;createGrid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;markup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;div class="container" id="container" style="display: grid;
                                                 border: 1px black solid; 
                                                 height:100%; 
                                                 width: 100%"&amp;gt;
    &amp;lt;/div&amp;gt; `&lt;/span&gt;
    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;markup&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this is very ES6 what with the arrow functions and template strings. But we are not importing any libraries or frameworks in this entire project other than the JS core.&lt;/p&gt;

&lt;p&gt;I've found the easiest way, for me personally, to create HTML in JS without having to involve JSX is to simply write the markup code as a variable (in this case &lt;code&gt;const markup&lt;/code&gt;) and append it to the body's DOM via &lt;code&gt;document.body.innerHTML += markup&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;All this script does is create a div that takes up the whole viewport, that has a grid display with a black border around it. &lt;/p&gt;

&lt;p&gt;To lay out the grid columns and rows, we involve this guy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;layoutGrid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gridTemplateColumns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`repeat(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 1fr)`&lt;/span&gt;
    &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gridTemplateRows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`repeat(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 1fr)`&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those of you familiar with JS should be able to see what this does pretty clearly right off. For those that aren't familiar with JS, this script selects our grid container from the DOM, and assigns two styles to it, &lt;code&gt;gridTemplateColumns&lt;/code&gt; and &lt;code&gt;gridTemplateRows&lt;/code&gt;, and uses the CSS &lt;code&gt;repeat&lt;/code&gt; function to assign equally sized columns and rows using the &lt;code&gt;fr&lt;/code&gt; css unit. The number of columns and rows are determind by the &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; arguments passed to the &lt;code&gt;layoutGrid&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;So now we have a grid div that contains a grid. What about the blocks? The following script addresses that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fillGrid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;blockSize&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numOfBlocks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num_of_blocks&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
                &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;markup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;div id="card &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" 
                                   style="grid-column: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; / span &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;blockSize&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;; 
                                          grid-row: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; / span &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;blockSize&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
                                          background-color: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;;
                                          border: 1px black solid;"&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/div&amp;gt;`&lt;/span&gt;
                &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;markup&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;To pro JS devs: please be gentle. To new JS devs: I'm sorry. I am not sure what it is, but I feel like this script is very ugly. Putting that aside, let me at least explain what it does.&lt;/p&gt;

&lt;p&gt;First, we define a function named &lt;code&gt;fillGrid&lt;/code&gt; that accepts the arguments &lt;code&gt;x&lt;/code&gt;, &lt;code&gt;y&lt;/code&gt;, &lt;code&gt;blockSize&lt;/code&gt;, &lt;code&gt;numOfBlocks&lt;/code&gt;, and &lt;code&gt;color&lt;/code&gt;. &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; define the starting axes of each block we're going to place. &lt;code&gt;blockSize&lt;/code&gt; determines how many spaces in the grid each block will occupy. &lt;code&gt;numOfBlocks&lt;/code&gt; is how many blocks we're going to be tossing into this grid and finally, &lt;code&gt;color&lt;/code&gt; is tells the browser what the background color of these blocks will be.&lt;/p&gt;

&lt;p&gt;Our first line selects the DOM element that contains our grid. We then generate an Array that has &lt;code&gt;numOfBlocks&lt;/code&gt; items in it and iterate over it using a for...of loop that creates our blocks. &lt;/p&gt;

&lt;p&gt;Each block has its size and placement defined by the Math.floor() function (which generates pseudo-random whole numbers) that are between 0 and the maximum block size established by the &lt;code&gt;blockSize&lt;/code&gt; argument.&lt;/p&gt;

&lt;p&gt;Each block then receives a 1px black solid border and the specified background color, and is appended to the Grid's markup.&lt;/p&gt;

&lt;p&gt;Now, let's include our scripts in our HTML document like so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text/javascript"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"gridTraversal.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createGrid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;layoutGrid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;fillGrid&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the script and watch the fun! Every page load (or refresh) will rearrange the blocks in the grid. Play around with the size of the blocks, the number of blocks to place, and the number of columns and rows in the grid! Many times the blocks overlap and create really unique-looking grid layouts. Give it a try and let me know what you get!&lt;/p&gt;

&lt;p&gt;If you like this kind of content, remember to give this post a like, comment, of bookmark it for reading so that I know what you all want to see next! Thanks so much for reading and I look forward to providing more content for all you Devvers in the future!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>es6</category>
      <category>css</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Help Testing "Sentinel": A Real-Time Proxy Bot Filter for the Web</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Mon, 01 Apr 2019 20:58:02 +0000</pubDate>
      <link>https://dev.to/kaelscion/help-testing-sentinel-a-real-time-proxy-bot-filter-for-the-web-208p</link>
      <guid>https://dev.to/kaelscion/help-testing-sentinel-a-real-time-proxy-bot-filter-for-the-web-208p</guid>
      <description>&lt;p&gt;Hi Devvers! So I would just like to test the waters on the community's willingness to help test a product I am developing called "Sentinel". As many of you probably know, I did a #showdev on Sentinel's sister package "Slither" insanely recently and the response has been incredible (25 stars and 4 forks since yesterday night 😱😱😱), so I thought I would toss this one out there too.&lt;/p&gt;

&lt;p&gt;So what is Sentinel? Well, if you read my profile, you will see that I enjoy double dipping in the web crawler industry. This means that I build both sophisticated crawler bots, and the services that keep them out. Seeing as Slither is a crawler bot proxy framework, I'm sure you can guess what Sentinel does...&lt;/p&gt;

&lt;p&gt;Over the years, I've written web crawlers that do all sorts of different things and have gained valuable insight into both how filters identify bots, and how web scrapers circumvent these filters. Being on both sides of the equation has given me a pretty unique perspective that I thoroughly enjoy!&lt;/p&gt;

&lt;p&gt;Sentinel is a live-update crawler bot detection system that is meant to keep malicious web crawlers from getting to your resources in real time. The best part: It can be applied to specific resource pages on your website. Don't mind crawlers getting the company support phone number but don't want them scraping eCommerce data? Just tell Sentinel to only monitor your listing pages or galleries. This is done by maintaining a list, updated every 15 minutes, of proxy ips, known spammer subnets, and malicious bots and referencing every incoming connection against this list in real time! Think of it as a robots.txt that is NOT optional.&lt;/p&gt;

&lt;p&gt;The product, as it stands, is in its infancy, but I really want to get an MVP out into the wild as soon as possible and need folks like the dev community to help me out! Let me know in the comments or via DM if you're interested in helping to test the functionality out on your websites! Thanks so much to you all for your support and interest!&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>webscraping</category>
      <category>opensource</category>
      <category>python</category>
    </item>
    <item>
      <title>Introducing Slither: Adding anonymous proxy IPs and randomized User Agents to Scraping Projects</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Sun, 31 Mar 2019 20:21:52 +0000</pubDate>
      <link>https://dev.to/kaelscion/introducing-slither-adding-anonymous-proxy-ips-and-randomized-user-agents-to-scraping-projects-1ej9</link>
      <guid>https://dev.to/kaelscion/introducing-slither-adding-anonymous-proxy-ips-and-randomized-user-agents-to-scraping-projects-1ej9</guid>
      <description>&lt;p&gt;Hey there Devvers! Long time, no see! I have been on vacation for the past while and thought I would return with my first open sourced project, Slither. Slither is a basic anonymizing framework for adding elite, https, anonymous proxy IPs and pseudo-random User Agents to your web scraping and/or pen-testing projects! Finally up and running and based heavily on the Bye Bye 403 series that I've been writing, Slither is my first foray into OSS and something I deeply care about and hope folks find useful!&lt;/p&gt;

&lt;p&gt;The GitHub repo can be found &lt;a href="https://github.com/kaelscion/slither" rel="noopener noreferrer"&gt;here&lt;/a&gt; and I really hope you all enjoy it! A lot of requests and questions have come from around the web about this topic and how to make it easier to avoid the dreaded 403 (or worse, 503) when you're trying to scrape and/or aggregate data! The framework is dead simple and supports concurrent scraping as well as parallel processes. &lt;/p&gt;

&lt;p&gt;Whenever an instance of the Slither class is declared, a list of IPs and User-Agents are pulled from proxy sites around the web and assigned to the &lt;code&gt;Slither().ip&lt;/code&gt;and &lt;code&gt;Slither().ua&lt;/code&gt; variables. Simple plug those two variables into your project's headers and your off and running!&lt;/p&gt;

&lt;p&gt;I really hope this helps some newcomers to web scraping and the emerging field of collecting data for data scientists and ML engineers to use! Please give it a try and leave a comment here or on the repo. Be gentle as this is my first OSS project despite years of working in software 😝. Enjoy and happy scraping! &lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>python</category>
      <category>webscraping</category>
    </item>
    <item>
      <title>Bye Bye 403 - Building a Filter Resistant Web Crawler Part III: User Agents</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Thu, 07 Mar 2019 05:08:16 +0000</pubDate>
      <link>https://dev.to/kaelscion/bye-bye-403---building-a-filter-resistant-web-crawler-part-iii-user-agents-3453</link>
      <guid>https://dev.to/kaelscion/bye-bye-403---building-a-filter-resistant-web-crawler-part-iii-user-agents-3453</guid>
      <description>&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%2Fftt0jtvnxrr0pyd8xut8.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%2Fftt0jtvnxrr0pyd8xut8.png" alt="bye-bye-403-part-3-user-agents"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So we’ve covered what web scraping is. We’ve also covered how to cycle proxy information to disguise our IP Address. But there is another step in masking the scraper that we now must consider. To illustrate, think of it this way:&lt;/p&gt;

&lt;p&gt;Imagine that somebody is bugging you on any social media platform and you’ve blocked them. Let’s say you’re an influencer so you get hundreds of follows every day and it is really hard to do a “profile check” of every follower to make sure that they are not the person who you’ve blocked. What would be the easiest way for you to make a preliminary guess? Obviously, checking the name of the new followers would be your first line of defense. Well, what if somebody with the same name and profile picture started following you? Would the fact that their profile snippet listed them as being from a different country than before stop you from blocking them right away? Not likely. In all likelihood, it would make you more suspicious of this person because they are being deceitful.&lt;/p&gt;

&lt;p&gt;Think of a web server bot filter as the “influencer with an annoying follower”. By cycling our IP address, we change our respective location ID, and “profile pic”, but we are still listed as a connection from the same type of laptop, with the same OS version, from the same browser, etc. It's pretty easy to peg and filter. So what is a budding web scraper to do? Cycle your User-Agent.&lt;/p&gt;

&lt;p&gt;A User-Agent is essentially a field in your HTTP/S headers that tells the web server the browser version, host OS version, host machine form factor, and some other small tidbits about every request that comes through. This serves two purposes: diagnostics of the web content (to see if a certain bug is only reported on certain OSes, Browsers, or some combination of the two) and security (to see who’s connected and what are they connecting from to track possible offenders during and/or after a security incident). So in lamen’s terms, a User-Agent tells the web server about the connecting machine, whereas an IP address tells it more about where you’re coming from. Make sense? Good!&lt;/p&gt;

&lt;p&gt;To begin cycling User-Agents, head &lt;a href="https://deviceatlas.com/blog/list-of-user-agent-strings#desktop" rel="noopener noreferrer"&gt;here&lt;/a&gt; for an up-to-date collection of desktop User-Agents:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Pro Tip: We can also scrape the mobile versions of websites by changing the User Agent. That is actually how the “show desktop site” option on Mobile Browsers works. The browser will spoof your User Agent as if it came from a desktop device despite the fact that you are on mobile, thus showing you the “desktop version” of any content. The same works in reverse for scraping mobile-only content&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, we could just copy/paste all of these user-agents into a file, but this is a web scraping post series after all so instead, create a new project file and call it user_agent.py&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;bs4&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserAgent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

    &lt;span class="n"&gt;ua_source_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://deviceatlas.com/blog/list-of-user-agent-strings#desktop&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new_ua&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_ua_list&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So first we’re making the UserAgent class. If you’ve made it this far into the series you can probably put together that I am a big fan of encapsulation. This is largely due to coming from the Network Engineering and IT Technical worlds before I started writing code where, it is assumed, that an incident WILL wake you up EVERY TIME you are on call at no earlier than 4 AM. Because of this, I am a huge fan of creating things that are easily debugged. Getting paged at 4, getting to the office by 4:30, and leaving by 4:45 to actually have some semblance of a morning with my family is preferred to taking 3 hours to fix a simple issue that was buried under layers of junk. Because if it takes me 3 hours, then I have solved my problem by 7:30. You know, just in time to start “normal” work for the day… &lt;/p&gt;

&lt;p&gt;That being said, the UserAgent class is going to handle all the user-agenty things for us! The class variable we’ve created &lt;code&gt;ua_source_url&lt;/code&gt; is outside of the &lt;code&gt;__init__&lt;/code&gt; function, as you might have noticed. Why is that? Because everything inside  &lt;code&gt;__init__&lt;/code&gt; only “exists” after an instance of the class is called (aka instantiated) in your code. Class level variables can be referenced directly and more importantly, are shared among all instances of that class. Meaning when we multithread this bad boy, we won't have to store that particular string in memory more than once. &lt;/p&gt;

&lt;p&gt;Within our &lt;code&gt;__init__&lt;/code&gt; function is the &lt;code&gt;new_ua&lt;/code&gt; property which we want to be different for each instance of this class but not be pulled into existence until the class is created. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side Note: For a further understanding of &lt;code&gt;__init__&lt;/code&gt;, what it does, and how to use it, stick around. There is a post coming on that very soon!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;new_ua&lt;/code&gt; property picks a random user agent from a list of user agents. Where will we get that list you ask? From the code your about to type:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_ua_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ua_source_url&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;html.parser&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tables&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;soup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;table&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;td&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tables&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;So what have we done here? Well, we have scraped the page above (as we do) for the user-agent information listed on that page. As with all of our little scraping scripts, it started with a Requests &lt;code&gt;get()&lt;/code&gt; function, fed the response content to our HTML parser (BeautifulSoup), found the table markup for each user-agent, and extracted the text of the data of each table. Now that this function is complete, does the &lt;code&gt;__init__&lt;/code&gt; make a bit more sense? If not, allow me to explain:&lt;/p&gt;

&lt;p&gt;As soon as we create an instance of the UserAgent class ANYWHERE in our code, it will run this function without us needing to touch it. When the function completes, it will have assigned the list of potential UserAgents to the property &lt;code&gt;new_ua&lt;/code&gt;. How is this relevant? Take a look at the terminal screen capture below which shows the output of the following code:&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;i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;UserAgent&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;new_ua&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="mi"&gt;1&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%2F27ocvdkv40x4fcx3yued.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%2F27ocvdkv40x4fcx3yued.png" alt="UserAgent Cycling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, we do not need to write the user agents to a file, which involves opening the file, reading it, then closing it again, relying on disk memory. Instead, we read this list into RAM (the faster, easier-to-clean storage) and retrieve it only when we need it, getting a different UserAgent each time through the &lt;code&gt;random.choice()&lt;/code&gt; function&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Pro Tip: For those of you who are unfamiliar with &lt;code&gt;random.choice()&lt;/code&gt;, it basically does the same thing when selecting from a list or iterable as &lt;code&gt;random.randint(0, len(sample_list))&lt;/code&gt;. Simply put, it selects a pseudo-random item from any iterable data structure you pass to it. In instances like this, &lt;code&gt;random.choice()&lt;/code&gt; is my preference because both approaches do roughly the same thing and &lt;code&gt;.choice()&lt;/code&gt; is fewer keystrokes.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Alright, Mavericks (Season of the Drifter anyone 😉) you've got the tools to fool 99% of bot filters. But do you know how to use them? Head out into the Wild and find out, then report back. I'd love to hear your stories of the datasets your gathering and what you plan to do with them! Successes and failures are equally welcome because this completes the first set of countermeasures we're going to discover. These are referred to (by me at least) as the "hard skills" of web scraping. The skills we need to develop our knowledge. But how are your instincts? Find out next week in part four when we break into the intermediate stuff: Timing and Throttling!&lt;/p&gt;

</description>
      <category>python</category>
      <category>tutorial</category>
      <category>datascience</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Life Can Be Tough, But We Are DAMN Good at What We Do!</title>
      <dc:creator>kaelscion</dc:creator>
      <pubDate>Fri, 08 Feb 2019 15:54:25 +0000</pubDate>
      <link>https://dev.to/kaelscion/life-can-be-tough-but-we-are-damn-good-at-what-we-do-2g9o</link>
      <guid>https://dev.to/kaelscion/life-can-be-tough-but-we-are-damn-good-at-what-we-do-2g9o</guid>
      <description>&lt;p&gt;Devvers, lend me your ears...eyes...ears? Whatever, just listen. The past six months have been rough for me personally. Health issues always suck, but they're a real pain in the ass when they almost kill you. Something like that can change the way you look at the world. That being said, it can be a surreal experience when you are suddenly forced to acknowledge that you do indeed matter, even in a small way, and that you can only ignore your body and mind's signals for so long before stuff hits the fan. I just got out of a critical care unit Monday and need to share the good with those who may need it just like I do. Because what is a community for if not support, encourage, and unconditional love (some of ya'll like to be prickly enough to only get love unconditionally sometimes. You know who you are, and I dig you anyway 😋)?&lt;/p&gt;

&lt;p&gt;So, here's what we're gonna do: Anybody who reads this post that inherently thinks what they do, either personally or professionally is too small to matter. For all of us out there that think "Junior Developer" translates to "coffee-getter with no talent or skills". For anybody that is having a harder and harder time refuting other's assertions that DevOps/QA/Front End/DBA work is just the crap that is put in place to annoy the "real geniuses" so that "the company can feel good about including non-critical staff in important work". For any person in tech that is female, brown or black, wears a hijab, dashiki, or yukata to work, or is just otherwise looked down on because of external crap &lt;strong&gt;or having the gall&lt;/strong&gt; to value your cultural or religious traditions over the extreme views or ignorant opinions of others, this thread is for you. Whether you have an invisible illness that people think you are faking or a visible difference to your appearance that people think you should change, we're gonna show the "boss" in all of us.&lt;/p&gt;

&lt;p&gt;Here's my contribution: Right now I am currently building a system for a client of mine that has one of the most low-level and accurate testing suites for GMOs in plants. They are tasking me with giving them a "market snapshot" of who the players are in the Corn Ethanol biofuel market globally so that they will better know how to make decisions with their products and services based on where their target customers are moving as an industry. To do this, I am putting my Data Junkie skillset to use by finding the company information (location, employee count, gross income, stock price, etc) of all the players in the US. Below is a screenshot of the runtime of two scripts that do this by extracting that particular data from the websites of the 204 players in the Continental US. The top runtime is a solution I designed and created for this purpose. The second is of a "copy and paste" solution I found online that is lightly modified to perform the same task as my custom solution. &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%2Fnsnh5yw8uyk8kr9h90l8.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%2Fnsnh5yw8uyk8kr9h90l8.png" alt="high-volume-web-scraping-solution"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Hey wait, Jake. Are you grandstanding here?" How dare you ask that entirely true, accurate, and appropriate question! But seriously, that what this thread is about. I am a lone-wolf, back-end, guy-who-builds-stuff-that-is-never-seen-and-never-acknowledged kind of guy. And I have been for many years. Tooting my own horn is something I'm not usually comfortable with. But here, in this thread, BRAG YOUR BLOODY HEADS OFF. Because every now and then, we need to shout to anybody who will listen how damn smart, creative, and clever we are. Nobody is going to do it for us, so go nuts! Post screenshots or tell stories of things you've done that you think are really cool, innovative, clever, or elegant. Talk to me, and the community about your pet projects or nifty solutions that you're too nervous are not "cool" enough to get positive attention from your colleagues. They are not only cool enough, but they are &lt;strong&gt;too cool&lt;/strong&gt; for those guys. So tell us, and don't be modest about it 😁 😁 😁! I very much look forward to your submissions!&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>career</category>
      <category>beginners</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
