<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emilia G.</title>
    <description>The latest articles on DEV Community by Emilia G. (@emigs1995).</description>
    <link>https://dev.to/emigs1995</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1311251%2F5f226326-fddd-40a9-b01c-f1dd024b88b5.jpg</url>
      <title>DEV Community: Emilia G.</title>
      <link>https://dev.to/emigs1995</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emigs1995"/>
    <language>en</language>
    <item>
      <title>A Sneak Peek at our Haskell Training Course</title>
      <dc:creator>Emilia G.</dc:creator>
      <pubDate>Wed, 20 Mar 2024 19:55:43 +0000</pubDate>
      <link>https://dev.to/emigs1995/a-sneak-peek-at-our-haskell-training-course-3mnh</link>
      <guid>https://dev.to/emigs1995/a-sneak-peek-at-our-haskell-training-course-3mnh</guid>
      <description>&lt;p&gt;Our Haskell training course is a unique part of working as an engineer in Stack Builders. It helps to build our community and helps engineers see problems in new ways, regardless of whether they’re working on Haskell projects, or in languages. We hope that this high-level overview helps you to find the motivation to learn Haskell.&lt;/p&gt;

&lt;p&gt;Given the interest in our last post “&lt;a href="https://www.stackbuilders.com/blog/the-uncommon-advantage-from-training-in-unpopular-programming-languages/"&gt;The Uncommon Advantage from Training in Unpopular Programming&lt;/a&gt;“, we wanted to provide some more details on the Haskell Language Training Course used for full-time staff at Stack Builders. For the past 9 years, we’ve offered Haskell training to our developers. During this time, we’ve taught approximately a hundred developers and invested thousands of hours in learning and sharing Haskell concepts. In this article, we highlight the curriculum and experiences of some of our developers - we hope that it’s useful in your own Haskell journey or if you decide to implement your own in-house Haskell training program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our industry-relevant Haskell curriculum&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stack Builders' 10-week Haskell course is crafted based on our extensive experience in the software industry. The curriculum is designed to meet the demands of real-world projects, ensuring that participants gain practical skills applicable to commercial software development.&lt;br&gt;
These are the modules of our Haskell course. Each module offers a variety of exercises that help implement learning hands-on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Module 1: Introduction (Getting started and Types and classes)&lt;/li&gt;
&lt;li&gt;Module 2: Functions (Defining functions and Recursive and higher-order functions)&lt;/li&gt;
&lt;li&gt;Module 3: Types and classes and IO&lt;/li&gt;
&lt;li&gt;Module 4: Monads (Functors, Applicatives, and Monads)&lt;/li&gt;
&lt;li&gt;Module 5: Lazy evaluation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We use &lt;a href="https://www.cs.nott.ac.uk/~pszgmh/pih.html"&gt;Programming in Haskell by Graham Hutton&lt;/a&gt; to support our course, but we encourage developers to refer to resources including the following to supplement “Programming in Haskell”:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://learnyouahaskell.com/"&gt;Learn you a Haskell for great good&lt;/a&gt;! by Miran Lipovača&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.manning.com/books/get-programming-with-haskell"&gt;Get Programming with Haskell&lt;/a&gt; by Will Kurt&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/severij/cis194-solutions"&gt;CIS 194: Introduction to Haskell (Spring 2013)&lt;/a&gt; by Brent Yorgey&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/kowainik/learn4haskell"&gt;Learn4Haskell&lt;/a&gt; by Kowainik&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hands-on mentorship and code reviews&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Unlike many online courses that rely solely on pre-recorded lectures, our course offers close guidance, mentorship, and code reviews in smaller teams. Each module has programming exercises that we’ve selected from several resources to ensure our developers are clear on concepts and can apply them later. This hands-on approach provides the opportunity to apply theoretical knowledge to actual coding scenarios. This prepares our developers to work on real-world Haskell projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Focus on functional programming principles&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our course goes beyond teaching Haskell syntax. It emphasizes implementing functional programming principles in other languages, promoting cleaner code, improved maintainability, and enhanced software reliability. This approach sets it apart from courses that focus solely on language features without a broader perspective on software development.&lt;br&gt;
This is what our developers say about the Haskell Training Course at Stack Builders and how it has helped them grow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Jorge Galarza - Software Developer - 1.5 years at Stack Builders&lt;/strong&gt;&lt;br&gt;
The Haskell training course not only deepened my comprehension of functional programming but also instilled a commitment to fundamental functional programming principles. Whether working in Haskell or other languages, this experience influenced my approach to coding and also caused a paradigm shift in my conventional programming mindset. Consistently applying principles such as pure functions, immutability, and strong type systems has fostered code reliability and clarity leading to more resilient and forward-thinking software development in the projects that I've worked on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diego Balseiro - Senior Software Developer - 6 years at Stack Builders&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;The Haskell Training Course has been a part of our company for several years. It's a unique aspect of our business that sets us apart from others. Haskell is taught to all our employees, including our interns, which is something not many companies across the globe can say.&lt;br&gt;
Haskell is much more than just a programming language. It's a method of viewing computation that can offer a fresh perspective even when you're programming in more traditional languages like JavaScript or Python.&lt;br&gt;
Functional Programming and Haskell are at the core of Stack Builders. We believe that it's this focus that has contributed significantly to our success. Haskell offers a unique way to think and reason about code.&lt;br&gt;
Our Haskell course could provide you with a new set of tools for your developer toolkit to innovate and solve complex problems.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alex Mejía - Senior Software Developer - 3 years at Stack Builders&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Learning Haskell has been a great experience that has allowed me to be a better developer. It gave me the ability to be proficient in a new language and allowed me to be more effective in my current projects. It also gave me the ability to effectively use functional programming concepts in other languages like Python, JavaScript, and more.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Franz Guzmán - Software Developer - 2.5 years at Stack Builders&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;I began the course with some prior experience in Haskell. However, a certain curiosity persisted about what I could pick up from it, as most concepts were still unfamiliar to me. During the course, I not only demystified the language but also revealed its elegance and power. What stood out for me was the ability to effortlessly build upon existing software through a simple analysis of the function's input and output types. The course also highlighted functional thinking, encouraging us to view inputs as data streams and enabling the seamless chaining of data transformations. This paradigm has proven to be a valuable skill applicable to any programming language, especially as modern languages increasingly embrace the functional approach.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Haskell training course is a unique part of working as an engineer in Stack Builders. It helps to build our community and helps engineers see problems in new ways, regardless of whether they’re working on Haskell projects, or in languages like Python, TypeScript, or Kotlin. While we aren’t able to make the course available externally at this time, we hope that this high-level overview helps you to find the motivation to learn Haskell on your own or start an in-house Haskell initiative at the company where you work. &lt;/p&gt;

