<?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: Charles White</title>
    <description>The latest articles on DEV Community by Charles White (@charlesw001).</description>
    <link>https://dev.to/charlesw001</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%2F547540%2F5b0e6757-7c36-4fe0-b638-51f63acdfe01.jpg</url>
      <title>DEV Community: Charles White</title>
      <link>https://dev.to/charlesw001</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/charlesw001"/>
    <language>en</language>
    <item>
      <title>Getting Historical Stock Data Using Python</title>
      <dc:creator>Charles White</dc:creator>
      <pubDate>Sun, 16 May 2021 00:26:03 +0000</pubDate>
      <link>https://dev.to/charlesw001/getting-historical-stock-data-using-python-2o0h</link>
      <guid>https://dev.to/charlesw001/getting-historical-stock-data-using-python-2o0h</guid>
      <description>&lt;p&gt;There's an easy way to get stock data using pandas_datareader from yahoo finance which uses basics of pandas dataframe and also doing a moving average. It actually only takes a few lines of code and can help you in your data pipeline.  This is just the quick snippet to get you going, if you want to see the full article you can scroll to the bottom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extracting data from yahoo with Pandas
&lt;/h2&gt;

&lt;p&gt;We will be using Yahoo Finance for obtaining stock data. Firstly we will import pandas_datareader.data then send a request to yahoo finance with ticker , start and end date. The “pandas_datareader” module is a useful module that abstracts extracting web data very easily. You don’t have to bother with “requests” or “urllib” and parse the HTML data, this is all done for you! From the module in response we will get a dataframe containing our data in rows and columns . The columns are basically High , Low , Open , Close , Volume and Adj Close.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas_datareader.data as web
import datetime as dt

ticker = "AAPL" # This is Apple's ticker
start = dt.datetime(2020,1,1) # Starting date in format (year,month,day)
end = dt.datetime(2020,12,1) # Ending date 

df = web.DataReader(ticker,"yahoo",start,end)
print(df.head()) # Prints first 5 columns of data
print(df.shape) # Prints the number of rows and columns
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get the output:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo0apqru4fvys2m5kr6ku.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo0apqru4fvys2m5kr6ku.png" alt="Output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;df = web.DataReader(ticker,"yahoo",start,end) - This stores the dataframe obtained in the variable df. The first value passed here is ticker i.e. “AAPL” , second is the source name . As we are using yahoo finance here so it should be “yahoo”. Then the end and start date (in the form of datetime). You can see other data sources here.&lt;/li&gt;
&lt;li&gt;print(df.head()) - It prints the first 5 columns of the data obtained.&lt;/li&gt;
&lt;li&gt;print(df.shape) - Prints the rows and columns in the dataframe . As seen in output there are 241 rows and 6 columns&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  There's more..
&lt;/h3&gt;

&lt;p&gt;There's still want to know more you can find out all of these and more at our full article: &lt;a href="https://pythonhowtoprogram.com/getting-historical-stock-data-using-python-3/?utm_source=dev.to&amp;amp;utm_medium=cp&amp;amp;utm_campaign=ctalink&amp;amp;utm_term=historical-stock-data-article"&gt;Full article: how to get and chart historical stock data&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>datascience</category>
      <category>stockdata</category>
    </item>
    <item>
      <title>Execute commands from the command line in a python program</title>
      <dc:creator>Charles White</dc:creator>
      <pubDate>Sun, 16 May 2021 00:15:02 +0000</pubDate>
      <link>https://dev.to/charlesw001/execute-commands-from-the-command-line-in-a-python-program-3edn</link>
      <guid>https://dev.to/charlesw001/execute-commands-from-the-command-line-in-a-python-program-3edn</guid>
      <description>&lt;p&gt;While working in Python you may come across cases where you want a quick way to run programs from the command line. This could be your own python scripts or any other command line program. This is where the subprocess module can come into play.&lt;/p&gt;

