<?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: Shane Lee</title>
    <description>The latest articles on DEV Community by Shane Lee (@shanelee).</description>
    <link>https://dev.to/shanelee</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%2F302160%2F0a80d325-4106-442c-adf3-cb91e82b3660.jpeg</url>
      <title>DEV Community: Shane Lee</title>
      <link>https://dev.to/shanelee</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shanelee"/>
    <language>en</language>
    <item>
      <title>A Brief 10-Point Guide to GraphQL</title>
      <dc:creator>Shane Lee</dc:creator>
      <pubDate>Sat, 12 Sep 2020 14:49:50 +0000</pubDate>
      <link>https://dev.to/shanelee/a-brief-10-point-guide-to-graphql-o1a</link>
      <guid>https://dev.to/shanelee/a-brief-10-point-guide-to-graphql-o1a</guid>
      <description>&lt;p&gt;When I’m learning new about new technologies, one of the first things, I’ll do is write a numbered list 1–10 and then fill that numbered list in with points about that particular technology. I realised that these lists might be useful to others so I’m going to start posting them. This week I looked at GraphQL.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;GraphQL can be best thought of as a middleware between your clients and your servers. The idea behind GraphQL is to have a system which sits between your clients and your API and allows the requesting of data through itself. It has an in-built query language which allows your to create requests and GraphQL will handle the fetching and composing of the data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the primary reasons to use GraphQL is that it simplifies dealing with your backend APIs. For example, a common pattern to find in applications is the need to request data from two or more distinct sources and compose them to be processed together. For example, you might have images stored in one database and text stored in another. Using GraphQL enables you to have a single query to get the data from both of the sources and return a single response, which greatly simplifies your code has you don’t have to deal with the complexities of handling multiple requests and waiting all of them before processing the data together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the oft-quoted benefits of GraphQL is that it decouples you from your existing API implementation. This means that with GraphQL you can easily swap out the implementation of your existing API for another one and everything will continue hunky dory. However, the seldom mentioned caveat to this is that you are necessarily coupling yourself to GraphQL itself&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Data savings are another benefit of using GraphQL. With GraphQL, you don’t need to make multiple calls to your API as you would with REST. You can query for only the data you want: GraphQL can aggregate data from multiple sources for you and it will only return the data that you need. The result of this is data savings for each API call, which leads to improved performance of your application overall.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;GraphQL enables increased speed of development. The reason for this is that because GraphQL decouples your client from your API, different teams also become decoupled, meaning there is a reduced need of coordination between teams to get development done. To give an example, instead of the frontend team needing to coordinate with the backend team to update or add a new REST endpoint, they can simply develop their new frontend functionality using GraphQL to get the exact data they need.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another benefit of using GraphQL is that there is reduced need for filtering data. Often when developing a new feature of an application, a developer will have to filter and aggregate existing data to generate the new data required for the new feature. All of this leads to additional code, which incurs additional costs both in terms of development time and maintenance time. With GraphQL this is unnecessary as GraphQL handles the aggregation and filtering of data for free.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the drawbacks of GraphQL is that there is a need for a fair amount of boilerplate code. For example you will often need to write a Resolver, a query, a mutation, and a schema.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Benefit — Strong typing — GraphQL’s query language is strongly typed. This is benefit because it provides a common contract for communication between the client of an application and the backend. This helps facilitate independent development of both the frontend and backend because the strong typing of GraphQL provides a solid and predictable foundation on which to base the target of future system states. In other words, developer can write new code knowing that GraphQL will be able to provide the data they require and they will know the format of that data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another disadvantage of GraphQL is that error handling is somewhat more difficult and cumbersome than it is with REST. If you GraphQL query errors, it doesn’t return a 5xx error code or even a 4xx error code, but instead it always returns a 200 success code. The error will be in the JSON response itself. This is weird. It’s something that you should be aware of because if you are considering migrating your system to GraphQL, this quirk will likely increase the time required to do so because you will have to change your error handling and any code that specifically checks for standard error codes. This will likely mean changing many of your test code as well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A final consideration of GraphQL is the complexity of it. Now this isn’t really a disadvantage or an advantage. The reason being is that it isn’t particularly complex, however it is more complex than a standard REST API. If you know that your application is going to have a relatively simple and stable API over time, then you might be better sticking with REST. If you are unsure about this, I would be better to use GraphQL from the start as the complexity involved in migrating from REST to GraphQL once an application is midway through development wouldn’t be the quickest process, you’d have to define all your schemas, mutations, queries, and resolvers. Plus you’d potentially have to write new tests and learn a whole new testing API.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>graphql</category>
    </item>
    <item>
      <title>A Brief 10-Point Guide to AWS Elastic Beanstalk</title>
      <dc:creator>Shane Lee</dc:creator>
      <pubDate>Sat, 05 Sep 2020 10:45:28 +0000</pubDate>
      <link>https://dev.to/shanelee/a-brief-10-point-guide-to-aws-elastic-beanstalk-gm4</link>
      <guid>https://dev.to/shanelee/a-brief-10-point-guide-to-aws-elastic-beanstalk-gm4</guid>
      <description>&lt;p&gt;When I’m learning new about new technologies, one of the first things, I’ll do is write a numbered list 1-10 and then fill that numbered list in with points about that particular technology. I realised that these lists might be useful to others so I’m going to start posting them. This week I looked at AWS Elastic Beanstalk.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Amazon's Elastic Beanstalk is a service which allows you to deploy applications within an AWS context that involves a number of different AWS services such as S3 and ECR. With Elastic Beanstalk you don't have to worry about the management and orchestration of these services. You can simply focus on your application. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the main benefits of using AWS Elastic Beanstalk is that is it abstracts away the need to deal with infrastructure. You don't have to worry about configuring load-balancing or scaling your application. You can simply upload your code and go.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another benefit of using AWS Elastic Beanstalk is that assuming you were planning to host your application on AWS to begin with, there's no additional cost to using Elastic Beanstalk. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;While you have the ability to sit back and let Elastic Beanstalk handling everything for you, AWS does give to the option to configure and control the AWS resources you use for your application. And what's more, it's not an all or nothing deal. You could for example decide to manually manage your AWS ECR instances, but leave your S3 instances to be managed by Elastic Beanstalk. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setting up monitoring and logging tools for your application is often a full-time job in of itself. With Elastic Beanstalk, you don't have to bother because Elastic Beanstalk comes with a monitoring interface which is integrated with Amazon CloudWatch and AWS X-Ray.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the drawbacks of a system that abstracts away the need for management is that understanding when things have gone wrong with Elastic Beanstalk can be a difficult task, because it can be difficult to see the error to diagnose the problem. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An additional drawback of using Elastic Beanstalk is third-party integration. Some of the common culprits like Docker, Jenkins and Github are supported, but don't expect to find the third-party integration extensive. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the pros of AWS Elastic Beanstalk is that you can easily integrate Code pipelines into it, which can enable you to check if your code you've just uploaded is working correctly. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another one of the benefits of the auto-management of AWS Elastic Beanstalk is that unavoidable things like updating versions and operating systems, can be done without any downtime to the application. Furthermore, should something go wrong with one of those updates, it is quite easy to rollback the application to an earlier state. Again, without any downtime to the application (Unless of course the update itself caused downtime).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A final disadvantage of using AWS Elastic Beanstalk is that if you require technical support from Amazon, there is a charge for that. While this is something which is normally to be expected from modern SaaS and PaaS apps. In this case it is something to consider carefully, because of the challenges of not being easily able to diagnose problems with the system as mentioned above.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>elasticbeanstalk</category>
      <category>devops</category>
      <category>deployment</category>
    </item>
    <item>
      <title>A Brief 10-Point Guide to AWS DyanmoDB</title>
      <dc:creator>Shane Lee</dc:creator>
      <pubDate>Sat, 29 Aug 2020 12:02:40 +0000</pubDate>
      <link>https://dev.to/shanelee/a-brief-10-point-guide-to-aws-dyanmodb-43o8</link>
      <guid>https://dev.to/shanelee/a-brief-10-point-guide-to-aws-dyanmodb-43o8</guid>
      <description>&lt;ol&gt;