&lt;p&gt;Feel free to contact us if you have questions or would like information on joining our team.&lt;/p&gt;

</description>
      <category>haskell</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
    <item>
      <title>Combining Nix with Terraform for better DevOps</title>
      <dc:creator>Emilia G.</dc:creator>
      <pubDate>Mon, 18 Mar 2024 19:07:30 +0000</pubDate>
      <link>https://dev.to/emigs1995/combining-nix-with-terraform-for-better-devops-4bce</link>
      <guid>https://dev.to/emigs1995/combining-nix-with-terraform-for-better-devops-4bce</guid>
      <description>&lt;p&gt;An investment in creating the best software in the world will still go to waste if the infrastructure it runs on isn’t well-managed. At Stack Builders, our mission is to push the boundaries of the software industry through quality, pragmatic solutions that bring to life our client's vision, and one way we are doing this is to leverage our training and staff experience with functional programming to make DevOps better.&lt;/p&gt;

&lt;p&gt;In that light, we’re thrilled to announce the release of &lt;a href="https://github.com/stackbuilders/nixpkgs-terraform/"&gt;nixpkgs-terraform&lt;/a&gt;! This Nix project significantly enhances the flexibility and control of your Terraform environment, making its installation and management declarative and reproducible. This is largely thanks to Nix and its unique capabilities for precisely pinning packages to a version, ensuring its consistency across different environments. Forget about writing documentation on environment setup - just use one of the provided &lt;a href="https://github.com/stackbuilders/nixpkgs-terraform/tree/main/templates"&gt;templates&lt;/a&gt; to bootstrap your Terraform installation and get the whole team on the same version with minimal manual intervention.&lt;/p&gt;

&lt;p&gt;No need for deep knowledge of Nix either - just keep adding tools to your template of choice to craft a reproducible, declarative, and portable development environment for everyone on the project so that you can focus on what matters.&lt;/p&gt;

