<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Clement Lelievre, Author at Be on the Right Side of Change</title>
	<atom:link href="https://blog.finxter.com/author/clementlelievre/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.finxter.com/author/clementlelievre/</link>
	<description></description>
	<lastBuildDate>Sat, 21 Jan 2023 20:11:55 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog.finxter.com/wp-content/uploads/2020/08/cropped-cropped-finxter_nobackground-32x32.png</url>
	<title>Clement Lelievre, Author at Be on the Right Side of Change</title>
	<link>https://blog.finxter.com/author/clementlelievre/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Kata Recursive Replication &#8211; Python Solution Video</title>
		<link>https://blog.finxter.com/kata-recursive-replication-python-solution-video/</link>
		
		<dc:creator><![CDATA[Clement Lelievre]]></dc:creator>
		<pubDate>Tue, 25 May 2021 08:42:41 +0000</pubDate>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=30318</guid>

					<description><![CDATA[<p>Problem Formulation The following problem formulation is taken from this Kata. Design a recursive function called replicate(times, number) that returns an array of repetitions of the number argument. For example, replicate(3, 5) should return the list [5, 5, 5]. If the times argument is negative, return an empty array. Do not use loops to solve ... <a title="Kata Recursive Replication &#8211; Python Solution Video" class="read-more" href="https://blog.finxter.com/kata-recursive-replication-python-solution-video/" aria-label="Read more about Kata Recursive Replication &#8211; Python Solution Video">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/kata-recursive-replication-python-solution-video/">Kata Recursive Replication &#8211; Python Solution Video</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem Formulation</h2>



<p>The following problem formulation is taken from <a href="https://www.codewars.com/kata/57547f9182655569ab0008c4/python" target="_blank" rel="noreferrer noopener" title="https://www.codewars.com/kata/57547f9182655569ab0008c4/python">this Kata</a>. </p>



<hr class="wp-block-separator"/>



<p>Design a recursive function called <code>replicate(times, number)</code> that returns an array of repetitions of the <code>number</code> argument. </p>



<p>For example, <code>replicate(3, 5)</code> should return the <a href="https://blog.finxter.com/python-lists/" target="_blank" rel="noreferrer noopener" title="The Ultimate Guide to Python Lists">list </a><code>[5, 5, 5]</code>. </p>



<p>If the <code>times</code> argument is negative, return an empty array.</p>



<p>Do not use <a href="https://blog.finxter.com/python-loops/" title="Python Loops" target="_blank" rel="noreferrer noopener">loops </a>to solve this problem.</p>



<h2 class="wp-block-heading">Background Resources</h2>



<ul class="wp-block-list"><li><a href="https://blog.finxter.com/recursion/" title="Recursion: A Helpful Guide in Python" target="_blank" rel="noreferrer noopener">Recursion: A Helpful Guide in Python</a></li><li><a href="https://blog.finxter.com/python-one-line-recursion/" title="Python One Line Recursion" target="_blank" rel="noreferrer noopener">Python One Line Recursion</a></li></ul>



<h2 class="wp-block-heading">Video Solution</h2>



<p>This video solution is contributed by <a href="https://blog.finxter.com/become-python-freelancer-course/" target="_blank" rel="noreferrer noopener" title="Become Python Freelancer Course">Finxter </a>Creator <strong><em>Clement</em></strong>:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="A Python Kata on Recursive Replication" width="937" height="527" src="https://www.youtube.com/embed/1CIanvydiC4?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">Code Solution</h2>



<p>Here&#8217;s the code discussed in tihs video:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">def replicate(times, number):
    # the forbidden way
    result = []
    for i in range(times):
        result.append(number)
    return result


def replicate(times, number):
    # recursive solution
    if times &lt;= 0:
        return [] # base case and exception handling
    return replicate(times-1, number) + [number]
    
    </pre>



<p>The first function uses the for loop, the second function uses the recursive solution with the base case and the recursion case. </p>



<h2 class="wp-block-heading">Where to Go From Here?</h2>



<p>Enough theory. Let’s get some practice!</p>



<p>Coders get paid six figures and more because they can solve problems more effectively using machine intelligence and automation. </p>



<p>To become more successful in coding, solve more real problems for real people. That’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?</p>



<p><strong>You build high-value coding skills by working on practical coding projects!</strong></p>



<p>Do you want to stop learning with toy projects and focus on practical code projects that earn you money and solve real problems for people?</p>



<p class="has-global-color-8-background-color has-background"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> If your answer is <strong><em>YES!</em></strong>, consider becoming a <a rel="noreferrer noopener" href="https://blog.finxter.com/become-python-freelancer-course/" data-type="page" data-id="2072" target="_blank">Python freelance developer</a>! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.</p>



<p>If you just want to learn about the freelancing opportunity, feel free to watch my free webinar <a rel="noreferrer noopener" href="https://blog.finxter.com/webinar-freelancer/" target="_blank">“How to Build Your High-Income Skill Python”</a> and learn how I grew my coding business online and how you can, too—from the comfort of your own home.</p>



<p><a href="https://blog.finxter.com/webinar-freelancer/" target="_blank" rel="noreferrer noopener">Join the free webinar now!</a></p>
<p>The post <a href="https://blog.finxter.com/kata-recursive-replication-python-solution-video/">Kata Recursive Replication &#8211; Python Solution Video</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Schedule Your Python Script for Free on Heroku</title>
		<link>https://blog.finxter.com/how-to-schedule-your-python-script-for-free-on-heroku/</link>
		
		<dc:creator><![CDATA[Clement Lelievre]]></dc:creator>
		<pubDate>Tue, 11 May 2021 19:08:36 +0000</pubDate>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<category><![CDATA[Web Scraping]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=29849</guid>

					<description><![CDATA[<p>Hey Finxters! In my last article, I showed you how to host your Streamlit/Python web app in the cloud on Heroku. Now, perhaps you thought to yourself, that’s very nice but I need my script (not necessarily a web app, by the way) to run twice a week to load this new data at work, ... <a title="How to Schedule Your Python Script for Free on Heroku" class="read-more" href="https://blog.finxter.com/how-to-schedule-your-python-script-for-free-on-heroku/" aria-label="Read more about How to Schedule Your Python Script for Free on Heroku">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/how-to-schedule-your-python-script-for-free-on-heroku/">How to Schedule Your Python Script for Free on Heroku</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="How to Schedule Your Python Script for Free on Heroku" width="937" height="527" src="https://www.youtube.com/embed/qn3Obj56wfA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>Hey Finxters!</p>



<p>In <a href="https://blog.finxter.com/how-to-build-and-host-your-python-web-app-for-free/" target="_blank" rel="noreferrer noopener">my last article</a>, I showed you how to host your Streamlit/Python web app in the cloud on <a href="http://www.heroku.com" target="_blank" rel="noreferrer noopener">Heroku</a>.</p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img fetchpriority="high" decoding="async" src="https://lh6.googleusercontent.com/6Str0Z3EiB6v7H2EYkk35aMK7pX52TX3Npw-kWExXr3AtYUhrC8f_WQhXqgzAFQaFo4KAUYfzoEG0mPONXXNm0n7764E7gsWqXUwCbW_kSlM0jWEvz9JqBwLv84jBKHFn78Ziq9L" alt="" width="600" height="315"/></figure></div>



<p>Now, perhaps you thought to yourself, that’s very nice but I need my script (not necessarily a web app, by the way) to run twice a week to load this new data at work, or to send an email to these customers every night at 3.00 a.m European time, or perhaps as a hobby, you’d like to get in your emailbox that football data freshly scraped overnight?</p>



<p>If so, then keep reading!</p>



<p>While there are many platforms allowing you to do this starting at 0€/month (AWS, Google, <a href="https://www.pythonanywhere.com/" target="_blank" rel="noreferrer noopener">Python Anywhere</a>, cron, for example), we will stick with Heroku in this tutorial, to be consistent with my previous article.</p>



<p>This article assumes you have:</p>



<ul class="wp-block-list"><li>basic knowledge of Linux command line</li><li>read <a href="https://blog.finxter.com/how-to-build-and-host-your-python-web-app-for-free/" target="_blank" rel="noreferrer noopener">my previous article</a> on pushing Python code on Heroku (recommended)</li><li>the <a href="https://devcenter.heroku.com/articles/heroku-cli" target="_blank" rel="noreferrer noopener">Heroku CLI</a> installed</li><li>basic <a href="https://blog.finxter.com/top-cheat-sheets-for-git/" target="_blank" rel="noreferrer noopener" title="Top 10 Git Cheat Sheets">Git </a>notions</li><li>a Heroku account (free) (do not forget to configure your email address)</li><li><a href="https://blog.finxter.com/subscribe/" target="_blank" rel="noreferrer noopener" title="Subscribe">basic Python</a> notions</li></ul>



<p><strong>Plan for today:</strong></p>



<h2 class="wp-block-heading">Prepare your Python script</h2>



<p>In this tutorial, I need a script in which the result is visible so that you can actually view the output, so I decided on … wait for it… <a href="https://blog.finxter.com/how-to-send-emails-in-python/" title="How to Send Emails in Python?" target="_blank" rel="noreferrer noopener">sending an email</a> with a scheduled agenda, as this will provide a very visual way to check the results and their timing.</p>



<p>So here I went, creating the folder and starting to populate it with the necessary files:&nbsp;</p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img loading="lazy" decoding="async" src="https://lh6.googleusercontent.com/govpqm9hwgPx1SF9FK--5SDvyty4HrGeJtcf74F4kWCIUhkASOHqiZGavbwXoGJf-1377__7wKc3AXsgWismjO1Z2owkw5fzonmin7kb1f6o6x4a9aUCQ-tSVxQZzLzbCb6CHwcB" alt="" width="574" height="158"/></figure></div>



<p>Then scripting this snippet:</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://lh5.googleusercontent.com/UZvtCoZzQ9UntcI4BC0Y03dor4b5y2DuAqQ-YV32nZi6olvyQXXhZNHkhVxvbYxs2GZfYWkOg3_47Mq4tK9Yq8mv40VxZ9J2qSk4ri9gwHmXPURjC7V5H1wLXvDYMCYTa8JD8h3l" alt=""/></figure></div>



<p>Now adding the <code>credentials.json</code> and <code>token.json</code> so that the script can access the Gmail account. (Need a refresher? => See <a href="https://blog.finxter.com/ezgmail-python-managing-your-emails-programmatically/" target="_blank" rel="noreferrer noopener">here</a>):</p>



<div class="wp-block-image"><figure class="aligncenter is-resized"><img loading="lazy" decoding="async" src="https://lh6.googleusercontent.com/9XrOGBl4N5el1nel17jXvNUwgL0FpKIiP5PAKSEypD0esaKo9RSNyJVc1UjoiF6QooS4sDaG0nNfgmVWGaEo-b8_yXBPSrxLIuKMr-KqtXj7uW7OtFiFKfZYpH2duWHsqok0lvm9" alt="" width="612" height="42"/></figure></div>



<p>As a reminder:</p>



<ul class="wp-block-list"><li>use a toy email account if this is for hobby</li><li>don’t push such sensitive files as <code>credentials.json</code> to public repos. (By the way, there is this great startup, <a href="https://www.gitguardian.com/" target="_blank" rel="noreferrer noopener">Gitguardian</a>, which job is to detect such risks and alert accordingly)</li></ul>



<h2 class="wp-block-heading">Push it on Heroku</h2>



<p>Now you must be accustomed to it, so here I go:</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://lh6.googleusercontent.com/bMijWwhwEnHeqU5b-9lHN6Q2dCqP0w-eBi-lvzLJVU6I42wEQVT8Qz15pAvPaU3H9tLcf8EiLECTVFBSAoewth8RzJOPByy2o0sp2p40sLLQpbvADxA1QjKmn80rlXZ103CRRtZI" alt=""/></figure></div>



<p>Notice I did not specify any app name (heroku create), so Heroku will find an available name randomly. This is because it doesn’t really matter as this is not a website, but only a scheduled process running in the background, so noone will see its name except me (and potential collaborators).</p>



<p>What a great name though! : Enigmatic escarpment!</p>



<p>What happens if I click on the URL provided with the project?</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://lh6.googleusercontent.com/wo-65wISXwY8YFpiITnFxIytorMvQvFYf8GWI1g-DHXtGMEg-gEyA6eTWL-c5xTBKaRUVjs2AysNYA_POkwpIuc0FU779Nm5ZTVv7fBVuQlGTeASS4dzbcch7g9Kfz9HE3sU-fKi" alt=""/></figure></div>



<p>Oouups! Did I mess things up?</p>



<p>No! That’s normal, Heroku provides me with a URL but I’m not making a web app this time.</p>



<h2 class="wp-block-heading">Trigger a Scheduler</h2>



<p>Now that our script is in the cloud, nothing will happen until we select and trigger a scheduler. We will do it the GUI way.</p>



<p>To do so, go to your app page, click on the Resources tab, and start typing ‘schedule’ in the add-ons bar and you will see several schedulers appear:</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://lh6.googleusercontent.com/Mnp4i5apV6faTnioL0dVPaQ7YuIaMASAgxxEMJGAnllDMz9ZPeHqIPaNkWI4srT8E23OyaQLhoXHr-vJFeLdmsvOYagxidZ723ct2fi-iiIm84jiOeP0yzGQjYhXn8NMhFUwxqUD" alt=""/></figure></div>



<p>Depending on your goal and your budget, you may pick one of the above.</p>



<p>I’ll go with the free plan of the advanced scheduler for this tutorial.</p>



<p>Just select the one that best suits your need, and click on submit order form.</p>



<p>Then click on the scheduler to start setting it, and you will see a purple button ‘Create first trigger’, click on it.</p>



<p>At this stage, you might get a pop-up requiring you to fill in your bank details before being able to proceed. If you then opt for a free plan, you can do so without worry of being charged.</p>



<p>You will be prompted to type a name for the trigger, the command to run.</p>



<p>The command is the one you would type in your shell to run your Python program (in this project, the command to type is thus: <code><strong>python scheduled_script.py</strong></code>). </p>



<p>Then select your timezone and whether this is a one-off or recurring.</p>



<p>In my case and for this tutorial, I selected recurring every minute:</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://lh4.googleusercontent.com/A7JSV-7uDQ97bbeawCnGeE49ykvvufvC99u0w_UIVvHZrb6g1cijLD0BltRDDD-GFXH6NmEq659r-3Ugws6MIJjbwDYVuyJvqFXgesNWxptiKLYS8SymFU6Y8E8DkNZGg_MQUdsR" alt=""/></figure></div>



<p>Finally, you can monitor your scheduler add-on on the dedicated page that follows:</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://lh6.googleusercontent.com/wyrhnumOF2at6XNnbzsGAgWkZM71JiV2ABhyqk4aVT-Jx0ig5c_4r1SuQ0yNgi5uRv7bsDhNltY_GtQAOIMBhiUmcd42HXP9jG5FNRqFMFgnct6jmnBhgjzxf_1c59PO26vsC2JB" alt=""/></figure></div>



<h2 class="wp-block-heading">Enjoy your automation!</h2>



<p>You can now sit and relax, while Python on Heroku is doing all the nightly work for you!</p>



<p>You remember I wrote and pushed a program that sends emails to myself every single minute, with the time in the subject of the email?&nbsp;</p>



<p>Look at the results:</p>



<div class="wp-block-image"><figure class="aligncenter"><img decoding="async" src="https://lh4.googleusercontent.com/X-LWoIZwQxp5Cxprpuo1szwR47SR5hjZQDk5SYHHS0iOhg9nQMBYJy_3jfmkhI4DyCbSJt8SLLdB6assiouDeCkY8nSnm4BKn0TO3mZHKnOSe0I3U41C7hRQVfEPrq9zyKI4LK9j" alt=""/></figure></div>



<p>Just imagine the endless possibilities for your future programs!</p>



<p>Beware though, I do not recommend using a free plan for serious projects, as the reliability might not be up to standards and your dyno might run out.</p>



<p>Also, please use this kind of technology responsibly.</p>



<p>That’s all for today, I’m sure you can now try it yourself and create great things.</p>



<h2 class="wp-block-heading">Where to Go From Here?</h2>



<ul class="wp-block-list"><li>Creating your own scheduled Python task</li><li>try out other schedulers</li><li>try out the <a href="https://documentation.advancedscheduler.io">Advanced Scheduler Service API</a></li></ul>
<p>The post <a href="https://blog.finxter.com/how-to-schedule-your-python-script-for-free-on-heroku/">How to Schedule Your Python Script for Free on Heroku</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to Build and Host Your Python Web App for Free</title>
		<link>https://blog.finxter.com/how-to-build-and-host-your-python-web-app-for-free/</link>
		
		<dc:creator><![CDATA[Clement Lelievre]]></dc:creator>
		<pubDate>Tue, 27 Apr 2021 17:18:58 +0000</pubDate>
				<category><![CDATA[Distributed Systems]]></category>
		<category><![CDATA[Flask]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Web Development]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=28911</guid>

					<description><![CDATA[<p>Hey Finxters! Have you ever felt surrounded by developers boasting from their latest app in prod hosted in the cloud?&#160; Or the need for making yours too but overwhelmed by the technicalities involved? Needed to set up quickly and easily a mini data science demo website without resorting to web developers? Or simply wanting to ... <a title="How to Build and Host Your Python Web App for Free" class="read-more" href="https://blog.finxter.com/how-to-build-and-host-your-python-web-app-for-free/" aria-label="Read more about How to Build and Host Your Python Web App for Free">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/how-to-build-and-host-your-python-web-app-for-free/">How to Build and Host Your Python Web App for Free</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Hey Finxters!</p>



<ul class="wp-block-list"><li><em>Have you ever felt surrounded by developers boasting from their latest app in prod hosted in the cloud?&nbsp;</em></li><li><em>Or the need for making yours too but overwhelmed by the technicalities involved?</em></li><li><em>Needed to set up quickly and easily a <a href="https://blog.finxter.com/your-first-dash-app-how-to-get-started-in-4-minutes-or-less/" target="_blank" rel="noreferrer noopener" title="Your First Dash App – How to Get Started in 4 Minutes or Less">mini data science demo website</a> without resorting to web developers?</em></li><li><em>Or simply wanting to share your Python work with non-technical people?</em></li></ul>



<p>Then this article is for you.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="How to Build and Host Your Python Web App for Free" width="937" height="527" src="https://www.youtube.com/embed/URK-iWbz764?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p class="has-pale-cyan-blue-background-color has-background">?&nbsp;Today I will show you one of the simplest ways to set-up your very own Python web app in the cloud, using <a href="https://streamlit.io/" target="_blank" rel="noreferrer noopener">streamlit</a> to design the app together with <a href="https://www.heroku.com/">Heroku</a> for the hosting part. And it is free.</p>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter is-resized"><img loading="lazy" decoding="async" src="https://lh3.googleusercontent.com/2Mwm9avgBJOTiHmPNMRuwiULHWlqrC5pktFQrpIVJQo1jzy4Qnk8Z4jTvVHHp3PFSLeUN-cBwU8yRaMzUU_4BsbkoZQ3FttOSIsnOLtN22-chBMYIemzBySkrBjj5GlZs8VonFyb" alt="" width="300" height="157"/></figure>
</div></div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"><div class="wp-block-image">
<figure class="aligncenter is-resized"><img loading="lazy" decoding="async" src="https://lh6.googleusercontent.com/Jo-PcjuMW4Y2FrTxRE-XAXJffa8mYMEL_Z6eFhItgMNYeNxtC_gielcFx0phRGOZmWjqq7PtO9IGGMDEHTeJM7hCJayAQfeY09zHB9xXi-9_bjPaRvo_4ZEBOL0bTWtx1SI7_j9s" alt="" width="300" height="158"/></figure>
</div></div>
</div>



<p>This article assumes you have at least:</p>



<ul class="wp-block-list"><li>basic Python notions</li><li>basic Git notions</li><li>a Heroku account (free) (do not forget to configure your email address)</li><li>the <a href="https://devcenter.heroku.com/articles/heroku-cli" target="_blank" rel="noreferrer noopener">Heroku CLI</a> installed</li><li>basic notions of Linux commands</li><li>basic notions of bash scripting</li></ul>



<p>Ready? Here is the plan of our journey:</p>



<h2 class="wp-block-heading"><strong>What is Streamlit?</strong></h2>



<p><a href="https://www.streamlit.io/">Streamlit</a> is a data science oriented application framework.&nbsp;</p>



<p>Its goal is to enable data scientists to release applications without requiring the assistance of a development team</p>



<p>Streamlit allows for example to build an app making predictions using a trained machine learning model, with very few lines of code handling the user interface and controls, and almost no design efforts.</p>



<p>During this tutorial, I will be referring heavily to the <a href="https://docs.streamlit.io/en/stable/" target="_blank" rel="noreferrer noopener">Streamlit documentation</a>, and I strongly encourage you to spend some time reading it.</p>



<p>To use it you will first need to do the following in your terminal:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install streamlit
streamlit hello  # not strictly mandatory; launches the ‘hello world’ app to test it works</pre>



<p>Then in your Python file, the canonical import will be:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import streamlit as st</pre>



<h2 class="wp-block-heading">What is Heroku?</h2>



<p>From their own words: <em>“Heroku is a cloud platform that lets companies build, deliver, monitor and scale apps — we&#8217;re the fastest way to go from idea to URL, bypassing all those infrastructure headaches.”</em></p>



<p>That’s right, at the end of this article, we will get an actual URL for our Python project!</p>



<p>Because we will be using a free account, the URL will look like: <em>our_project_name.herokuapp.com</em>, but you might want to upgrade in order to have more options.</p>



<p>So in a nutshell, we will be hosting our Python web app designed with Streamlit on their server, in order for other people to access it without having to have our machine running 24/7.</p>



<p>More info on Heroku can be found <a href="https://www.heroku.com/what" target="_blank" rel="noreferrer noopener">here</a>.</p>



<h2 class="wp-block-heading">Building the Project</h2>



<p>In order to keep things as simple as possible, I will show you the minimum package needed to successfully run your app, but of course you may encounter additional files in other Streamlit/Heroku repos depending on what is achieved, such as for instance:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">.gitignore, README.md, Makefile, MANIFEST.in, setup.py, runtime.txt, credentials.json, token.json, some_machine_learning_trained_model.h5, etc.</pre>



<p>I will not comment on these files specifics in this tutorial, as we will focus on building and hosting our Python <a href="https://blog.finxter.com/how-to-create-a-site-on-webflow-export-the-code-host-it-anywhere/" data-type="post" data-id="780707" target="_blank" rel="noreferrer noopener">web app</a>.</p>



<p>Start by creating a folder where you will put all the necessary files:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">mkdir my_project_folder &amp;&amp; cd my_project_folder</pre>



<p>If you already have a Python project coded, say on Github: then <em>git clone</em> it.</p>



<p>Here is the list of files that we will need in our folder before pushing to Heroku, I will go over each of them:</p>



<ul class="wp-block-list"><li><code>main.py&nbsp;</code></li><li><code>requirements.txt</code></li><li><code>Procfile</code></li><li><code>setup.sh</code></li></ul>



<p>And that’s all! Let’s dive in the files specifics:</p>



<h3 class="wp-block-heading"><code><strong>main.py</strong></code></h3>



<p>This is the Python file (you may need several depending on your project).</p>



<p>This is where your Python code lies and also where the web app structure comes in, thanks to <code>streamlit</code>. Remember you imported <em><code>streamlit as st</code></em> at the top of this file?</p>



<p>You can now design many elements thanks to this, for example:</p>



<ul class="wp-block-list"><li>markdown : <code><a href="https://docs.streamlit.io/en/stable/api.html?highlight=markdown#streamlit.markdown" target="_blank" rel="noreferrer noopener">st.markdown</a>('''some text ''')</code></li><li>a slider&nbsp; : <code><a href="https://docs.streamlit.io/en/stable/api.html?highlight=slider#streamlit.slider" target="_blank" rel="noreferrer noopener">st.slider</a>(*args, *kwargs)</code></li><li>a file uploader : <code><a href="https://docs.streamlit.io/en/stable/api.html?highlight=uploader#streamlit.file_uploader" target="_blank" rel="noreferrer noopener">st.file_uploader</a>(*args, *kwargs)</code></li></ul>



<p>as well as many, many more features, developed by an active community.</p>



<p>One more tip: to tailor things such as your app’s favicon, title etc., look into <a href="https://docs.streamlit.io/en/stable/api.html?highlight=set%20page%20config#streamlit.set_page_config" target="_blank" rel="noreferrer noopener"><code>st.set_page_config</code></a> and place it at the top of your Python script, just below the imports.&nbsp;</p>



<p>You should have a look at the documentation to get a grasp of the possibilities there.</p>



<p>Finally, if you fancy looking at sample websites, visit the Streamlit <a href="https://streamlit.io/gallery" target="_blank" rel="noreferrer noopener">gallery</a>!</p>



<p>Please note that every time the user will interact with your app, the code will be rerun from top to bottom. This may result in unresponsiveness at times.</p>



<h3 class="wp-block-heading"><code><strong>requirements.txt</strong></code></h3>



<p>This is the text file that specifies which (not built-in) modules will be needed for your web app to run on Heroku.</p>



<p>The minimum it should contain is therefore <code>streamlit</code>.</p>



<p>It basically just lists the (not built-in) modules imported in your Python file(s) for this project.</p>



<p>Beware the 3 following items:</p>



<ul class="wp-block-list"><li>version constraints must be stated (ex: <em><code>scikit-learn&gt;=0.21.3</code></em> or <em><code>requests==2.*</code></em>)&nbsp;</li><li>as well as the exact module name (the name may differ between what is pip installed and what is imported)</li><li>as we are using a free Heroku plan, the slug size is limited to 500mB thus preventing heavy modules, <a href="https://stackoverflow.com/questions/65677710/tensorflow-apps-no-longer-deploying-to-heroku-slug-size-too-large" target="_blank" rel="noreferrer noopener">such as Tensorflow</a></li></ul>



<p><em><code>touch requirements.txt</code> </em>then add manually the modules, or use a script that does it for you, or <code>echo “modules” &gt; requirements.txt</code></p>



<p>if you setup a <a href="https://blog.finxter.com/python-virtual-environments-with-venv-a-step-by-step-guide/" target="_blank" rel="noreferrer noopener" title="Python Virtual Environments with “venv” — A Step-By-Step Guide">virtual env </a>for your app, they can be obtained through a <em><code>pip freeze</code></em></p>



<h3 class="wp-block-heading"><code><strong>Procfile</strong></code></h3>



<p>That’s right, this file has no extension. It is a process file specific to Heroku that details which commands should be executed by the app on startup. In our case a <em>web</em> process. More details <a href="https://devcenter.heroku.com/articles/procfile" target="_blank" rel="noreferrer noopener">here</a></p>



<p>For now, you can simply <em><code>echo &gt;</code> </em>the following snippet in your <em><code>Procfile</code></em>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">web: sh setup.sh &amp;&amp; streamlit run &lt;your_python_file>.py</pre>



<p>Of course, you should adapt it with your own Python file’s name (main.py in this tutorial).</p>



<h3 class="wp-block-heading"><code><strong>setup.sh</strong></code></h3>



<p>Custom script launched by the Procfile command. Indicates to Streamlit the app owner&#8217;s email and Heroku&#8217;s dynamically assigned port on which to run.</p>



<p>Like before, for now you can just copy this piece of code:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">mkdir -p ~/.streamlit/

echo "\
[general]\n\
email = \"${HEROKU_EMAIL_ADDRESS}\"\n\
" > ~/.streamlit/credentials.toml

echo "\
[server]\n\
headless = true\n\
enableCORS = false\n\
port = $PORT\n\
" > ~/.streamlit/config.toml
</pre>



<p>And that’s it! Now that you have the full structure in mind, let’s see an example.</p>



<p>Perhaps you’ve read my article about <a href="https://blog.finxter.com/ezgmail-python-managing-your-emails-programmatically/" target="_blank" rel="noreferrer noopener">sending email from a Gmail account with Python</a>?</p>



<p>Well, I actually made a Streamlit/Heroku web app with it, and here is the resulting directory:</p>



<figure class="wp-block-image is-resized"><img loading="lazy" decoding="async" src="https://lh4.googleusercontent.com/r3fsFL6DyRllFNDtfO3_FQdpGEW3lYiIMT0featkGhjLBTyrLr90-j22RRFqrSCLP5zQWwrBQ5SwsmWxARdQsjeVZwl4ozCJQJHfalcE-An-TZS-1ViApYdbbtm7vbF1vcwzyIWx" alt="" width="416" height="208"/></figure>



<h2 class="wp-block-heading">Testing the App Locally</h2>



<p>To check that your Python file works and make modifications to it quickly, use the following command to run it locally:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">streamlit run &lt;your_python_file>.py</pre>



<p>Either your browser will open and show your app, or two URLs will appear, allowing you to view your app. Click on Network URL.</p>



<figure class="wp-block-image is-resized"><img loading="lazy" decoding="async" src="https://lh3.googleusercontent.com/fpsilP3sJl2VAAWY-M-fS5Mue_FZf34aGWJk0YbPAdEciGd5VEJJk8ASsvWgfMdaBFq1Ugl2yayNBHE3hrT6krBTweiOjF2JSMysizwzVc5Jt6GNe1Nvl7hoNSO7eIrcN-irrCqL" alt="" width="579" height="125"/></figure>



<p>Here is what I’d get in my browser in my example email project:</p>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://lh3.googleusercontent.com/gpp3Rjrd7lxp9oz9OsEwwdGe-9uv85vmqS8n_btF9QYRk5yzmpAggImMWsf014_mPUKyu-QJhAJVUjvYXF-Bk6Plh-h8lztxy0xwxyQnQqaL17HnOgBJ7_wLw7pU4CR60QE5QNnz" alt=""/></figure>
</div>


<p>If you want to have a closer look, find my repo <a href="https://github.com/Clement-Lelievre/send-emails-free" target="_blank" rel="noreferrer noopener">here</a>.</p>



<h2 class="wp-block-heading">Pushing the Project</h2>



<p>Last but not least, we now need to make our web app available to the world, as for now it only runs locally.</p>



<p>How to proceed?</p>



<p>Like so:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># if not already done, log in to Heroku
heroku login

# create the app in your region and pick an available APP_NAME
heroku create APP_NAME --region eu
</pre>



<p><em>An example for say, a <a href="https://finxter.com/" target="_blank" rel="noreferrer noopener" title="https://finxter.com/">Finxter web app</a>, would go:</em></p>



<figure class="wp-block-image"><img decoding="async" src="https://lh6.googleusercontent.com/APZIbeaT3I5uW5TqJ5-LN_wh8kUhWo7ZmeNqVPuuP14rSplDYNKB8tpcJ3Plf-4bGJBldRVnsLWqYwcoXoRMyQ1w22a5vlTO37Flti6bc6jy7N1HeT5BGqJuFD1Xgbzvucnpv6U6" alt=""/></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># you should see the origin remote for GitHub if you cloned a repo
# and the heroku remote for Heroku
git remote -v
</pre>



<p><em>Example from my terminal:</em></p>



<figure class="wp-block-image"><img decoding="async" src="https://lh6.googleusercontent.com/IZK4LbrBKbPr7-lLTycDX5mwsQ199BVGLXQCJ47RljmoyplkcagVc_zgwm6rAG6XU8PHadHGZqLH6CiYSIv0K-piEs6a47ScGc57H7FpuDDEwt4aXTLYgifb_290f__LEJsAHC-X" alt=""/></figure>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># manually add the heroku remote if necessary
git remote add heroku https://git.heroku.com/APP_NAME.git

# if not already done
git add . # or specify files if you don’t want to push everything
git commit -m “&lt;your commit comment>”

# deploy the app 
git push heroku master  # this could take up to a few minutes and you will witness the build. Change the branch name if needed (eg “main” instead of “master”)</pre>



<figure class="wp-block-image"><img decoding="async" src="https://lh5.googleusercontent.com/nDD-JM1Z1I_ucW9Jw44JbUUaHS67HdEJ_ASMZHgxArBLUtIlMHMWAwm_Z64phfP6xWHif7XW0lY3nrNUIDj0-VbHdYr8tbgha2k5n29uv61o0dlCHpxeH8kuI4tQ18UOp4faMAPA" alt=""/></figure>



<p>If you read the logs above, you should now be able to understand the deployment process.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># start the web dyno (this is not strictly necessary in most cases)
heroku ps:scale web=1

# open a browser to your deployed web app!
heroku open
</pre>



<p>Now, you may experience issues at deployment stage.</p>



<p>Hence a useful command to know is:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># check the logs for errors
heroku logs --tail  
# will help you troubleshoot, by showing the build logs (you can also view them on your Heroku app profile on Heroku’s website)
</pre>



<p>The Heroku GUI in your profile will look like this:</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh5.googleusercontent.com/YSW2R3FcHgFZFBjZ_TVwoCnAEBylY7cwhkVK-hgVJxUzQqtmzm6Ul9qTa0tSho1U_Tc8znCfrIituSQIaTqVFAb049jlBPrrpVFB69EOfvIzqR5lGjkA7QyCQj6Znkt3UKcp6rys" alt=""/></figure>



<p>Last, a few remarks:</p>



<ul class="wp-block-list"><li>this requires a bit of practice before deploying with ease but is definitely worth it!</li><li>with a free plan, expect your app to sleep after some time of inactivity. I found a possible remedy to this <a href="http://kaffeine.herokuapp.com/">here</a></li><li>whenever your app is awakened, it may take up to 30 seconds to load, that is perfectly normal</li><li>with a free, unverified Heroku account, you can have up to 5 apps running at the same time</li><li>the free plan allocates some number of dyno hours per month after which your app will sleep</li><li>despite all these limitations, you can still very much present data science results or any Python work really and get a reliable app!</li></ul>



<p>I hope you enjoyed our journey into the Python web app deployment universe and that you will create amazing apps!</p>



<p>Oh wait! I said I deployed my email sender project, fancy seeing it?</p>



<p>Here it is: <a href="https://email-sender-finxter.herokuapp.com/" target="_blank" rel="noreferrer noopener">https://email-sender-finxter.herokuapp.com/</a></p>



<p>You can add several recipients as well as add attachments.</p>



<p>With great power comes great responsibility: use it responsibly.</p>



<h2 class="wp-block-heading">Where to Go From Here</h2>



<ul class="wp-block-list"><li>make your own Python web app!</li><li>tune it</li><li>maybe onboard a trained machine learning model on it?</li><li>share it to the world!</li><li>filter email content with NLP</li></ul>



<p>I hope you will benefit from my experience on this topic, see you next time guys! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p></p>
<p>The post <a href="https://blog.finxter.com/how-to-build-and-host-your-python-web-app-for-free/">How to Build and Host Your Python Web App for Free</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Coding Your Own Google Home and Launch Spotify in Python</title>
		<link>https://blog.finxter.com/coding-your-own-google-home/</link>
		
		<dc:creator><![CDATA[Clement Lelievre]]></dc:creator>
		<pubDate>Thu, 25 Mar 2021 17:24:40 +0000</pubDate>
				<category><![CDATA[Artificial Intelligence]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=26892</guid>

					<description><![CDATA[<p>Doesn&#8217;t this project sound exciting? Project Goal Project goal: code your own Google Home with Python and learn how to use speech recognition to launch Spotify and play songs! Ever wanted to code a powerful yet simple tool that is more bespoke than mainstream devices? We will learn how to implement it in Python with ... <a title="Coding Your Own Google Home and Launch Spotify in Python" class="read-more" href="https://blog.finxter.com/coding-your-own-google-home/" aria-label="Read more about Coding Your Own Google Home and Launch Spotify in Python">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/coding-your-own-google-home/">Coding Your Own Google Home and Launch Spotify in Python</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Doesn&#8217;t this project sound exciting?</p>



<h2 class="wp-block-heading">Project Goal</h2>



<p class="has-global-color-8-background-color has-background"><strong>Project goal: </strong>code your own Google Home with Python and learn how to use speech recognition to launch Spotify and play songs!</p>



<p>Ever wanted to code a powerful yet simple tool that is more bespoke than mainstream devices?</p>



<p>We will learn how to implement it in Python with a bunch of powerful libraries!</p>



<p>Breaking down our problem, there are three tasks ahead of us:</p>



<ul class="wp-block-list">
<li>processing speech and convert it into text</li>



<li>based on some <a href="https://blog.finxter.com/category/python-string/">string</a> condition in the text, open a process (here, the Spotify app)</li>



<li>interact with the process</li>
</ul>



<h2 class="wp-block-heading"><strong>Performing Speech Recognition</strong></h2>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="690" height="460" src="https://blog.finxter.com/wp-content/uploads/2023/01/image-251.png" alt="" class="wp-image-1075724" srcset="https://blog.finxter.com/wp-content/uploads/2023/01/image-251.png 690w, https://blog.finxter.com/wp-content/uploads/2023/01/image-251-300x200.png 300w" sizes="auto, (max-width: 690px) 100vw, 690px" /></figure>
</div>


<p><strong><em>Don’t do the heavy lifting yourself!</em></strong></p>



<p>Speech recognition is the ability to detect and identify words and phrases in spoken language and subsequently convert them into human, readable text.&nbsp;</p>



<p>This field can be very complex and top Python libraries result from decades of hard work from experts. We will obviously not be constructing from A to Z such a library, that would be way beyond this tutorial. Instead, we will be using the <a href="https://pypi.org/project/SpeechRecognition/">SpeechRecognition</a> library.</p>



<p>Therefore, we don&#8217;t need to build any machine learning model from scratch, this library provides us with wrappers for several well known public speech recognition APIs (such as Google Cloud Speech API, IBM Speech To Text, etc.).</p>



<p>As usual, we will start downloading the module:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install SpeechRecognition pydub</pre>



<p>Then, in a new Python file, you can import it the following way:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import speech_recognition as sr</pre>



<p>It is now very handy, you have access to several speech recognition engines, that have different use cases:</p>



<ul class="wp-block-list">
<li><a href="http://cmusphinx.sourceforge.net/wiki/" target="_blank" rel="noreferrer noopener">CMU Sphinx</a> (offline)</li>



<li>Google Speech Recognition</li>



<li><a href="https://cloud.google.com/speech/" target="_blank" rel="noreferrer noopener">Google Cloud Speech API</a></li>



<li><a href="https://wit.ai/" target="_blank" rel="noreferrer noopener">Wit.ai</a></li>



<li><a href="https://azure.microsoft.com/en-us/services/cognitive-services/speech-services/" target="_blank" rel="noreferrer noopener">Microsoft Bing Voice Recognition</a></li>



<li><a href="https://www.houndify.com/" target="_blank" rel="noreferrer noopener">Houndify API</a></li>



<li><a href="https://www.ibm.com/watson" target="_blank" rel="noreferrer noopener">IBM Speech To Text</a></li>



<li><a href="https://snowboy.kitt.ai/" target="_blank" rel="noreferrer noopener">Snowboy Hotword Detection</a> (offline)</li>
</ul>



<p>In this tutorial, we will be using Google Speech Recognition, because it is rather simple to use, efficient, and does not require any API key.</p>



<h2 class="wp-block-heading">Interpreting Speech from a File</h2>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="690" height="460" src="https://blog.finxter.com/wp-content/uploads/2023/01/image-252.png" alt="" class="wp-image-1075726" srcset="https://blog.finxter.com/wp-content/uploads/2023/01/image-252.png 690w, https://blog.finxter.com/wp-content/uploads/2023/01/image-252-300x200.png 300w" sizes="auto, (max-width: 690px) 100vw, 690px" /></figure>
</div>


<h3 class="wp-block-heading">Regular Size</h3>



<p>Before starting, make sure you placed an audio file containing english language, in the current working directory for maximised simplicity, or somewhere you know the path (such as ‘../audio_files/my_audio_file.wav’).</p>



<p>The first step is to initialize your recognizer like so:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># initialize the recognizer
r = sr.Recognizer()</pre>



<p>The below code is then responsible for loading the audio file from the designated path, and then converting the speech into text using Google Speech Recognition:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># open the file
with sr.AudioFile(path_to_audio_file) as source:
    # listen to the data ( = load audio to memory)
    audio_data = r.record(source)
    # recognize (convert from speech to text)
    text = r.recognize_google(audio_data)
    print(text)
</pre>



<p>&nbsp;This could take a little while, on the other hand don’t think the duration of the code execution is in some way related to human speech speed: you will commonly eye-witness your code spitting out the full text even before the audio file has finished reading!</p>



<p>Okay, this kind of script works fine for small to medium-sized audio files, not so well for larger files.</p>



<h3 class="wp-block-heading"><strong>Large Audio Files</strong></h3>



<p>I won’t go into too many details here, as our goal is to launch Spotify thanks to voice command, remember? Suggesting we’ll use the mic.</p>



<p>However, if you do need to convert the content of large audio files, then you should be looking into the <a href="https://pypi.org/project/pydub/" target="_blank" rel="noreferrer noopener">pydub library</a>, more specifically its <a href="https://github.com/jiaaro/pydub/blob/master/pydub/audio_segment.py" target="_blank" rel="noreferrer noopener">AudioSegment</a> <a href="https://blog.finxter.com/python-attributes/">class</a> and <a href="https://github.com/jiaaro/pydub/blob/master/pydub/silence.py" target="_blank" rel="noreferrer noopener"><code>split_on_silence</code></a> <a href="https://blog.finxter.com/python-built-in-functions/">function</a>.</p>



<p>Why?</p>



<p>Because, well-equipped with these two, you will then be able to respectively load the audio data and chunk it, based on a pre-set silence duration found in the data.</p>



<p>This comes handy to split your audio file.</p>



<p class="has-base-background-color has-background"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f449.png" alt="👉" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Recommended</strong>: <a href="https://blog.finxter.com/large-audio-to-text-heres-my-speech-recognition-solution-in-python/" data-type="post" data-id="1075593" target="_blank" rel="noreferrer noopener">How to Recognize Speech From Large Audio Files?</a></p>



<h2 class="wp-block-heading">Interpreting Speech from the Mic</h2>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="690" height="690" src="https://blog.finxter.com/wp-content/uploads/2023/01/image-250.png" alt="" class="wp-image-1075719" srcset="https://blog.finxter.com/wp-content/uploads/2023/01/image-250.png 690w, https://blog.finxter.com/wp-content/uploads/2023/01/image-250-300x300.png 300w, https://blog.finxter.com/wp-content/uploads/2023/01/image-250-150x150.png 150w" sizes="auto, (max-width: 690px) 100vw, 690px" /></figure>
</div>


<p>We are now getting to the core of the tutorial! We will be processing the audio input directly from the mic, moving one step closer to being able to actually make voice commands.</p>



<p>To start with, this requires PyAudio to be installed on your machine and depending on your OS the installation procedure varies:</p>



<p><strong>Windows</strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install pyaudio</pre>



<p><strong>Linux</strong></p>



<p>You need to first install the dependencies:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sudo apt-get install python-pyaudio python3-pyaudio
pip install pyaudio</pre>



<p><strong>MacOS</strong></p>



<p>You need to first install portaudio:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">brew install portaudio
pip install pyaudio
</pre>



<p><strong>Warning:</strong> you may experience issues installing the module properly, especially on Windows.</p>



<p>For Windows users, if you don’t succeed the abovementioned way, try:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install pipwin (if you don’t already have it)
pipwin install pyaudio
</pre>



<p>Now we’re ready to start building our Spotify launcher!</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">with sr.Microphone() as source:
    # read the audio data from the microphone
    audio_data = r.record(source, duration=5)
    print("Analyzing...")
    # convert speech to text
    text = r.recognize_google(audio_data)
    print(text)
</pre>



<p>This piece of code will open the (default) mic, read the input for 5 seconds (you can obviously tailor this argument), then (try to) convert it, finally <a href="https://blog.finxter.com/the-separator-and-end-arguments-of-the-python-print-function/">print</a> out the output.&nbsp;</p>



<p>Obviously it still isn’t perfect, for example it usually struggles with homophonous phrases or words.</p>



<p>Two arguments are worth mentioning at this point:</p>



<ul class="wp-block-list">
<li>offset: passed to the record function, it is used to start recording after some delay (default 0)</li>



<li>language: passed to the recognize_google function, it changes the target language (ex: “fr-FR”). More info about supported languages <a href="https://stackoverflow.com/questions/14257598/what-are-language-codes-in-chromes-implementation-of-the-html5-speech-recogniti/14302134#14302134">here</a></li>
</ul>



<h2 class="wp-block-heading">Opening Processes with Python</h2>


<div class="wp-block-image">
<figure class="aligncenter size-large"><img loading="lazy" decoding="async" width="1024" height="683" src="https://blog.finxter.com/wp-content/uploads/2023/01/image-255-1024x683.png" alt="" class="wp-image-1075808" srcset="https://blog.finxter.com/wp-content/uploads/2023/01/image-255-1024x683.png 1024w, https://blog.finxter.com/wp-content/uploads/2023/01/image-255-300x200.png 300w, https://blog.finxter.com/wp-content/uploads/2023/01/image-255-768x512.png 768w, https://blog.finxter.com/wp-content/uploads/2023/01/image-255.png 1282w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /></figure>
</div>


<p>Now that we can talk to our speech recognizer and convert speech into text, let’s head towards our second task: opening processes.</p>



<p>As often, there are multiple ways to do this.</p>



<p>We will use the <a href="https://docs.python.org/3/library/subprocess.html" target="_blank" rel="noreferrer noopener">subprocess</a> module, which is built-in.</p>



<p>In particular, we will be using the Popen (P stands for process) function within this module, like so:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group=""># import the function from its module
from subprocess import Popen

Popen(path_of_the_executable)
</pre>



<p>For example, on my machine, opening the Spotify desktop app would be done like so: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">subprocess.Popen('C:\\Users\\cleme\\AppData\\Roaming\\Spotify\\Spotify.exe')</pre>



<p>Depending on your OS, you may need to adjust the slashes in the path to make sure it is understood well. You may want to use a function doing this for you in the <a href="https://docs.python.org/3/library/os.path.html">os</a> built-in module.</p>



<p>Of course, as always feel free to dive deeper into this module, but for now we have what we need to trigger the opening of our Spotify (desktop) app.</p>



<h2 class="wp-block-heading">Interacting with Windows</h2>


<div class="wp-block-image">
<figure class="aligncenter size-medium"><img loading="lazy" decoding="async" width="300" height="265" src="https://blog.finxter.com/wp-content/uploads/2021/01/windows-300x265.png" alt="" class="wp-image-21555" srcset="https://blog.finxter.com/wp-content/uploads/2021/01/windows-300x265.png 300w, https://blog.finxter.com/wp-content/uploads/2021/01/windows-768x678.png 768w, https://blog.finxter.com/wp-content/uploads/2021/01/windows-150x132.png 150w, https://blog.finxter.com/wp-content/uploads/2021/01/windows.png 870w" sizes="auto, (max-width: 300px) 100vw, 300px" /></figure>
</div>


<p>OK, let us sum up:</p>



<ul class="wp-block-list">
<li>we know how to convert speech to text</li>



<li>we know how to open processes</li>
</ul>



<p>From there, we can easily create a condition on the output text from the speech conversion; for example :</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">if "spotify" in text.lower():
    subprocess.Popen('C:\\Users\\cleme\\AppData\\Roaming\\Spotify\\Spotify.exe')</pre>



<p>What is there left to do?</p>



<p>Now that our Spotify app is open on voice command, we need to somehow be able to launch a song.</p>



<p>To do this, there may exist Spotify modules, but we will be using a powerful module:</p>



<p><a href="https://pyautogui.readthedocs.io/en/latest/" target="_blank" rel="noreferrer noopener"><code>pyautogui</code></a></p>



<p>This module is essentially about automating mouse, windows, and keyboard actions!</p>



<p>So, what we’ll do is identify the Spotify app search bar location, click it, clear it if needed, type a song or artist name in it, then press Enter, then press Play, and we’re done!</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install pyautogui</pre>



<p>The first thing is to make sure we are dealing with the Spotify app window.</p>



<p>To do this we’ll loop over <code>pyautogui.getAllWindows()</code>, which yields all the currently opened windows titles, and make an if statement to select the Spotify window.</p>



<p>We will then proceed to the subtasks identified above.</p>



<p>We will use a convention here in our voice command: for the sake of simplicity, we will assume that the name of the wanted artist comes last in the voice command (e.g.: “Please open Spotify and play Madonna”).</p>



<p>Of course this is a dummy example, but you can easily improve the voice command and make it more flexible.</p>



<p>Here is what it looks like:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">    for window in pyautogui.getAllWindows():
        if 'spotify' in window.title.lower():
            window.show()
            print('spotify window activated')
            text = text.split()  # break down text into list of single words strings, for later usage
            time.sleep(5.5)
            pyautogui.click(x=480,y=25) # this is the search bar location on my machine, when the window is maximized
            time.sleep(1)
            pyautogui.hotkey('ctrl','a') # clearing the search bar
            pyautogui.press('backspace') # clearing the search bar
            time.sleep(0.5)
            pyautogui.write(text[-1],interval=0.05) # because we assumed that the artist was the last word of the voice command
            time.sleep(3)
            pyautogui.click(x=380,y=250) # this is the play button location on my machine, when the window is maximized
            break</pre>



<p>Breaking down this piece of code, we performed sequentially all the steps we identified as mandatory.&nbsp;</p>



<p>Note the difference between the <em>hotkey</em> (keystroke combination) and <em>press</em> (single key, down then up) methods.</p>



<p>We used <em>Ctrl+a</em> to select all potential text in the search bar, then we removed it before typing our artist’s name. The <em>text[-1]</em> bit refers to the last word of our voice command, see the convention described above.</p>



<p>Please note the <em>interval</em> argument inside the write method: in some cases it is vital for our script to function properly. Why?</p>



<p>Because it is the argument that sets the typing speed, and in some instances, pyautogui just goes too fast for the process and this ends up in an unwanted result.</p>



<p>You might need to manually finetune this argument, like I did before settling with 0.05. In the same vein, the time.sleep() statements are here to make sure our code does not outspeed too much the app, for example it enables to wait for the proper opening of the app. This can imply some manual tries.</p>



<p>Last, the <a href="https://blog.finxter.com/python-cheat-sheet/" target="_blank" rel="noreferrer noopener" title="Python Beginner Cheat Sheet: 19 Keywords Every Coder Must Know"><em>break </em>statement</a> is there to make sure we go out of the for loop once we have found our app. Let’s not waste time checking useless windows!</p>



<p>Alright, we’re almost there, I can hear the song now!</p>



<p>Now you may wonder, what if we need to stop the song from playing?</p>



<p>Well, we’ll take care of just that in the below piece of code:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">while True:
        try:
            with sr.Microphone() as source:
                # read the audio data from the default microphone
                audio_data = r.record(source, duration=1)
                # convert speech to text
                text = r.recognize_google(audio_data)
                if 'stop' in text.lower():
                    pyautogui.click(x=955 ,y=1000)
                    break
        except Exception as e:
            continue
          print(f"Encountered error: {e}\n")</pre>



<p>The <a href="https://blog.finxter.com/python-loops/" target="_blank" rel="noreferrer noopener" title="Python Loops">while True loop</a> is there to keep looping until it hears ‘stop’ (again, you can obviously tailor this criterion).</p>



<p>If ‘stop’ is heard and correctly decoded, then pyautogui presses the Stop button for us. (Do not hesitate to look into parameters that enable to improve the mic detection when there is noise around (here, our song playing)).</p>



<p>With the use of a <a href="https://blog.finxter.com/how-to-catch-and-print-exception-messages-in-python/" target="_blank" rel="noreferrer noopener">try/except clause</a>, we are able to keep the program running without being bothered by potential errors in the way, but still able to print them if they appear, for later debugging.</p>



<h2 class="wp-block-heading">Combining Everything</h2>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="714" height="536" src="https://blog.finxter.com/wp-content/uploads/2023/01/image-243.png" alt="" class="wp-image-1073513" srcset="https://blog.finxter.com/wp-content/uploads/2023/01/image-243.png 714w, https://blog.finxter.com/wp-content/uploads/2023/01/image-243-300x225.png 300w" sizes="auto, (max-width: 714px) 100vw, 714px" /></figure>
</div>


<p>Want to see my full code? Here it is, below:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import pyautogui, subprocess, os, time
import speech_recognition as sr
 
# initialize the recognizer
r = sr.Recognizer()
 
with sr.Microphone() as source:
    # read the audio data from the default microphone
    audio_data = r.record(source, duration=3)
    print("Recognizing...")
    # convert speech to text
    text = r.recognize_google(audio_data)
    print(f"I think you said: '{text}'\nhmmm, let's see what I can do for you.")
 
if "spotify" in text.lower():
    subprocess.Popen('C:\\Users\\cleme\\AppData\\Roaming\\Spotify\\Spotify.exe')
    for window in pyautogui.getAllWindows():
        if 'spotify' in window.title.lower():
            window.show()
            print('spotify window activated')
            text = text.split()  # break down text list into single words for later usage
            time.sleep(5.5)
            pyautogui.click(x=480,y=25) # this is the search bar location on my machine, when the window is maximized
            time.sleep(1)
            pyautogui.hotkey('ctrl','a') # clearing the search bar
            pyautogui.press('backspace') # clearing the search bar
            time.sleep(0.5)
            pyautogui.write(text[-1],interval=0.05) # because we assumed that the artist was the last word of the voice command
            time.sleep(3)
            pyautogui.click(x=380,y=250) # this is the play button location on my machine, when the window is maximized
            break
    while True:
        try:
            with sr.Microphone() as source:
                # read the audio data from the default microphone
                audio_data = r.record(source, duration=1)
                # convert speech to text
                text = r.recognize_google(audio_data)
                if 'stop' in text.lower():
                    pyautogui.click(x=955 ,y=1000)
                    break
        except Exception as e:
            continue
    
</pre>



<p>There is room for improvement but it works, you can be proud of you if you manage to code your own music launcher!</p>



<p>Thank you guys! That’s all for today.</p>



<h2 class="wp-block-heading"><strong>Where to go from here?</strong></h2>



<ul class="wp-block-list">
<li>Create a voice command to change the sound level, or go to the next song</li>



<li>Combine this script with <a href="https://www.selenium.dev/">Selenium</a> to play music from the Internet instead</li>



<li>Use machine learning for smarter interpretation of the voice command</li>



<li>Convert text to speech</li>



<li>Schedule tasks with Python</li>



<li>In relation with the above item, look into cloud solutions to run code 24/7</li>
</ul>
<p>The post <a href="https://blog.finxter.com/coding-your-own-google-home/">Coding Your Own Google Home and Launch Spotify in Python</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The K-Means Algorithm in Python</title>
		<link>https://blog.finxter.com/k-means/</link>
		
		<dc:creator><![CDATA[Clement Lelievre]]></dc:creator>
		<pubDate>Thu, 04 Feb 2021 13:32:31 +0000</pubDate>
				<category><![CDATA[Algorithms]]></category>
		<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Data Science]]></category>
		<category><![CDATA[Machine Learning]]></category>
		<category><![CDATA[Python]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=22806</guid>

					<description><![CDATA[<p>Hey Finxters! Today we are going to talk about one of the most popular clustering algorithms: K-Means. Ever wondered how to organize seemingly unstructured data, making sense of unordered objects, in an easy way? For example, you might need to: perform customer segmentation store files based on their text content compress images with your own ... <a title="The K-Means Algorithm in Python" class="read-more" href="https://blog.finxter.com/k-means/" aria-label="Read more about The K-Means Algorithm in Python">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/k-means/">The K-Means Algorithm in Python</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="The K-means Algorithm in Python" width="937" height="527" src="https://www.youtube.com/embed/QXTRsowAuWA?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p>Hey Finxters! Today we are going to talk about one of the most popular clustering algorithms: <strong>K-Means</strong>.</p>



<p>Ever wondered how to <strong><em>organize seemingly unstructured data</em></strong>, making sense of unordered objects, in an easy way?</p>



<p>For example, you might need to:</p>



<ul class="wp-block-list"><li>perform customer segmentation</li><li>store files based on their text content</li><li>compress images with your own code</li></ul>



<p>We will learn how to implement it in Python and get a visual output!</p>



<h2 class="wp-block-heading">A Bit of Theory</h2>



<p><em>In case you are not that much into theory and/or need to get working quickly, you can just skip this part and go to the next one.</em></p>



<p>First of all, the <a href="https://blog.finxter.com/supervised-and-unsupervised-machine-learning/" target="_blank" rel="noreferrer noopener" title="Supervised And Unsupervised Machine Learning">Machine Learning</a> algorithm that we are about to learn is an <em>unsupervised</em> algorithm. What does that mean?</p>



<p>It means that we do not have beforehand any labels to use for the data-clustering, we might even have no idea what to expect! So in a way we are going to ask the algo to make groups where we might not necessarily see ones.</p>



<p>In addition to being <em>unsupervised</em>, we say this is a <em>clustering</em> algorithm because its point is to create sub-groups of datapoints that are close in some way, in terms of numerical distance. This idea was first implemented by the Bell labs in the late 1950s.</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh3.googleusercontent.com/G8GNxzga90_AmyIMdFWq8FV3tErVjnxlUX--fr6hNynbOyTqe1l-Vxi4mFPUSnmVOZ2L2RxFxvLMNiHn_U8x44k35rTntE1wqG1erYAH_j5C67bo2-KfBfh7r8MFeq2PSNxbEuJJ" alt=""/></figure>



<p>Perhaps the best way to view clusters for a human eye is in 3D like above, or in 2D; however, you rarely have so few features in the dataset. And it works better on data already clustered geometrically.</p>



<p>Which means it is often a good idea to start out reducing the dimensions, for example by means of a <strong><em>Principal Component Analysis</em></strong> algorithm.</p>



<p class="has-cyan-bluish-gray-background-color has-background">Note that this algo must be assisted in that it requires the user to input the number of clusters to create. Each of them will have a center point called “centroid”.</p>



<p>Here is the procedure that will be run under the hood once we execute our code:</p>



<ul class="wp-block-list"><li>Choose number of clusters K to look for (human input)</li><li>Initialize K centroids randomly</li></ul>



<ul class="wp-block-list"><li>Compute mean-square distance of each datapoint with each centroid</li><li>Assign each datapoint to the closest centroid (a cluster)</li><li>Compute the mean of each cluster, which becomes your new centroids</li></ul>



<p>The previous 3 steps make up what is called an <em>epoch</em>.</p>



<p>The program we will create will keep running epochs until centroids stop changing, i.e. convergence is obtained.</p>



<p>An image is worth a thousand words, so here is what it looks like:</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh3.googleusercontent.com/ARsbWnLjvLpB5h068Uqoaj-HJruBcY4sODSe7heeuoT-ulVLW-l-1f9UKeEfeCxTiwSeeEHpf9s18JCMmaf4o465BfJAwTdZYPiVzUPRyXUNsBR4262aL03_KCIlu4C5Y0GfSQuc" alt=""/></figure>



<p><strong><em>Does K-means have a loss function?</em></strong></p>



<p>Yes, it is called inertia and is the sum of squares of distances between data points and their respective centroids.</p>



<p>In practice</p>



<ul class="wp-block-list"><li>K-means is usually run a few times with different random initializations</li><li>Can use random mini-batch at each epoch instead of full dataset, for faster convergence</li><li>Algorithm is quite fast</li></ul>



<h2 class="wp-block-heading">Installing the Module</h2>



<p>The module that we will be using to perform this task is <a href="https://blog.finxter.com/scikit-learn-cheat-sheets/" target="_blank" rel="noreferrer noopener" title="[Collection] 10 Scikit-Learn Cheat Sheets Every Machine Learning Engineer Must Have">Scikit-Learn</a>, a very handy module when it comes to Machine Learning in Python.</p>



<p>If you do not already have it, proceed with the usual install command:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install scikit-learn</pre>



<p>Then, check it installed correctly:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip show scikit-learn</pre>



<p>Here is the sklearn documentation page dedicated to Kmeans: <a href="https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans">https://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html#sklearn.cluster.KMeans</a> , do not hesitate to check it for more details on the arguments you can pass and a more advanced use.</p>



<p>Once this is done, we will import the <a href="https://blog.finxter.com/tutorial-how-to-run-k-means-clustering-in-1-line-of-python/" target="_blank" rel="noreferrer noopener" title="[Tutorial] How to Run K-Means Clustering in 1 Line of Python?">Kmeans </a>class within this module:</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh6.googleusercontent.com/gpAtucNhEBxuRwF-zbRSpn4ej7OxXSRI_QL7PYnfgJnzWm1nJk1NKdbXCdezHPYJKyT0NWB4bIkbymen5uoFJL5aFX2wjHODyctRJtDs4brlFHB8iLX8mQeh8yeEcOqcYpR4m0Cl" alt=""/></figure>



<p>The first line is the import.</p>



<h2 class="wp-block-heading">Making the Magic Happen</h2>



<p>The second line instantiates the Kmeans class by creating an actual <code>Kmeans</code> object, here is it put in a <code>‘km’</code> variable and the user asked for the creation of 3 clusters.</p>



<p>The third line launches the computation of the clustering.</p>



<p>Once your K-Means model is fitted, you can use four <a href="https://blog.finxter.com/how-to-access-an-object-attribute-given-the-attribute-name-as-a-string/">attributes</a> that speak for themselves:</p>



<ul class="wp-block-list"><li><code>km.cluster_centers_</code> : provides the coordinates of each centroid</li><li><code>km.labels_</code> provides the cluster number of each datapoint (indexing starts at 0 like <a href="https://blog.finxter.com/python-list-methods/">lists</a>)&nbsp;</li><li><code>km.inertia_</code> : yields the sum of squared distances of samples to their closest centroid</li><li><code>km.n_iter_</code> : provides the number of epochs run</li></ul>



<p>If you want to try it but do not have a dataset ready, you can generate your own points thanks to sklearn <a href="https://scikit-learn.org/stable/modules/generated/sklearn.datasets.make_blobs.html" target="_blank" rel="noreferrer noopener"><code>make_blob</code></a> feature!</p>



<p>Here is an example output in 2D, with a PCA dimensionality reduction as you can see on the x and y axes:</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh4.googleusercontent.com/Xp0O_73B8Tll6lT78bvmUi-TXQgnYXMSyrOOffspXDeCFMpTvpKYKnvpfdjf3Y1nwemSqfIUArhpJythcAdiUzHUMu0m6pGN1KucwulwyhGumsjdFHxJbFeWCOMvgYut74BwDBu4" alt=""/></figure>



<p>I showed you the attributes, what about the <a href="https://blog.finxter.com/python-classmethod/" target="_blank" rel="noreferrer noopener">methods</a> available?</p>



<p>The most useful one probably is the <code>.predict(new_datapoint)</code> method, that returns an integer corresponding to the cluster (number) estimated by the model.</p>



<h2 class="wp-block-heading">How to Pick the Best Number of Clusters</h2>



<p>Wait, this is all very nice if I know what to expect in terms of number of clusters, as i can then input this number, but what if I have no idea how many clusters to expect?</p>



<p>Then use the elbow method. It means graph the evolution of the inertia according to the number of clusters, and pick the number of clusters after which decrease in inertia becomes marginal:</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh6.googleusercontent.com/Mb0xPtzTvfOd-AkR6AFoSbuJMWBUptV-pZmVNfYOE2phx9vGD9U-_7mUxPSPHV52-qzvyF4z7phcDhuxu6I5FjDawK8U4A7_CWj5iDE2PYEDQQLeCHqn7Go0BwlbeNbHzeaComMj" alt=""/></figure>



<p>In the above example, the ideal number of clusters seems to be 3. The graph is elbow-shaped, hence the name.</p>



<h2 class="wp-block-heading">K-Means with <a href="https://blog.finxter.com/6-best-python-nlp-libraries/" target="_blank" rel="noreferrer noopener">NLP</a>: Displaying a Wordcloud</h2>



<p>Assuming you used a K-Means algorithm within a <a href="https://blog.finxter.com/6-best-python-nlp-libraries/" target="_blank" rel="noreferrer noopener">Natural Language Processing</a> task, after preprocessing and vectorizing the words, you may be in need of a visual way to present your output.</p>



<p>Indeed, sometimes the number of clusters will be high and displaying labels in a grid will not be that impactful.</p>



<p>Then comes into play the <a href="https://pypi.org/project/wordcloud/" target="_blank" rel="noreferrer noopener">wordcloud module</a>, enabling you to generate easily pretty, colourful wordclouds for instant understanding.</p>



<p>Just <code>pip install wordcloud</code> and use&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">plt.imshow( Wordcloud().generate(your_text) )</pre>



<p>See documentation for parameters.</p>



<figure class="wp-block-image"><img decoding="async" src="https://lh5.googleusercontent.com/uKV6MHVQJx31FtHeRqQmwtbXvoonq4gvVq1ent81dtvxinHogxAGMEtg8P2_ymhWVXbDfLszuQGVRl0fdO5rt47KOtOr5fxUJcXMtvpc5y2QP6F-pQJlCbKVamf_9isIOfQpS_qd" alt=""/></figure>



<figure class="wp-block-image"><img decoding="async" src="https://lh5.googleusercontent.com/DmSXL0Sk57b-CoRF8TwuzY5pbmZvC-7qwPLGxCBgAwNK_MXwVvs_kLcqCCLY4k5fE3ByNmddi4ZjLzkL6HmYpUqj4v4hhNVU48F3IaT6DRzlwFHJrvEqXV3JVYvsvoCABs6u5lDl" alt=""/></figure>



<p>In my example shown above, I was dealing with Irish PDF reports, and in each report part of the content was written in Gaelic.&nbsp;</p>



<p><strong><em>Guess what the algo found? Look at the bottom cluster!</em></strong></p>



<p>This illustrates the “unsupervised” characteristic: I did not tell it there was another language, and yet it found it and isolated it by itself!</p>



<h2 class="wp-block-heading">Where to Go From Here?</h2>



<p>I hope you enjoyed this article. To go deeper into the topics, do check the documentation and experiment yourself:</p>



<ul class="wp-block-list"><li>PCA analysis</li><li>More clustering techniques: <a href="https://scikit-learn.org/stable/modules/clustering.html" target="_blank" rel="noreferrer noopener">https://scikit-learn.org/stable/modules/clustering.html</a></li><li>More ideas to implement this algorithm : <a href="https://dzone.com/articles/10-interesting-use-cases-for-the-k-means-algorithm" target="_blank" rel="noreferrer noopener">https://dzone.com/articles/10-interesting-use-cases-for-the-k-means-algorithm</a></li></ul>



<p>Any comments? Let us know!</p>
<p>The post <a href="https://blog.finxter.com/k-means/">The K-Means Algorithm in Python</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>EZGmail and Python &#8212; Managing Your Emails Programmatically</title>
		<link>https://blog.finxter.com/ezgmail-python-managing-your-emails-programmatically/</link>
		
		<dc:creator><![CDATA[Clement Lelievre]]></dc:creator>
		<pubDate>Tue, 26 Jan 2021 09:41:56 +0000</pubDate>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<guid isPermaLink="false">https://blog.finxter.com/?p=22079</guid>

					<description><![CDATA[<p>Hey Finxters! Among the many daily tasks you can achieve with Python, there is one Siri-like task that comes quite handy: managing your emails in a programmatic way.&#160; Of course, many emails need your human understanding to be processed properly, and this article is not about implementing a neural network to fine-tune every single email ... <a title="EZGmail and Python &#8212; Managing Your Emails Programmatically" class="read-more" href="https://blog.finxter.com/ezgmail-python-managing-your-emails-programmatically/" aria-label="Read more about EZGmail and Python &#8212; Managing Your Emails Programmatically">Read more</a></p>
<p>The post <a href="https://blog.finxter.com/ezgmail-python-managing-your-emails-programmatically/">EZGmail and Python &#8212; Managing Your Emails Programmatically</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Hey Finxters! Among the many daily tasks you can achieve with Python, there is one <strong><em>Siri</em></strong>-like task that comes quite handy: <strong><em>managing your emails in a programmatic way</em></strong>.&nbsp;</p>



<p>Of course, many emails need your human understanding to be processed properly, and this article is not about implementing a neural network to fine-tune every single email action.&nbsp;</p>



<p>However, it is about learning a key asset: how to implement a code to manage simple tasks on a Gmail account, with the <code>ezgmail</code> module, such as:&nbsp;&nbsp;</p>



<ul class="wp-block-list"><li><strong>receiving </strong>and reading your unread messages&nbsp;</li><li><strong>sending </strong>emails, including attachments&nbsp;</li><li><strong>downloading </strong>attachments&nbsp;</li><li><strong>viewing </strong>your recent messages&nbsp;</li></ul>



<p>Building on these simple tasks, you will then be able to endlessly tailor your mailbox according to your personal needs, such as for example:&nbsp;</p>



<ul class="wp-block-list"><li><strong>trigger automatic replies</strong> based on specific strings found in an email body and/or subject,</li><li><strong>block a sender</strong> by throwing to the bin emails based on sender email address, or</li><li>albeit more elaborate, make your very own <strong>spam detector </strong>by injecting an NLP algorithm in your program.</li></ul>



<p>Lets get started!&nbsp;</p>



<h2 class="wp-block-heading">Setting It Up</h2>



<p>For this project to work, you need two things:&nbsp;</p>



<ul class="wp-block-list"><li>installing the right module</li><li>enabling the Gmail API</li></ul>



<h3 class="wp-block-heading">Install the ezgmail Module</h3>



<p>The module well be working with is called <code>ezgmail</code>, and you can install it with the usual command:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install ezgmail</pre>



<p>or</p>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip3 install ezgmail</pre>



<p>Alternatively, you may run </p>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip install --user -upgrade ezgmail</pre>



<p> on Windows, to make sure you get the latest version.&nbsp;</p>



<p>To check it installed correctly, you can then check the version with the following command line argument:&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="powershell" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">pip show ezgmail </pre>



<p>Note that this module is not produced by or affiliated with Google. It was developed by software programer <strong><em>Al Sweigart</em></strong> and you can find all the details here: <a href="https://github.com/asweigart/ezgmail" target="_blank" rel="noreferrer noopener">https://github.com/asweigart/ezgmail</a>&nbsp;</p>



<h3 class="wp-block-heading">Enabling the Gmail API&nbsp;</h3>



<p>First of all, I highly recommend you setup a separate Gmail account for this project. This will prevent any unexpected event from altering your mailbox in any unwanted way.&nbsp;</p>



<p>So, start out by signing up for a new Gmail account, then visit this page: <a href="https://developers.google.com/gmail/api/quickstart/python" target="_blank" rel="noreferrer noopener">https://developers.google.com/gmail/api/quickstart/python</a>&nbsp;</p>



<p>Click Enable the Gmail API button, then fill in the form, after which you&#8217;ll see a link to a <code>credentials.json</code> file, which you&#8217;ll have to download and place in the same directory as your Python file. This is a requirement for the code to work. (For those who don&#8217;t know, basically, <a href="https://blog.finxter.com/python-one-line-pretty-print-json/" target="_blank" rel="noreferrer noopener" title="Pretty Print JSON [Python One-Liner]">json</a> is a popular and widespread format that looks like a <a href="https://blog.finxter.com/python-dictionary/" target="_blank" rel="noreferrer noopener" title="Python Dictionary – The Ultimate Guide">dictionary </a>in Python.)&nbsp;</p>



<p>Consider this file content the same as your Gmail password, so keep it secret.&nbsp;</p>



<p>When you will run your Python code to manage your Gmail account, the code will first visit the <code>json</code> file directory in order to fetch your credentials from the <code>credentials.json</code> file.&nbsp;</p>



<p>This provides additional security as unlike other modules, with <code>ezgmail</code> you do NOT have to type in plain text your credentials in the program.&nbsp;</p>



<p><strong><em>Time to start: enter the following code: </em></strong></p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">import ezgmail, os
# change dir to the one where json credentials are saved:
os.chdir(r'C:/path_to_credentials_json_file')
ezgmail.init()</pre>



<p>As a side remark, notice that you could have achieved what the second line does (i.e., changing the current working directory to the directory containing the file <code>credentials.json</code>) with the <a href="https://blog.finxter.com/python-exec/" title="Python exec() — A Hacker’s Guide to A Dangerous Function" target="_blank" rel="noreferrer noopener">Python <code>exec()</code></a> function!</p>



<p>Something like:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">exec(import os; os.system(cd path_to_credentials_json_file))  </pre>



<p>The <code>.init()</code> method will open your browser towards a Google page where you can login. Type your credentials, you may then see This app isn&#8217;t verified: this is OK (believe me, I did it before you and I&#8217;m fine!), click <strong>Advanced</strong>, then <strong>Go to quickstart (unsafe)</strong>.&nbsp;</p>



<p>When the next page prompts you with Quickstart wants to access your Google account, allow it, then close the browser.&nbsp;</p>



<p>You&#8217;re almost done with the setup phase.&nbsp;&nbsp;</p>



<p>What just happened is a <code>token.json</code> file was created, and this will be used to provide your Python code access to the Gmail account you created for this project. Keep this one safe, too.&nbsp;</p>



<p>So from now on, you will no longer need to manually type your credentials.&nbsp;</p>



<p>You&#8217;re good to go! Starting now, the <code>.init()</code> method should no longer be necessary.&nbsp;&nbsp;</p>



<h2 class="wp-block-heading">Sending emails&nbsp;</h2>



<p>The method is quite straightforward: <code>ezgmail.send()</code> </p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">ezgmail.send('recipient@gmail.com', 'test', 'hello world!')</pre>



<p>Here are the arguments that you can pass: </p>



<p></p>



<p>Mandatory <code>args</code> are:&nbsp;</p>



<ul class="wp-block-list"><li>recipient&nbsp;</li><li>subject&nbsp;</li><li>body&nbsp;</li></ul>



<p>Optional, <code>kwargs</code> are:&nbsp;</p>



<ul class="wp-block-list"><li>attachment (you can pass a list if there are several)&nbsp;</li><li>sender&nbsp;</li><li>cc (might not work at the moment, as per the github page)&nbsp;</li><li>bcc (might not work at the moment, as per the github page)&nbsp;</li></ul>



<p>Forgot the email address the <code>token.json</code> was setup for?&nbsp;</p>



<p>Just check the attribute <code>ezgmail.EMAIL_ADDRESS</code> <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /> </p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">ezgmail.EMAIL_ADDRESS</pre>



<h2 class="wp-block-heading">Receiving emails&nbsp;</h2>



<p>There are two steps involved:</p>



<ul class="wp-block-list"><li>Reading the email, and</li><li>Downloading its attachments.</li></ul>



<h3 class="wp-block-heading">Reading mail&nbsp;</h3>



<p>The <code>ezgmail</code> package structures emails just like the GUI email client does: it organizes them into threads, that can in turn contain multiple messages.&nbsp;</p>



<p>Hence the method <code>.unread()</code> lists the <code>GmailThread</code> objects. </p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">print(ezgmail.unread())</pre>



<p><strong><em>Want to read a specific email within a thread?&nbsp;</em></strong></p>



<p>The <code>.messages</code> attribute is just what you need. It is subscriptable: </p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">unreadThreads = ezgmail.unread()
print(unreadThreads[0].messages[0].body)</pre>



<p>It comes with a bunch of attributes such as <code>sender</code>, <code>recipient</code>, <code>body</code>, <code>timestamp</code> etc.&nbsp;</p>



<p>Also check the <code>.recent()</code> method: it yields the 25 most recent threads of your Gmail account. </p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">recentThreads = ezgmail.recent()
print(ezgmail.summary(recentThreads))</pre>



<h3 class="wp-block-heading">Downloading attachments&nbsp;</h3>



<p>A <code>GmailMessage</code> object carries an attachments attribute that&#8217;s a <a href="https://blog.finxter.com/python-lists/" target="_blank" rel="noreferrer noopener" title="The Ultimate Guide to Python Lists">list </a>of filenames.&nbsp;</p>



<p>Pass any combination of these filenames in the <code>.downloadAttachment()</code> method to download the files, or if you want all of them, use the <code>.downloadAllAttachments()</code> method, which even has an argument enabling&nbsp; you to specify where to download the files (default the current working directory).&nbsp;</p>



<h2 class="wp-block-heading">Searching mail&nbsp;</h2>



<p>You guessed it use the <code>ezgmail.search()</code> method!&nbsp;</p>



<p>Enter a string in this method just like you would in a GUI mailbox.&nbsp;</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">resultThreads = ezgmail.search('json')
ezgmail.summary(resultThreads)</pre>



<p>This returns a list of threads (remember the <code>GmailThreads</code> objects?) </p>



<p>You can then pass the above mentioned attributes to retrieve specific info about a message.&nbsp;</p>



<h2 class="wp-block-heading">Where to go from here?&nbsp;</h2>



<p>Try it yourself!&nbsp;</p>



<p>And do discover the other features provided by this efficient and user-friendly module!&nbsp;</p>



<ul class="wp-block-list"><li>Maybe you need it to automate a newsletter?&nbsp;</li><li>Or to setup email reminders for your personal need?&nbsp;</li><li>Or at work?&nbsp;</li></ul>



<p><a href="https://blog.finxter.com/subscribe/" target="_blank" rel="noreferrer noopener" title="Subscribe">Let us know!&nbsp;</a></p>



<p>A few concluding remarks:&nbsp;</p>



<ul class="wp-block-list"><li>in general, for this to work the email account needs to be configured with the lowest level of security, else the email will end-up either blocked or in the spams&nbsp;</li><li>you may not be able to send repeated emails with the exact same text (as these probably are spams) nor with <code>.exe</code> attachments (since these are probably viruses)&nbsp;</li><li>please use this technology responsibly&nbsp;</li><li>thanks to Al Sweigart for creating and maintaining this awesome module&nbsp;</li><li>just because it currently works doesn&#8217;t mean it will forever; it is reliant on Googles choices among other things, and this module behaviour through time cannot be guaranteed&nbsp;</li></ul>



<p>Last, if you need to process emails from an account other than Gmail, you should check the right modules to send and receive emails from any account, respectively using SMTP and IMAP protocols.&nbsp;</p>
<p>The post <a href="https://blog.finxter.com/ezgmail-python-managing-your-emails-programmatically/">EZGmail and Python &#8212; Managing Your Emails Programmatically</a> appeared first on <a href="https://blog.finxter.com">Be on the Right Side of Change</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>

<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/?utm_source=w3tc&utm_medium=footer_comment&utm_campaign=free_plugin

Page Caching using Disk: Enhanced 
Minified using Disk

Served from: blog.finxter.com @ 2026-06-05 20:33:47 by W3 Total Cache
-->