&lt;li&gt;Amazon's DynamoDB is fully managed key-value and document database &lt;/li&gt;
&lt;li&gt;As DynamoDB is fully managed, one of the benefits of using it is that there is no server to manage and more importantly DynamoDB auto-scales to the demand on the database as a result the performance of the AWS DynamoDB is consistent at scale. &lt;/li&gt;
&lt;li&gt;Performance is another reason to use DynamoDB. Amazon boasts: 'single-digit millisecond response times at any scale'&lt;/li&gt;
&lt;li&gt;Data safety is another benefit of using DynamoDB. Amazon enables instant backups of 'hundreds of terabytes of data' with no performance impact. Further, with DynamoDB it is possible to restore the database to any state that existed within the last 35 days. More impressive is that this can be done with no downtime. &lt;/li&gt;
&lt;li&gt;A seldom mentioned, but very important benefit of using DynamoDB is that Amazon provides the ability to &lt;a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html"&gt;deploy instances of DynamoDB locally&lt;/a&gt;, which is very useful for testing your application. Being able to deploy a local instance of DynamoDB means that you can run your integration tests against that instance, which provides a more valid test context, which means you are more likely to catch bugs that would occur in production therefore enabling you to improve the quality of your code and speed up the development cycle.&lt;/li&gt;
&lt;li&gt;Another benefit of using DynamoDB is that it accommodates cases where some data is accessed more than other data while still providing autoscaling. To understand this benefit, it is important to understand that this wasn't always the case. It used to be the case that with autoscaling just sticking the data in DynamoDB could lead to a problem where performance would be impacted or queries would error. The reason for this is that DynamoDB when autoscaling would shard the data with the assumption that all the data will be accessed with uniform frequency. It did not consider what data is most important. Not all data is created equal. Some data will be accessed far more often than other data. The term for this is a 'hot key'. In other words, it used to assume that you will access each key in the database roughly an equal number of times, which often isn't the case. However, now DynamoDB has a feature called adaptive capacity, which, &lt;a href="https://aws.amazon.com/blogs/database/how-amazon-dynamodb-adaptive-capacity-accommodates-uneven-data-access-patterns-or-why-what-you-know-about-dynamodb-might-be-outdated/"&gt;as of 2019&lt;/a&gt;, will instantly adapt to your data. In other words the sharding process which occurs during autoscaling distributes your data according to the demands on different keys. This is remarkable. What's more, this is done at no additional cost and it does not have to be configured.&lt;/li&gt;
&lt;li&gt;Perhaps one of the drawbacks of using DynamoDB is that the costs of using it can balloon if you experience spikes in demand or if you haven't done a good job of predicting what the demand on your database will be. While Amazon does provide a &lt;a href="https://calculator.aws/"&gt;pricing calculator&lt;/a&gt; to help you estimate your costs, it is still dependent on your assumptions and estimates. This drawback is really tradeoff for the autoscaling capacity that DynamoDB provides. One of the things you should therefore ask your self is are you expecting fluctuations in demand that would benefit from DynamoDB's autoscaling?&lt;/li&gt;
&lt;li&gt;Another drawback of using DynamoDB is that it has a limit on &lt;a href="https://aws.amazon.com/blogs/database/how-to-determine-if-amazon-dynamodb-is-appropriate-for-your-needs-and-then-plan-your-migration/"&gt;individual binary items of 400kb&lt;/a&gt;. This means that DynamoDB is not well-suited to storing images or large documents. &lt;/li&gt;
&lt;li&gt;In DynamoDB, &lt;a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-query-scan.html"&gt;scanning a table is not an efficient operation&lt;/a&gt;, which can of course be problem depending on the structure of your data and your use case. In furtherance, this may lead to to incur addition costs over what was initially planned, scanning the whole table in DynamoDB is expensive. This may lead you desire additional indexes, particularly secondary global indexes, which can be provisioned at an &lt;a href="https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html"&gt;additional cost particularly because of the additional cost in writing to DynamoDB.&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;A final drawback to consider is that write operations to DynamoDB are expensive. Writes to DynamoDB are prices via 'Write Capacity Units' per month. When you have a use case with a lot of writes this cost can balloon.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>dynamodb</category>
      <category>documentdatabases</category>
      <category>database</category>
    </item>
    <item>
      <title>A Brief 10-Point Guide to AWS Aurora</title>
      <dc:creator>Shane Lee</dc:creator>
      <pubDate>Sat, 22 Aug 2020 10:28:16 +0000</pubDate>
      <link>https://dev.to/shanelee/a-brief-10-point-guide-to-aws-aurora-4m25</link>
      <guid>https://dev.to/shanelee/a-brief-10-point-guide-to-aws-aurora-4m25</guid>
      <description>&lt;p&gt;When I’m learning new about new technologies, one of the first things, I’ll do is write a numbered list 1-10 and then fill that numbered list in with points about that particular technology. I realised that these lists might be useful to others so I’m going to start posting them. This week I looked at AWS Aurora.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Amazon Aurora is a cloud-based database solution (database-as-a-service DBaas) that is compatible with MySQL and PostgreSQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using Amazon Aurora has the benefit that users don't have to deal with the headaches involved in managing and maintaining physical hardware for their databases. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another benefit of using Aurora over MySQL and PostgreSQL is the performance. Aurora is around 5 times as fast as MySQL, and around 3 times as fast as PostgreSQL when compared on the same hardware. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With Aurora, the concern about database capacity is eradicated because the storage on Aurora will automatically scale all the way from the 10gb minimum to the 64TB maximum. Meaning, the maximum table size (64TB) using Aurora is four times the size of the maximum table size (16TB) of innodb. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A further benefit of Aurora over MySQL is replication.  In Aurora, you can create up to 15 replicas &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the most prominent drawbacks of AWS Aurora is that it is only compatible with MySQL 5.6 and 5.7. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A somewhat minor drawback is that the port number of connections to the database cannot be configured, they are locked at 3306&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another benefit is that, as you would expect, Aurora has great integration capabilities with other AWS products, for example, you can invoke an AWS Lambda function from within an AWS Aurora database cluster. You can also load data from S3 buckets. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;With AWS Aurora, the minimum RDS instance size you can use is r3.large, which will impact the cost of using AWS Aurora. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS Aurora is also not available on the AWS free tier&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>devops</category>
      <category>database</category>
    </item>
    <item>
      <title>A Brief 10-Point Guide to AWS Lambda</title>
      <dc:creator>Shane Lee</dc:creator>
      <pubDate>Wed, 12 Aug 2020 14:09:35 +0000</pubDate>
      <link>https://dev.to/shanelee/a-brief-10-point-guide-to-aws-lambda-4mhe</link>
      <guid>https://dev.to/shanelee/a-brief-10-point-guide-to-aws-lambda-4mhe</guid>
      <description>&lt;p&gt;When I'm learning new about new technologies, one of the first things, I'll do is write a numbered list 1-10 and then fill that numbered list in with points about that particular technology. I realised that these lists might be useful to others so I'm going to start posting them. This week I looked AWS Lambda. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AWS Lambda lets you run an application without rigging or managing servers. It is an event-driven computing platform. The code is executed in Lambda upon configured event trigger.&lt;/li&gt;