&lt;p&gt;At Stack Builders, our DevOps/SRE team uses nix-shells to install all of the necessary tooling to work on various Infrastructure-as-Code projects across the board. However, while nix-shells are useful for creating portable development environments, more fine-grained control over the different Terraform versions was lacking. We've taken inspiration from &lt;a href="https://github.com/cachix/nixpkgs-python"&gt;nixpkgs-python&lt;/a&gt; and &lt;a href="https://github.com/bobvanderlinden/nixpkgs-ruby"&gt;nixpkgs-ruby&lt;/a&gt;, and we're grateful for the paths they've paved.&lt;/p&gt;

&lt;p&gt;We’ve noticed that some users have been asking about how to use older versions of Terraform in their Nix setups [&lt;a href="https://discourse.nixos.org/t/use-a-specific-version-of-terraform-in-a-nix-shell/27880"&gt;1&lt;/a&gt;, &lt;a href="https://github.com/NixOS/nixpkgs/issues/218617"&gt;2&lt;/a&gt;]. This is an example of the diverse needs of people and the importance of maintaining backward compatibility. We hope that nixpkgs-terraform will be a useful tool for these users.&lt;/p&gt;

&lt;p&gt;The design of nixpkgs-terraform follows a bottom-up approach, making it more approachable for newcomers. We hope this will empower everyone to take their Nix experience to the next level!&lt;/p&gt;

&lt;p&gt;Looking forward to your feedback and contributions. Happy Nixing!&lt;/p&gt;

&lt;p&gt;Don't forget to subscribe to our &lt;a href="https://www.stackbuilders.com/blog/"&gt;newsletter&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>terraform</category>
      <category>nix</category>
      <category>programming</category>
    </item>
    <item>
      <title>Video Generation with Python</title>
      <dc:creator>Emilia G.</dc:creator>
      <pubDate>Mon, 11 Mar 2024 21:21:21 +0000</pubDate>
      <link>https://dev.to/emigs1995/video-generation-with-python-192f</link>
      <guid>https://dev.to/emigs1995/video-generation-with-python-192f</guid>
      <description>&lt;p&gt;Python has become a popular programming language for different applications, including data science, artificial intelligence, and web development. But, did you know creating and rendering fully customized videos with Python is also possible? At Stack Builders, we have successfully used Python libraries such as &lt;a href="https://zulko.github.io/moviepy/"&gt;MoviePy&lt;/a&gt;, &lt;a href="https://scipy.org/"&gt;SciPy&lt;/a&gt;, and &lt;a href="https://imagemagick.org/"&gt;ImageMagick&lt;/a&gt; to generate videos with animations, text, and images. In this article, we will look closer at how Python can be used for video generation and explore some of the powerful libraries and tools that make it possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;Creating a customized video might sound easy, especially if tools for video editing are an option. Creating one or maybe a couple of them might even sound fun, but if you need to generate hundreds or even thousands of customized videos daily, this does not sound like a good idea. Imagine&lt;br&gt;
Facebook manually creating millions of videos for friendship anniversaries, birthdays and marketing campaigns for all their users. That would require an extreme amount of time to do, create delays in the delivery of the videos, and take away from an ideal user experience.&lt;/p&gt;

&lt;p&gt;Producing a video programmatically might not be a task developers come across daily. Having a firm understanding of what the final video should look like is vital for accomplishing this task.&lt;/p&gt;
&lt;h2&gt;
  
  
  Facing the Challenge
&lt;/h2&gt;

&lt;p&gt;Here is where software development comes in handy and helps automate tasks to make our lives easier once again. Having a toolbelt filled with tools like Python gives us the upper hand in this challenge. This tutorial will explain how to work with multiple video segments using &lt;code&gt;MoviePy&lt;/code&gt; tools together.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is MoviePy?
&lt;/h2&gt;

&lt;p&gt;You might have heard of &lt;a href="https://ffmpeg.org/"&gt;FFMPEG&lt;/a&gt; or &lt;a href="https://imagemagick.org/"&gt;ImageMagick&lt;/a&gt; for image and video edition in a programmatic way. &lt;a href="https://zulko.github.io/moviepy/"&gt;MoviePy&lt;/a&gt; is a Python module for video editing (Python wrapper for FFMPEG and ImageMagick). It provides&lt;br&gt;
functions for cutting, concatenations, title insertions, video compositing, video processing, and the creation of custom effects. It can read and write common video and audio formats and be run on any platform with Python 2.7 or 3+.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is ImageMagick?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://imagemagick.org/"&gt;ImageMagick&lt;/a&gt; is an open-source software suite used for editing and manipulating digital images. It includes a command-line interface for executing complex image processing tasks, as well as APIs for integrating its features into software applications. &lt;code&gt;MoviePy&lt;/code&gt; &lt;a href="https://moviepy-tburrows13.readthedocs.io/en/improve-docs/ref/VideoClip/TextClip.html"&gt;TextClip&lt;/a&gt; requires ImageMagick. &lt;/p&gt;
&lt;h2&gt;
  
  
  What is SciPy?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://scipy.org/"&gt;SciPy&lt;/a&gt; is a library used for scientific computing and technical computing. SciPy contains modules for image processing. MoviePy video tools plugins like &lt;a href="https://zulko.github.io/moviepy/ref/videotools.html#moviepy.video.tools.segmenting.findObjects"&gt;&lt;code&gt;Segmenting&lt;/code&gt;&lt;/a&gt; benefit from this to locate objects and separate them.&lt;/p&gt;