&lt;p&gt;The subprocess module, present in a standard installation of Python is used to run new applications or programs through Python code by creating new processes.&lt;/p&gt;

&lt;p&gt;It gives us the ability to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;spawn new processes&lt;/li&gt;
&lt;li&gt;connect to their input, output and error pipes&lt;/li&gt;
&lt;li&gt;obtain their return codes&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A common use for subprocess would be to list files and folders in a directory. This makes use of the run method of subprocess.&lt;/p&gt;

&lt;p&gt;The code will differ depending on what operating system you are on. For example, on a windows based computer this would be using the command dir&lt;/p&gt;

&lt;h4&gt;
  
  
  For Linux
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import subprocess

subprocess.run('ls')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  For Windows
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import subprocess

subprocess.run("dir", shell=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above we have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;import subprocess module&lt;/li&gt;
&lt;li&gt;call the run module from it&lt;/li&gt;
&lt;li&gt;pass the list directory command based on your system (ls/dir). If you are on Windows you will have to additionally pass shell=True because dir is a shell command and you need to tell the system that you want to use it.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;We automatically got output in the terminal even though we did not print it ourselves. That is how the run command works – it does not capture our command output by default.&lt;/p&gt;

&lt;p&gt;Let’s see what happens if we try to capture our command by placing it in a variable&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import subprocess

result = subprocess.run("dir", shell=True)

print(result)
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkuckqzwhx0yeeqqhycyu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkuckqzwhx0yeeqqhycyu.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The output is not what you would expect. We get the output still, and a message containing the arguments that were passed and the return code.&lt;/p&gt;

&lt;p&gt;If we wanted to capture the output we would modify out code to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import subprocess

result = subprocess.run(["dir"], shell=True, capture_output=True, text=True)

print(result.stdout)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have added:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;capture_output=True&lt;/code&gt;: to capture the output&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text=True&lt;/code&gt;: to decode the output to a readable format since it is captured as bytes&lt;/li&gt;
&lt;li&gt;We then &lt;code&gt;print result.stdout&lt;/code&gt; : the result as standard output &lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The same can be achieved with the follow code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import subprocess

result = subprocess.run(["ls", "-la"], stdout=subprocess.PIPE, text=True)

print(result.stdout)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is stdout=subprocess.PIPE This code performs the same function as capture_output=True&lt;/p&gt;

&lt;p&gt;In addition, we use the ls command with the argument of -la both passed as a list &lt;/p&gt;

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

&lt;h3&gt;
  
  
  There's more..
&lt;/h3&gt;

&lt;p&gt;There's still more you can do with subprocess including outputting to a file, reading data from a file, and to trigger programs interactively to name a few things.  Find out all of these and more at: &lt;a href="https://pythonhowtoprogram.com/use-subprocess-to-execute-commands-in-python-3/?utm_source=dev.to&amp;amp;utm_medium=cp&amp;amp;utm_campaign=ctalink&amp;amp;utm_term=subprocess-article"&gt;Full Article at PythonHowToProgam&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>automation</category>
    </item>
    <item>
      <title>Supercharge your python code with Decorators</title>
      <dc:creator>Charles White</dc:creator>
      <pubDate>Sat, 30 Jan 2021 17:34:20 +0000</pubDate>
      <link>https://dev.to/charlesw001/get-your-head-around-python-decorators-2i34</link>
      <guid>https://dev.to/charlesw001/get-your-head-around-python-decorators-2i34</guid>
      <description>&lt;h1&gt;
  
  
  What is a decorator?
&lt;/h1&gt;

&lt;p&gt;A decorator is a feature in python that allows you to add extra capabilities to your function, without having to change the inner workings of your function.  &lt;/p&gt;

&lt;p&gt;Some examples of uses of decorators include: determining the execution time of a function, determine which URL call should result in this function being called, adding logging messages when a function starts/stops. There are many uses for this.&lt;/p&gt;

&lt;p&gt;More technically, a decorator is a function that takes another function as an argument, adds some functionality then returns another function. This happens without altering the original source code of the function that was passed.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Concept Behind Decorators
&lt;/h1&gt;

&lt;p&gt;So the above should explain the power of decorators. So how does it actually work? Well it’s a combination of a few interesting features in python:&lt;/p&gt;

&lt;p&gt;Functions are First-Class Objects: this means you can assign functions to variables, pass them as arguments, and return them as values from other functions.&lt;br&gt;
Scope / Closure: this specifically refers to how a nested function that has access to variable(s) from its enclosing function.&lt;/p&gt;

&lt;p&gt;It’s these two things that make it possible to have decorators. This is a diagram that shows what happens conceptually. The actual call to the original function is circumvented to call the decorator which encapsulates the call to the original call with some additional functionality. That’s where the magic lies&lt;/p&gt;

&lt;p&gt;See the following diagram that helped me to conceptualise the flow which was really helpful.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w3dO-b7V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8dtxd049ci8bvlqjbrpc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w3dO-b7V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/8dtxd049ci8bvlqjbrpc.png" alt="Screenshot 2021-01-31 at 1.10.59 AM"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To find out more about decorators including a practical example using parameters, you can see our full article  &lt;a href="https://pythonhowtoprogram.com/simple-guide-to-decorators-in-python-3-when-and-how-to-use-them/?utm_source=dev.to&amp;amp;utm_medium=cp&amp;amp;utm_campaign=ctalink&amp;amp;utm_term=decorator-article"&gt;Simple Guide To Decorators in Python 3 – When and How to Use Them&lt;/a&gt;.   The articles show examples with code you can readily cut and paste.&lt;/p&gt;

</description>
      <category>python</category>
    </item>
    <item>
      <title>Add Some Colour To Your Python Logs</title>
      <dc:creator>Charles White</dc:creator>
      <pubDate>Mon, 04 Jan 2021 14:48:29 +0000</pubDate>
      <link>https://dev.to/charlesw001/add-some-colour-to-your-python-logs-3g3h</link>
      <guid>https://dev.to/charlesw001/add-some-colour-to-your-python-logs-3g3h</guid>
      <description>&lt;p&gt;Logging is an essential part of any mid-large size application which will give you an idea of the inner working of your code.   Once you get beyond a small application, just using print statements can be quite cumbersome and difficult to maintain.&lt;/p&gt;

&lt;p&gt;The python &lt;code&gt;logging&lt;/code&gt; library is already very useful to allow you to create output of logs, but then they can be quite difficult to read.  It can be especially difficult when you are trying to trace through an execution to debug what happened.&lt;/p&gt;

&lt;p&gt;This is where the &lt;code&gt;colorlogs&lt;/code&gt; library can really help.  With the library you can add some color based on types of logging messages - e.g. red for error, blue for debug etc.&lt;/p&gt;

&lt;p&gt;See the following code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import coloredlogs, logging

mylogs = logging.getLogger(__name__)

coloredlogs.install(level=logging.DEBUG, logger=logger)
# Some examples.
mylogs.debug("This is debug")
mylogs.info("This is info")
mylogs.warning("This is warning")
mylogs.error("This is an error")
mylogs.critical("This is a critical message")
&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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftr6qzd0tp2a23kwwa21c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftr6qzd0tp2a23kwwa21c.png" alt="colored-output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;coloredlogs&lt;/code&gt; creates a stream handler and attaches it to the logger passed. It has its own default format and colour settings which can be customised as per interest. Lets first look at the few important parameters we can pass in &lt;code&gt;coloredlogs.install()&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;level&lt;/code&gt; - An integer to denote the level. (Remember logging.DEBUG returns an integer)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;logger&lt;/code&gt; - Name of the logger in which this stream handler has to be attached. (Performs same act as &lt;code&gt;logger.add_handler()&lt;/code&gt; )&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fmt&lt;/code&gt; - A string denoting the format style.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;datefmt&lt;/code&gt; - A string denoting the format of asctime .&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;level_styles&lt;/code&gt; - A dictionary containing the data of level and their colors&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;field_styles&lt;/code&gt; - A dictionary containing the data of field and their colors &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To find out more about setting up logs, you can see our full article &lt;a href="https://pythonhowtoprogram.com/logging-in-python-3-how-to-output-logs-to-file-and-console/?utm_source=dev.to&amp;amp;utm_medium=cp&amp;amp;utm_campaign=ctalink&amp;amp;utm_term=logging-in-python-3-how-to-output-logs-to-file-and-console"&gt;Logging in Python 3, How To Output Logs to File and Console&lt;/a&gt; .  We give tips on how to setup log output both to a screen and a file, as well as other great tips.&lt;/p&gt;

</description>
      <category>python</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Plugin Architecture in Python </title>
      <dc:creator>Charles White</dc:creator>
      <pubDate>Tue, 29 Dec 2020 16:31:53 +0000</pubDate>
      <link>https://dev.to/charlesw001/plugin-architecture-in-python-jla</link>
      <guid>https://dev.to/charlesw001/plugin-architecture-in-python-jla</guid>
      <description>&lt;p&gt;For some of your Python applications, a plugin architecture could really help you to extend the functionality of your applications without affecting the core structure of your application. Why would you want to do this? Well, it helps you to separate the core system and allows either yourself or others to extend the functionality of the core system safely and reliably. &lt;/p&gt;

&lt;p&gt;Some of the advantages include that when a new plugin is created, for example, you would just need to test the plugin and the whole application. The other big advantage is that your application can grow by your community making your application even more appealing. Two classic examples are the plugins for Wordpress blog and the plugins for Sublime text editor. In both cases, the plugins enhance the functionality of the core system but the core system developer did not need to create the plugin.&lt;/p&gt;

&lt;p&gt;There are disadvantages too however with one of the main ones being that you can only extend the functionality based on the constraints that is imposed on the plugin placeholder e.g. if an app allows plugins for formatting text in a GUI, it's unlikely you can create a plugin to play videos.&lt;/p&gt;

&lt;p&gt;There are several methods to create a plugin architecture, here we will walkthrough the approach using &lt;code&gt;importlib&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Basic Structure Of A Plugin Architecture
&lt;/h2&gt;

&lt;p&gt;At its core, a plugin architecture consists of two components: a core system and plug-in modules.   The main key design here is to allow adding additional features that are called plugins modules to our core system, providing extensibility, flexibility, and isolation to our application features. This will provide us with the ability to add, remove, and change the behaviour of the application with little or no effect on the core system or other plug-in modules making our code very modular and extensible .&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3oromcydjo3ucbpqm3jj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3oromcydjo3ucbpqm3jj.png" alt="plugin2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Core System
&lt;/h3&gt;

&lt;p&gt;The core system defines how it operates and the basic business logic. It can be understood as the workflow, such as how the data flow inside the application, but, the steps involved inside that workflow is up to the plugin(s).  Hence, all extending plugins will follow that generic flow providing their customised implementation, but not changing the core business logic or the application's workflow.&lt;/p&gt;

&lt;p&gt;In addition, it also contains the common code being used (or has to be used) by multiple plugins as a way to get rid of duplicate and boilerplate code, and have one single structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Plug-in Modules
&lt;/h3&gt;

&lt;p&gt;On the other hand, plug-ins are stand-alone, independent components that contain, additional features, and custom code that is intended to enhance or extend the core system.  The plugins however, must follow a particular set of standards or a framework imposed by the core system so that the core system and plugin must communicate effectively.  A real world example would be a car engine - only certain car engines ("plugins") would fit into a Toyota Prius as they follow the specifications of the chassis/car ("core system")&lt;/p&gt;

&lt;p&gt;The independence of each plugin is the best approach to take.  It is not advisable to have plugins talk to each other, unless, the core system facilitates that communication in a standardized way so that independent plugins can talk to each other.  Either way, it is simpler to keep the communication and the dependency between plug-ins as minimal as possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Core System
&lt;/h2&gt;

&lt;p&gt;As mentioned before, we will have a core system and zero or more plugins which will add features to our system, so, first of all, we are going to build our core system (we will call this file core.py) to have the basis in which our plugins are going to work. To get started we are going to create a class called "MyApplication" with a run() method which prints our workflow&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#core.py
class MyApplication:
    def __init__(self, plugins:list=[]):
        pass
    # This method will print the workflow of our application
    def run(self):
        print("Starting my application")
        print("-" * 10)
        print("This is my core system")
        print("-" * 10)
        print("Ending my application")
        print()


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

&lt;/div&gt;

&lt;p&gt;Now we are going to create the main file, which will import our application and execute the run() method&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#main.py
# This is a main file which will initialise and execute the run method of our application

# Importing our application file
from core import MyApplication

if __name__ == "__main__":
    # Initialising our application
    app = MyApplication() 
    # Running our application 
    app.run()  


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

&lt;/div&gt;

&lt;p&gt;And finally, we are run our main file which result  is the following: &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5hiwo8aict4dadyf2bzd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5hiwo8aict4dadyf2bzd.png" alt="Screenshot-2020-12-28-145146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that we have a simple application which prints it's own workflow, we are going to enhance it so we can have an application which supports plugins, in order to perform this, we are going to modify the &lt;strong&gt;init&lt;/strong&gt;() and run() methods.&lt;/p&gt;

&lt;h2&gt;
  
  
  The  importlib  package
&lt;/h2&gt;

&lt;p&gt;In order to achieve our next goal, we are going to use the importlib which provide us with the power of implement the import statement in our &lt;strong&gt;init&lt;/strong&gt;() method so we are going to be able to dynamically import as many packages as needed.  It's these packages that will form our plugins&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#core.py
import importlib

class MyApplication:
    # We are going to receive a list of plugins as parameter
    def __init__(self, plugins:list=[]):
        # Checking if plugin were sent
        if plugins != []:
            # create a list of plugins
            self._plugins = [
                # Import the module and initialise it at the same time
                importlib.import_module(plugin,".").Plugin() for plugin in plugins
            ]
        else:
            # If no plugin were set we use our default
            self._plugins = [importlib.import_module('default',".") .Plugin()]


    def run(self):
        print("Starting my application")
        print("-" * 10)
        print("This is my core system")

        # We is were magic happens, and all the plugins are going to be printed
        for plugin in self._plugins:
            print(plugin)

        print("-" * 10)
        print("Ending my application")
        print() 


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

&lt;/div&gt;

&lt;p&gt;The key line is "&lt;code&gt;importlib.import_module&lt;/code&gt;" which imports the package specified in the first string variable with a ".py" extension under the current directory (specified by "." second argument).  So for example, the file "&lt;code&gt;default.py&lt;/code&gt;" which is present in the same directory would be imported by calling: &lt;code&gt;importlib.import_module('default', '.')&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The second thing to note is that we have ".Plugin()" appended to the importlib statement: &lt;code&gt;importlib.import_module(plugin,".").Plugin()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This (specifically the trailing brackets Plugin() is present) to create an instance of the class and store it into _plugins internal variable.  &lt;/p&gt;

&lt;p&gt;We are now ready to create our first plugin, the default one, if we run the code at this moment it is going to raise a ModuleNotFoundError exception due to we have not created our plugin yet. So let's do it!.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating default plugin
&lt;/h2&gt;

&lt;p&gt;Keep in mind that we are going to call all plugins in the same way, so files have to be named as carefully, in this sample, we are going to create our "&lt;code&gt;default&lt;/code&gt;" plugin, so, first of all, we create a new file called "&lt;code&gt;default.py&lt;/code&gt;" within the same folder than our &lt;code&gt;main.py&lt;/code&gt; and &lt;code&gt;core.py&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once we have a file we are going to create a class called "&lt;code&gt;Plugin&lt;/code&gt;", which contains a method called process.  This can also be a static method in case you want to call the method without instantiating the calls. It's important that any new plugin class is named the same so that these can be called dynamically&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#deafult.py
# Define our default class 
class Plugin:
    # Define static method, so no self parameter 
    def process(self, num1,num2):
        # Some prints to identify which plugin is been used
        print("This is my default plugin") 
        print(f"Numbers are {num1} and {num2}") 


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

&lt;/div&gt;

&lt;p&gt;At this moment we can run our main.py file which will print only the plugin name.  We should not get any error due to we have created our default.py plugin.  This will print out the module (from the print statement under the MyApplicaiton.run() module) object itself to show that we have successfully imported out the plugin&lt;/p&gt;

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

&lt;p&gt;Let's now modify just one line in our &lt;code&gt;core.py&lt;/code&gt; file so we call the &lt;code&gt;process()&lt;/code&gt; method instead of printing the module object&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

#core.py
import importlib

class MyApplication:
    # We are going to receive a list of plugins as parameter
    def __init__(self, plugins:list=[]):
        # Checking if plugin were sent
        if plugins != []:
            # create a list of plugins
            self._plugins = [
                importlib.import_module(plugin,".").Plugin() for plugin in plugins
            ]
        else:
            # If no plugin were set we use our default
            self._plugins = [importlib.import_module('default',".").Plugin()]


    def run(self):
        print("Starting my application")
        print("-" * 10)
        print("This is my core system")

        # Modified for in order to call process method
        for plugin in self._plugins:
            plugin.process(5,3)

        print("-" * 10)
        print("Ending my application")
        print() 


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

&lt;/div&gt;

&lt;p&gt;Output as follows:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

# Output
$ py main.py 
 Starting my application
 This is my core system   
 This is my default plugin
 Numbers are 5 and 3      
 Ending my application  



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

&lt;/div&gt;

&lt;p&gt;We have successfully created our first plugin, and it is up and running.  You can see the statement "This is my default plugin" which comes from the plugin &lt;code&gt;default.py&lt;/code&gt; rather than the &lt;code&gt;main.py&lt;/code&gt; program.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Using this framework, you can easily extend this to add more plugins easily.  The key is that you don't need to change the core.py nor the main.py which helps to keep your code clean but at the same time help to extend your application.&lt;/p&gt;

&lt;p&gt;To see a more in depth version of this article and more examples, you can see the full article at &lt;a href="https://pythonhowtoprogram.com/a-plugin-architecture-for-using-importlib-in-python-3/?utm_source=dev.to&amp;amp;utm_medium=cp&amp;amp;utm_campaign=ctalink&amp;amp;utm_term=a-plugin-architecture-for-using-importlib-in-python-3"&gt;PythonHowToProgram.com&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Parse Arguments from the Command Line using argparse in Python 3</title>
      <dc:creator>Charles White</dc:creator>
      <pubDate>Sat, 26 Dec 2020 16:13:41 +0000</pubDate>
      <link>https://dev.to/charlesw001/how-to-parse-arguments-from-the-command-line-using-argparse-in-python-3-ack</link>
      <guid>https://dev.to/charlesw001/how-to-parse-arguments-from-the-command-line-using-argparse-in-python-3-ack</guid>
      <description>&lt;p&gt;Having command line parameters is an essential mechanism to manage the behaviour of your application but it can get complex to validate and extract the arguments.  In our previous article on arguments (&lt;a href="https://pythonhowtoprogram.com/how-to-use-argv-and-argc-command-line-parameters-in-python/?utm_source=dev.to&amp;amp;utm_medium=cp&amp;amp;utm_campaign=reflink"&gt;How to use argv parameters in Python&lt;/a&gt;), we went over how to use command line parameters with sys.argv. This is a useful module, but we will come across cases where we want to do more than just that. If you code enough in Python, you are most likely going to want to let users provide values for variables at runtime.&lt;/p&gt;

&lt;p&gt;This is where argparse comes in.  In this article, we are going to look into argparse - what it is. why we use it and how we parse arguments using it.&lt;/p&gt;

&lt;p&gt;argparse is a python module whose primary purpose is to create command line interfaces. This module was released as a replacement for the getopt and optparse modules because they lacked some important features.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Parse Arguments with argparse
&lt;/h2&gt;

&lt;p&gt;To understand how argparse works and how we go about making our own command line interfaces, we will begin with a simple example illustrated below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-n", "--name", required=True)
args = parser.parse_args()
print(f'Hi {args.name} , Welcome ')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confusing? Yes, I know. But let's break this down line by line:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We initially import the argparse module&lt;/li&gt;
&lt;li&gt;We then initialize the ArgumentParser object as parser&lt;/li&gt;
&lt;li&gt;We add the only argument --name, here we must specify both the shorthand and longhand versions. Either can be used when the program is run&lt;/li&gt;
&lt;li&gt;We stipulate that this argument is required&lt;/li&gt;
&lt;li&gt;We execute the parse_args() method&lt;/li&gt;
&lt;li&gt;We output the parsed argument&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;We get the output of our print statement plus the parsed argument. But what would happen if we ran the program but didn't give any arguments?  We will try that next:&lt;/p&gt;

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

&lt;p&gt;We got an error message, explaining the usage of the program and the arguments that are required. But we never added that to our code, did we? Well, not explicitly. When we added arguments for the program, argparse generates the error message if those arguments ate not given.&lt;/p&gt;

&lt;p&gt;Looking at the output once again, you will notice there is another argument,  one that we did not give -h. This is an optional argument that the program accepts. It serves as a sort of help command to describe what is required by the program. &lt;/p&gt;

&lt;p&gt;Let's parse that argument to see what output we get:&lt;/p&gt;

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

&lt;p&gt;As we see, parsing the -h argument gives a bit more detailed explanation of the program. Armed with a basic understanding of argparse we can look at another example.&lt;/p&gt;

&lt;p&gt;We are going to code our own program that simulates the same operation as ls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Import the argparse library
import argparse

import os
import sys

my_parser = argparse.ArgumentParser(description='List all the contents of a folder')

my_parser.add_argument('Path',
                       metavar='path',
                       type=str,
                       help='the path to list')

args = my_parser.parse_args()

input_path = args.Path

if not os.path.isdir(input_path):
    print('The path specified does not exist')
    sys.exit()

print('\n'.join(os.listdir(input_path)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to import a number of modules first namely os, sys, and argparse. After that we:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create the parser and assign it the name my_parser&lt;/li&gt;
&lt;li&gt;add the necessary arguments - in this case, path.
&lt;/li&gt;
&lt;li&gt;We also specify the type of the argument as string which tells argparse to check the type automatically&lt;/li&gt;
&lt;li&gt;execute the parse_args() function
&lt;/li&gt;
&lt;li&gt;create a variable named input_path and assign it args.Path - calling path on the parser&lt;/li&gt;
&lt;li&gt;run a check if the parsed directory does not exist and display an error message if it doesn't &lt;/li&gt;
&lt;li&gt;we output the inputted directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are running the program on the same directory as before:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There are many other things you can do - the original article came from &lt;a href="https://pythonhowtoprogram.com/how-to-parse-arguments-from-the-command-line-using-argparse-in-python-3/?utm_source=dev.to&amp;amp;utm_medium=cp&amp;amp;utm_campaign=ctalink"&gt;Python How To Program: Argparse library article&lt;/a&gt; where you can find the complete post.&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