&lt;li&gt;AWS Lambda uses a Function as a Service (FaaS) model of cloud computing.&lt;/li&gt;
&lt;li&gt;With AWS Lambda you don't need an application that is running 24/7, as a consequence, you only pay for the time your functions were executing which can lead to a significant cost-reduction against traditional server-based architectures.&lt;/li&gt;
&lt;li&gt;Due to the nature of AWS Lambda's FaaS model of cloud computing, development times for applications can be greatly increased, because the problems of managing an application stack within a server-based context are eliminated.&lt;/li&gt;
&lt;li&gt;Planning and management of resources are efforts, which are nearly completely removed with AWS Lambda, because of its auto-scaling when more computing power is needed it will scale up the resources seamlessly, and conversely, when fewer resources are required it will scale down seamlessly too.&lt;/li&gt;
&lt;li&gt;A greater proportion of developer time is available for working on the problems and challenges of the business logic with AWS Lambda.&lt;/li&gt;
&lt;li&gt;One of the drawbacks of using AWS Lambda is that is is not necessarily faster than traditional architectures, this is because when a new instance of a function is invoked it needs to start up the process with the code to be executed. This start up time is not present in traditional server-based architectures the process or processes are running all the time.&lt;/li&gt;
&lt;li&gt;A further drawback of using AWS Lambda is the issue of concurrent executions of functions. The default &lt;em&gt;account&lt;/em&gt; limit for concurrent execution of functions is 1000, although depending on region this can go up to 3000, but this has to be specifically requested. Few applications will have to worry about this problem however. One additional thing of note about concurrent executions is that AWS Lambda does allow you to specifically limit the concurrent executions of specific functions.&lt;/li&gt;
&lt;li&gt;The current maximum execution time for a AWS Lambda function is 15 minutes, which can be problem if the function is running a task which will take longer. Although this would be a sign that the function should be decomposed where possible.&lt;/li&gt;
&lt;li&gt;A further drawback AWS Lambda is that individual functions are somewhat constrained in there access to computational resources. For example the current RAM limit of an AWS Lambda function is 3GB.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>lambda</category>
      <category>serverless</category>
      <category>devops</category>
    </item>
    <item>
      <title>Keepgrabbing.py Analysed Line-by-Line - Aaron Swartz JSTOR Script</title>
      <dc:creator>Shane Lee</dc:creator>
      <pubDate>Tue, 11 Aug 2020 18:05:06 +0000</pubDate>
      <link>https://dev.to/shanelee/keepgrabbing-py-analysed-line-by-line-aaron-swartz-jstor-script-fk4</link>
      <guid>https://dev.to/shanelee/keepgrabbing-py-analysed-line-by-line-aaron-swartz-jstor-script-fk4</guid>
      <description>&lt;p&gt;Aaron Swartz was a programmer and political activist, who infamously downloaded an estimated 4.8 million articles from the JSTOR database of academic articles. This led him to be prosecuted by the United States. &lt;/p&gt;