&lt;h2&gt;
  
  
  What Do We Need?
&lt;/h2&gt;

&lt;p&gt;For this tutorial, ImageMagick is required and Python 3 with pipenv to manage its dependencies. All the modules can be installed from PyPI (Python Package Index) using &lt;code&gt;pip&lt;/code&gt;. For further instructions check the &lt;a href="https://github.com/stackbuilders/blog-code/blob/main/python/python-video-generation/code/Readme.md"&gt;readme file&lt;/a&gt; for this tutorial.&lt;/p&gt;
&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;This sample code will help to understand some basic concepts about Python, MoviePy and image processing libraries.&lt;/p&gt;
&lt;h3&gt;
  
  
  Importing the libraries
&lt;/h3&gt;

&lt;p&gt;Go the root directory of your project and create a new file named &lt;code&gt;python_video.py&lt;/code&gt; and start by adding the required libraries at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;moviepy.editor&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;mpy&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;moviepy.video.tools.segmenting&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;findObjects&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this piece of code we are telling Python to add the libraries that are going to be used in this tutorial. To keep it simple, we are adding all of the MoviePy tools inside its &lt;em&gt;editor&lt;/em&gt; module and renaming it to mpy to keep it short.&lt;/p&gt;

&lt;p&gt;In the next line, the MoviePy plugin &lt;code&gt;find_objects&lt;/code&gt; is imported to locate and separate objects in a clip. We are adding it to locate five stars in an PNG file for later animating them in the final clip.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating Constants
&lt;/h3&gt;

&lt;p&gt;First of all, we are going to create some constants to keep the code easy to understand. The first one is &lt;code&gt;WHITE&lt;/code&gt;. It is&lt;br&gt;
going to be the background color. MoviePy uses the traditional&lt;br&gt;
RGB scale (0 - 255).&lt;/p&gt;

&lt;p&gt;The second one is &lt;code&gt;SCREEN_SIZE&lt;/code&gt;. We will be using a standard of &lt;code&gt;640x480&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The rest of them, &lt;code&gt;VERTICAL_SPACE&lt;/code&gt; and &lt;code&gt;HORiZONTAL_SPACE&lt;/code&gt;, are used for adding homogenous horizontal and vertical space across elements in the video:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;WHITE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;SCREEN_SIZE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;640&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;480&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;VERTICAL_SPACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;
&lt;span class="n"&gt;HORIZONTAL_SPACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding an Image File
&lt;/h3&gt;

&lt;p&gt;It's time to use MoviePy! We can add some images to the video to make it more attractive to the viewers. For this we will be using the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;SB_LOGO_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./static/StackBuildersLogo.jpg&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;sb_logo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ImageClip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SB_LOGO_PATH&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;\
    &lt;span class="nf"&gt;set_position&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;center&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;\
    &lt;span class="nf"&gt;resize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;mpy.ImageClip&lt;/code&gt; function receives as a parameter the image to render. In this case the image path is set in the constant &lt;code&gt;SB_LOGO_PATH&lt;/code&gt;. Using &lt;code&gt;ImageClip&lt;/code&gt; attributes, it's possible to position the image using x, y coordinates. In this case, it's possible to mix keywords like &lt;code&gt;center&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt; and &lt;code&gt;top&lt;/code&gt; with specific coordinates.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;resize&lt;/code&gt; attribute reduces the size of the image keeping its ratio aspect using the key arguments &lt;code&gt;width&lt;/code&gt; or &lt;code&gt;height&lt;/code&gt; like in the snippet.&lt;br&gt;
It is possible to set a custom size explicitly using a tuple with the new dimensions &lt;code&gt;(width, height)&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Writing Text
&lt;/h3&gt;