&lt;p&gt;In the documentary "The Internet's Own Boy" about Aaron Swartz, there is a script that is referenced called KeepGrabbing.py. This script is what Aaron used to bulk download PDFs from the JSTOR database from within the MIT network. &lt;/p&gt;

&lt;p&gt;When first saw the documentary, I was fascinate by the idea that a simple computer program could cause such furore. Naturally, I wanted to know what was in the program. &lt;br&gt;
It turns out this program is just a simple python 2 script, that is only 21 lines long (17 if you don't include blank lines!)&lt;/p&gt;

&lt;p&gt;Here is the excerpt from the documentary in which the script is briefly discussed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=j0DLmgmh2N8"&gt;https://www.youtube.com/watch?v=j0DLmgmh2N8&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I managed to find the script online. But I didn't immediately understand it. I got the general gist, but there were a few things I had not seen before like the one line class which Aaron defines which is just an exception that appears to just do nothing. There's also a URL which has been reacted by the courts, which further makes this program difficult to understand. &lt;/p&gt;

&lt;p&gt;So let's look through the program and try and understand it line-by-line.&lt;/p&gt;

&lt;p&gt;Here is the file keepgrabbing.py:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```import subprocess, urllib, random&lt;br&gt;
class NoBlocks(Exception): pass&lt;br&gt;
def getblocks():&lt;br&gt;
    r = urllib.urlopen("http://{?REDACTED?}/grab").read()&lt;br&gt;
    if '&amp;lt;html' in r.lower(): raise NoBlocks&lt;br&gt;
    return r.split()&lt;/p&gt;

&lt;p&gt;import sys&lt;br&gt;
if len(sys.argv) &amp;gt; 1:&lt;br&gt;
    prefix = ['--socks5', sys.argv[1]]&lt;br&gt;
else:&lt;br&gt;
    prefix = []#'-interface','eth0:1']&lt;br&gt;
line = lambda x: ['curl'] + prefix + ['-H', "Cookie: TENACIOUS=" + str(random.random())[3:], '-o', 'pdfs/' + str(x) + '.pdf', "&lt;a href="http://www.jstor.org/stable/pdfplus/"&gt;http://www.jstor.org/stable/pdfplus/&lt;/a&gt;" + str(x) + ".pdf?acceptTC=true"]&lt;/p&gt;

&lt;p&gt;while 1:&lt;br&gt;
    blocks = getblocks()&lt;br&gt;
    for block in blocks:&lt;br&gt;
        print block&lt;br&gt;
        subprocess.Popen(line(block)).wait()```&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This is written in python2.&lt;br&gt;
I because we don't have the URL which is reacted, some of the notes here are my best interpretation.&lt;/p&gt;

&lt;p&gt;The imports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;subprocess - allows you to create new processes from the python script.
  subprocesses are child processes created from another process.&lt;/li&gt;
&lt;li&gt;urllib - allows you to retrieve resources from URL.&lt;/li&gt;
&lt;li&gt;random - generates pseudo-random numbers (i.e. not truly random numbers)&lt;/li&gt;
&lt;li&gt;sys - imported later. Enables access to parameters and functions specific
 to the machine that is running the code.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;import subprocess, urllib, random&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;After a little bit of investigation, I realised the one-line class NoBlocks that Aaron had included in this script was a way of terminating the script (more on this later).&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;class NoBlocks(Exception): pass&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The next bit of code is the method getblocks().&lt;br&gt;
This function reads from a URL which has been reacted by the courts.&lt;/p&gt;

&lt;p&gt; It looks like this function called to custom url which was likely set up by Swartz himself, which had a list of URLs linking to PDFs to download. It is likely the case that Swartz had this grab page setup and would control and modify it from out side of the MIT campus in order to direct the script to download the PDFs he wanted. The first line in this function calls urllib.urlopen().read and saves the response of this call to a variable called 'r'. The urlopen function reads from a URL and returns a file-like object from the contents of the external resource that the URL points to. The read function that is called on this simply reads the byte contents and returns them.&lt;/p&gt;

&lt;p&gt;The second line of this function checks to see if there is HTML in the retrieved page. If there is then it raises a NoBlocks exception and exits the script. It is likely that the URL that is reacted simply was a text file with the PDFs Swartz wanted to download. When he wanted to stop the script he could simply swap this text file for a HTML file and the script would exit.&lt;/p&gt;

&lt;p&gt;The split function simply takes a string and splits it into a list and by default, it will split the string at every space, which is what Aaron is doing here.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;def getblocks():&lt;br&gt;
    r = urllib.urlopen("http://{?REDACTED?}/grab").read()&lt;br&gt;
    if '&amp;lt;html' in r.lower(): raise NoBlocks&lt;br&gt;
    return r.split()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The next 5 lines of code are concerned with taking the arguments to the script from the sys.argv and if there is one present adding it to a variable as a list with the string - socks5 as the first string in the list.&lt;/p&gt;

&lt;p&gt;Note that it takes the second element in the sys.argv list as the first element in the sys.argv list is the name of the script.&lt;/p&gt;

&lt;p&gt;This prefix variable will be used in a lamda expression below.&lt;br&gt;
Basically, this prefix is used to make the script connect to JSTOR via a proxy or just though the computer's internet connection (which Aaron left a command about, suggesting this was an ethernet connection, which makes sense as the computer that Aaron used to run this script was in a store cupboard connected to the MIT network)&lt;/p&gt;

&lt;p&gt;This line may mean that Aaron could run this script from outside the MIT network, but that is just speculation.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import sys&lt;br&gt;
if len(sys.argv) &amp;gt; 1:&lt;br&gt;
    prefix = ['--socks5', sys.argv[1]]&lt;br&gt;
else:&lt;br&gt;
    prefix = []#'-interface','eth0:1']&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;The next line declares a lambda function which is saved to the variable called line.&lt;/p&gt;

&lt;p&gt;This lambda expression takes a single argument, which is the name of the PDF that the script is going to download.&lt;/p&gt;

&lt;p&gt;This lambda expression will later be used as part of a subprocess call later in the script. It defines a curl request. The curl command is a command which allows you&lt;br&gt;
to transfer data to or from a URL, i.e upload or download from a url. The curl request is with a proxy to connect via (depending on the conditional above as mentioned). Next, it defines a cookie, which is simply the string TENACIOUS= followed by a random 3-digit number. This cookie, will make the server responding to this curl request think that it is coming from a real user as opposed to a script. The next thing this function does is define the output of this curl request: the pdf file name to a directory called pdfs. The rest of this lambda creates the url of the PDF from which to download the PDF with using curl.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;line = lambda x: ['curl'] + prefix + ['-H', "Cookie: TENACIOUS=" + str(random.random())[3:], '-o', 'pdfs/' + str(x) + '.pdf', "http://www.jstor.org/stable/pdfplus/" + str(x) + ".pdf?acceptTC=true"]&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;This next section of code. Defines an infinite loop, which is the part of the code that composes everything else.&lt;/p&gt;

&lt;p&gt;First it calls the getblocks from earlier and saves the resulting list of PDFs to a variable called blocks.&lt;br&gt;
It then iterates over these, printing them to the console and then calling the line lambda from earlier in a subprocess.Popen call. Subprocess Popen will create a new process, in this case the curl request that will download the current PDF. Then the script will block until this subprocess finishes, i.e. it will wait until the PDF is finished downloading and then it will move on to the next PDF.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;while 1:&lt;br&gt;
    blocks = getblocks()&lt;br&gt;
    for block in blocks:&lt;br&gt;
        print block&lt;br&gt;
        subprocess.Popen(line(block)).wait()&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;And that's it!&lt;/p&gt;

&lt;p&gt;I have also made a video where I go through this code, if that sort of thing floats your goat:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=0sJ7CVos5bQ"&gt;https://www.youtube.com/watch?v=0sJ7CVos5bQ&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>webscraping</category>
      <category>aaronswartz</category>
      <category>mit</category>
    </item>
    <item>
      <title>How to Plot a Correlation with Python | Python for Statistics</title>
      <dc:creator>Shane Lee</dc:creator>
      <pubDate>Fri, 08 May 2020 07:52:58 +0000</pubDate>
      <link>https://dev.to/shanelee/how-to-plot-a-correlation-with-python-python-for-statistics-5ef</link>
      <guid>https://dev.to/shanelee/how-to-plot-a-correlation-with-python-python-for-statistics-5ef</guid>
      <description>&lt;p&gt;Plotting correlations with Python is a relatively straight-forward affair. For this example, I have provided a basic correlation dataset which is in a CSV file. If you have your own dataset, you can obviously use that, although if you have it in a different format, you will likely have to import it into your Python code differently.&lt;/p&gt;

&lt;p&gt;In order to follow along with this, first open your terminal and install the following Python modules unless you have already.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install numpy&lt;br&gt;
pip install pandas&lt;br&gt;
pip install matplotlib&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;Then create and open a new .py file and add those modules as imports like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The ‘as …’ allows us to alias the module to a more succinct series of characters and allow for more idiomatic Python code. For example it would be an absolute ballache to type out matplotlib.pyplot every time we wanted to access a function from that module, so instead we alias it to ‘plt’ and then we can simply call plt.whatever whenever we want to use function from that module.&lt;/p&gt;

&lt;p&gt;Next we need to get the data into the programme. For this i’m going to assume you have the data saved in the same directory as your .py file. My example dataset which can be downloaded from the link below is called ‘memes.csv’. In this dataset we have two columns which we want to correlate. ‘Memes’ and ‘Dankness’. Note that this is case sensitive. Ideally you wouldn’t mix cases in your column names, but I have because I’m a buffoon and it’s too late to change it now.&lt;/p&gt;

&lt;p&gt;We can use the read_csv function from the pandas python module to import the dataset. This will take the csv and turn into a lovely pandas DataFrame, which makes it nice and easy to manipulate the data. In order to access the individual columns we can simply pass the column names as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;data = pd.read_csv('memes.csv')
x = data['Memes']
y = data['Dankness']
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now we have two variables, x and y, which we can correlate.&lt;/p&gt;

&lt;p&gt;To do this, we can simply call the plt.scatter function, passing in our data. If we add the plt.show() function and run the programme we will see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jX5LYd7a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vsmzxgyk5kinudvtfl3n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jX5LYd7a--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vsmzxgyk5kinudvtfl3n.png" alt="Python generated correlation with Matplotlib and pandas"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Python generated correlation with Matplotlib and pandas&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plt.scatter(x, y) 
plt.show()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But we’re not finished there. As any mathematics teacher will say, we need to add titles to the plot and axes, and we need to add a line of best fit.&lt;/p&gt;

&lt;p&gt;Adding the titles is the simplest thanks to matplotlib, so let’s start with that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plt.title('A plot to show the correlation between memes and dankness')
plt.xlabel('Memes')
plt.ylabel('Dankness')
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In order to add the line of best fit we need to do the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plt.plot(np.unique(x), np.poly1d(np.polyfit(x, y, 1))(np.unique(x)), color='yellow')
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally if we wanted to print the correlation coefficient, we could use the numpy function corrcoef like so :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;print(np.corrcoef(x, y))```



Here is the full code from this tutorial:



```import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

data = pd.read_csv('memes.csv')
x = data['Memes']
y = data['Dankness']

print(np.corrcoef(x, y))

plt.scatter(x, y) 
plt.title('A plot to show the correlation between memes and dankness')
plt.xlabel('Memes')
plt.ylabel('Dankness')
plt.plot(np.unique(x), np.poly1d(np.polyfit(x, y, 1))(np.unique(x)), color='yellow')
plt.show()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This post was originally published &lt;a href="https://codeyogi.co.uk/2020/03/17/how-to-plot-a-correlation-with-python-python-for-statistics/"&gt;here&lt;/a&gt;, where you can also download the example dataset we used for this tutorial.&lt;/p&gt;

</description>
      <category>python</category>
      <category>datascience</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Visualise Multiple Stocks with Matplotlib</title>
      <dc:creator>Shane Lee</dc:creator>
      <pubDate>Fri, 31 Jan 2020 19:07:41 +0000</pubDate>
      <link>https://dev.to/shanelee/how-to-visualise-multiple-stocks-with-matplotlib-4050</link>
      <guid>https://dev.to/shanelee/how-to-visualise-multiple-stocks-with-matplotlib-4050</guid>
      <description>&lt;p&gt;In this quick tutorial, we are going to use python to get data about a collection of stocks, and then plot then on a single graph. &lt;/p&gt;

&lt;p&gt;The very first thing we need to is find the tickers for the stocks that we want to plot. &lt;/p&gt;

&lt;p&gt;So go to Yahoo Finance and search for the companies you are interested in. &lt;/p&gt;

&lt;p&gt;When you get to the company's listing you will see the ticker in parentheses next to the company's name. &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%2F0n2wpd168ppa2dvgfhmp.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%2F0n2wpd168ppa2dvgfhmp.png" alt="An example of United Utilities from the Yahoo Finance page."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An example of United Utilities from the Yahoo Finance page.&lt;/p&gt;

&lt;p&gt;Once you have the list of companies you want to plot. It's time to start coding. &lt;/p&gt;

&lt;p&gt;First we need a few imports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import numpy as np
import pandas as pd
from pandas_datareader import data as wb
import matplotlib.pyplot as plt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't have any of these installed. Go to your terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install pandas
pip install numpy
pip install pandas-datareader
pip install matplotlib
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's create an array of stock objects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stocks = [
    {
        'ticker': 'UU.L',
        'name': 'United Utilities'
    },
    {
        'ticker': 'VOD.L',
        'name': 'Vodafone Group'
    },
    {
        'ticker': 'BP.L',
        'name': 'BP Group'
    }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next let's create a method to take this data and plot the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def create_plot(stocks):
    # Create an empty dataframe
    data = pd.DataFrame()
    for stock in stocks: 
        # Create a column for the adjusted close of each stock
        # Here we use the DataReader library to get the data.
        data[stock['ticker']] = wb.DataReader(stock['ticker'], data_source='yahoo', start='2007-1-1')['Adj Close']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here's what the contents of the data frame currently looks like:&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%2F8vw558nhnvi94fyj4wt3.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%2F8vw558nhnvi94fyj4wt3.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see that adjusted close prices for each stock at present their own columns. &lt;/p&gt;

&lt;p&gt;The problem with the current state of the data is that we can't easily plot this data as if we did, all the of the stocks would displayed on different scales. &lt;/p&gt;

&lt;p&gt;So what we need to do is change this data to be the percentage return between each date and the first date in the series. &lt;/p&gt;

&lt;p&gt;To do this we can use a lovely bit of pythonic code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Calculate the returns for all the days
returns = data.apply(lambda x: (x / x[0] * 100))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are using a lambda expression to turn create a new data frame which contains the percent returns of each of the days for each of the stocks.&lt;/p&gt;

&lt;p&gt;That's all we have to do to get and adjust the data. &lt;/p&gt;

&lt;p&gt;Now all we have do is plot the data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plt.figure(figsize=(10,6))

# Plot the returns
for stock in stocks: 
plt.plot(returns[stock['ticker']], label=stock['name'])

# We need to call .legend() to show the legend.
plt.legend()
# Give the axes labels
plt.ylabel('Cumulative Returns %')
plt.xlabel('Time')
plt.show()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we're done. &lt;/p&gt;

&lt;p&gt;You can find the full code here: &lt;a href="https://codeyogi.co.uk/2019/12/30/visualising-multiple-stocks-with-matplotlib/" rel="noopener noreferrer"&gt;Full Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I've also made a video tutorial to go alongside this tutorial.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.youtube.com/watch?v=vKWf5skmGAI" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fimg.youtube.com%2Fvi%2FvKWf5skmGAI%2F0.jpg" alt="Python For Finance | Visualising Multiple Stocks with Matplotlib"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions or have any feedback (definitely welcome!), then please leave a comment below, or you can find me at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://youtube.com/shaneLeeCoding" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/ShaneLee" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://codeyogi.co.uk/" rel="noopener noreferrer"&gt;CodeYogi&lt;/a&gt;
​&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Article originally posted &lt;a href="https://codeyogi.co.uk/2019/12/30/visualising-multiple-stocks-with-matplotlib/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>matplotlib</category>
      <category>finance</category>
      <category>pandas</category>
    </item>
  </channel>
</rss>