&lt;p&gt;Now that we have the image in place, using &lt;code&gt;TextClip&lt;/code&gt; we are able to create an instance of a video with centered text below the logo image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;    &lt;span class="n"&gt;txt_clip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;TextClip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Let&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s build together&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;font&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Charter-bold&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;RoyalBlue4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;kerning&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;fontsize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;\
    &lt;span class="nf"&gt;set_position&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;center&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sb_logo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;VERTICAL_SPACE&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The variable &lt;code&gt;txt_clip&lt;/code&gt; is created for use in video composition later; it is a &lt;a href="https://moviepy-tburrows13.readthedocs.io/en/improve-docs/ref/VideoClip/TextClip.html"&gt;&lt;code&gt;TextClip&lt;/code&gt;&lt;/a&gt; instance that receives the text to display as the first parameter. The other parameters are used to style the text. Setting &lt;code&gt;font&lt;/code&gt;, &lt;code&gt;color&lt;/code&gt;, &lt;code&gt;kerning&lt;/code&gt; and &lt;code&gt;fontsize&lt;/code&gt; is enough.&lt;/p&gt;

&lt;p&gt;Finally, it sets the position it will have when included in compositions, with the function &lt;code&gt;set_position&lt;/code&gt;, it receives a tuple that contains the horizontal and vertical values. The positions are set here directly to use the &lt;code&gt;sb_logo&lt;/code&gt; attribute &lt;code&gt;size&lt;/code&gt; that provides a tuple of the clip dimensions &lt;code&gt;(width, height)&lt;/code&gt;. This helps to calculate in an easier way&lt;br&gt;
the &lt;code&gt;y-position&lt;/code&gt; of each clip. In this case the text is horizontally centered using the &lt;code&gt;center&lt;/code&gt; key and has a calculated vertical space value based on the logo clip vertical size plus a constant to put some extra space.&lt;/p&gt;

&lt;p&gt;Let’s also add an additional text to the video. As the &lt;code&gt;txt_clip&lt;/code&gt;, create a new variable named &lt;code&gt;txt_watermarkr&lt;/code&gt; and add it after the &lt;code&gt;txt_clip&lt;/code&gt; code. This will work like a watermark to indicate that this video is made with Python so it will have a light red color and will be located at the bottom of the screen.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   txt_watermark = mpy.TextClip(
       "This video was generated with Python",
       color="#ff8c82",
       kerning=4,
       fontsize=22,
       stroke_color="#ff8c82",
       stroke_width=0.4,
   ).set_position(("center", sb_logo.size[1] + txt_clip.size[1] + VERTICAL_SPACE * 6))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding Animation/FX
&lt;/h3&gt;

&lt;p&gt;With the text and image ready there is just one thing left to implement: Rotating stars (just because this video deserves 5 stars).&lt;/p&gt;

&lt;p&gt;MoviePy is capable of locating and separating objects like letters or shapes in a clip. In this case, we are going to use an image with stars to apply a rotate effect in each of them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;STARS_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./static/stars-5.png&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="n"&gt;stars_clip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CompositeVideoClip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;mpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ImageClip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;STARS_PATH&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;set_position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;center&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SCREEN_SIZE&lt;/span&gt;
&lt;span class="n"&gt;stars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;findObjects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stars_clip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As for the image file, we first start creating an &lt;code&gt;ImageClip&lt;/code&gt; with the image containing the stars by passing the path set in the constant 'STARS_PATH'.&lt;/p&gt;

&lt;p&gt;We can add it to a composite video by using &lt;code&gt;mpy.CompositeVideoClip&lt;/code&gt; we can generate a &lt;code&gt;VideoClip&lt;/code&gt; made up of other clips displayed together. For this sample the first parameter is a list with a single element and the second argument is the screen size &lt;code&gt;640x680&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, let’s assign it to the &lt;code&gt;stars_clip&lt;/code&gt; var to pass it as an argument in the function &lt;code&gt;findObjects&lt;/code&gt; to get each star separated in a list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;CLOCKWISE_ANGLE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;90&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;star&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;CLOCKWISE_ANGLE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vfx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mask_color&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_position&lt;/span&gt;&lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;HORIZONTAL_SPACE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sb_logo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;txt_clip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;VERTICAL_SPACE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;star&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the fun begins! As we said before, this video deserves 5 stars,&lt;br&gt;
and since configuring them to rotate one-by-one could be very repetitive, we are going to create a function that receives a list of stars and use a for loop in a list comprehension to return the list of stars inside clips (Like we&lt;br&gt;
did with the &lt;code&gt;txt_clip&lt;/code&gt; and &lt;code&gt;sb_logo&lt;/code&gt; clips) and rotating them in a clockwise direction. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;rotate&lt;/code&gt; function receives as a first parameter the stars &lt;code&gt;ImageClip&lt;/code&gt;s to rotate. It uses the video effects function &lt;code&gt;rotate&lt;/code&gt; with a lambda function as first parameter to rotate the star on its own axis in clockwise direction for each frame &lt;code&gt;t&lt;/code&gt; by multiplying the time in the video by (-90) degrees. The other parameter, &lt;code&gt;expand&lt;/code&gt;, is set to False to maintain the same size of the clip.&lt;/p&gt;

&lt;p&gt;If the angle of rotation is not one of 90, 180, -90, -180 (degrees) there will be black borders. We can make them transparent with &lt;code&gt;fx(mpy.vfx.mask_color)&lt;/code&gt;, which sets a transparent mask color by default.&lt;/p&gt;

&lt;p&gt;Finally, the position of each star is calculated so that they are centered below the image/text and horizontally separated equally between each other. &lt;/p&gt;
&lt;h3&gt;
  
  
  Generating the Video Clip
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;final_clip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;mpy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CompositeVideoClip&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;sb_logo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;txt_clip&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;SCREEN_SIZE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on_color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;WHITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;col_opacity&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set_duration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This piece of code is using &lt;code&gt;mpy.CompositeVideoClip&lt;/code&gt; to compose a video clip with the clips already created &lt;code&gt;sb_logo&lt;/code&gt; and &lt;code&gt;txt_clip&lt;/code&gt;. Additionally it concatenates to that all the rotating stars provided by our &lt;code&gt;rotate&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;The second parameter in &lt;code&gt;CompositeVideoClip&lt;/code&gt; is the size of the final clip, in this case &lt;code&gt;(640x480)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;on_color&lt;/code&gt; attribute helps to set the background color of the &lt;code&gt;VideoClip&lt;/code&gt;to &lt;code&gt;color=WHITE&lt;/code&gt;. The &lt;code&gt;on_color&lt;/code&gt; attribute has some extra parameters to change &lt;code&gt;size&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt; and &lt;code&gt;color opacity&lt;/code&gt;, but for now we don't need them.&lt;/p&gt;

&lt;p&gt;And last but not least, the video duration is set to 10 seconds using &lt;code&gt;set_duration&lt;/code&gt; attribute.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;final_clip&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write_videofile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;video_with_python.mp4&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fps&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the &lt;code&gt;write_videofile&lt;/code&gt; attribute writes in the disk the &lt;code&gt;VideoClip&lt;/code&gt;&lt;br&gt;
result of the &lt;code&gt;CompositeVideoClip&lt;/code&gt; stored in memory. Its first parameter is&lt;br&gt;
the &lt;code&gt;video file name&lt;/code&gt;, then we define the &lt;code&gt;fps&lt;/code&gt; rate. The &lt;code&gt;write_videofile&lt;/code&gt;&lt;br&gt;
has multiple parameters but we just need to set these two for now. You can also generate a GIF file by using &lt;code&gt;write_gif&lt;/code&gt; instead.&lt;/p&gt;

&lt;p&gt;Now if we run the code using &lt;code&gt;python python_video.py&lt;/code&gt;, we will&lt;br&gt;
have a 10 seconds video like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mWNhU48u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://raw.githubusercontent.com/stackbuilders/blog-code/main/python/python-video-generation/images/video.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mWNhU48u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://raw.githubusercontent.com/stackbuilders/blog-code/main/python/python-video-generation/images/video.gif" width="640" height="480"&gt;&lt;/a&gt; &lt;br&gt;
Figure 1  - Video generated by our code&lt;/p&gt;

&lt;p&gt;This might seem simple, but it's our first video generated by code! If you want to dig deeper into the code, you can find the &lt;a href="https://github.com/stackbuilders/blog-code/tree/main/python/python-video-generation/code"&gt;base code&lt;/a&gt; of the final version of the project&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;In summary, using Python for bulk video generation is a valuable asset for engineers working alongside marketing and content creation teams. This tutorial is meant to be a helpful resource to kickstart your journey.&lt;/p&gt;

&lt;p&gt;In the upcoming weeks, we will cover the implementation of golden testing for this type of video production, providing further insights into its features and benefits. Ensure you subscribe to our blog to stay updated!&lt;/p&gt;

</description>
      <category>python</category>
      <category>programming</category>
      <category>tutorial</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
