FLOSS Project Planets
Python GUIs: Building a Translation Application Using Tkinter — Translate Your Text With Python and Tkinter
Whether learning a new natural language or just browsing foreign websites, you sometimes come across text that you want to read but is written in a language you don't fully understand. To translate one natural language into your native language you can use a translator tool, like Google Translate.
In this tutorial, we'll build a desktop translator application to translate natural language using the Google Translate APIs. The UI will be built using the Tkinter GUI library from the Python standard library.
Table of Contents- Demo: A Translator App with Tkinter
- Installing the Required Packages
- Building the Window
- Creating the GUI
- Implementing the Translation Functionality
- Using the Translator App
- Conclusion
We'll work through the process of building the app step by step. Once we finish the tutorial, the app will look and work like the following:
You can select the source and destination languages. Then, you can paste or type some text in the left-hand area and hit the Translate button to get the translated text in the right-hand area.
Installing the Required PackagesOur Translator uses the googletrans library to perform the actual translation via Google. Tkinter is already available in the standard library, so we just need to install googletrans-py and a library called httpcore to deal with connection errors.
The first task will be to set up a Python virtual environment. Open the terminal, and run the following commands:
- Windows
- macOS/Linux
Working through these instructions, first we create a root directory for the Translator app. Next we create and activate a Python virtual environment for the project. Finally, we install googletrans and httpcore packages.
Now, create a file named translator.py in the root of your project. Additionally, create a folder called images/ where you'll store the icons for the application. The folder structure should look like this:
python translator/ &boxv &boxvr&boxh&boxh images/ &boxv &boxvr&boxh&boxh arrow.png &boxv &boxur&boxh&boxh logo.png &boxv &boxur&boxh&boxh translator.pyThe images for this project can be downloaded here.
The images/ folder contains the two icons that you'll use for the application. The translator.py is the app's source file.
Building the WindowOpen the translator.py file with your favorite Python code editor. We'll start by creating our main window:
python import tkinter as tk class TranslatorApp(tk.Tk): def __init__(self): super().__init__() self.title("Language Translator") self.resizable(width=False, height=False) if __name__ == "__main__": app = TranslatorApp() app.mainloop()This code imports Tkinter and then defines the application's main class, which we have called TranslatorApp. This class will hold the application's main window and allow us to run the main loop.
Importing tkinter under the alias tk is a common convention in Tkinter code.
Inside the class we define the __init__() method, which handles initialization of the class. In this method we first call the initializer __init__() of the parent class, tk.Tk, to initialize the app's window. Then, we set the window's title using the title() method. To make the window unresizable, we use the resizable() method with width and height set to False.
At the bottom of the code, we have the if __name__ == "__main__" idiom to check whether the file is being run directly as an executable program. Inside the condition block we first create an instance of TranslatorApp and then run the application's main loop or event loop.
If you run this code, you'll get an empty Tkinter window on your desktop:
python python translator.pyThe empty Tkinter window
Creating the GUINow that the main window is set up, let's start adding widgets to build the GUI. To do this, we'll create a method called setup_ui(), as shown below:
python import tkinter as tk class TranslatorApp(tk.Tk): def __init__(self): super().__init__() self.title("Language Translator") self.resizable(width=False, height=False) self.setup_ui() def setup_ui(self): frame = tk.Frame(self) frame.pack(padx=10, pady=10) if __name__ == "__main__": app = TranslatorApp() app.mainloop()The setup_ui() method will define the application's GUI. In this method, we first create a frame widget using the tk.Frame class whose master argument is set to self (the application's main window). Next, we position the frame inside the main window using the pack() geometry manager, using padx and pady arguments to set some padding around the frame.
Finally, we add the call to self.setup_ui() to the __init__() method.
We'll continue to develop the UI by adding code to the setup_ui() method.
Net we'll add the app's logo. In the setup_ui() method add the following code below the frame definition:
python import tkinter as tk class TranslatorApp(tk.Tk): def __init__(self): super().__init__() self.title("Language Translator") self.resizable(width=False, height=False) self.setup_ui() def setup_ui(self): frame = tk.Frame(self) frame.pack(padx=10, pady=10) self.logo = tk.PhotoImage(file="images/logo.png").subsample(5, 5) tk.Label(frame, image=self.logo).grid(row=0, column=0, sticky="w") if __name__ == "__main__": app = TranslatorApp() app.mainloop()This code loads the logo using the tk.PhotoImage class. To resize it, we use the subsample() method. Then, we add the logo to the frame using a tk.Label widget. The label takes the frame and the logo as arguments. Finally, to position the logo, we use the grid() geometry manager with appropriate values for the row, column, and sticky arguments.
The sticky argument determines which side of a cell the widget should align -- North (top), South (bottom), East (right) or West (left). Here we're aligning it on the Wiest or left of the cell with "w":
Tkinter window with the Google Translate logo in it
Let's start adding some inputs to the UIs. First, we'll create the language selection drop-down boxes:
python import tkinter as tk import tkinter.ttk as ttk from googletrans import LANGUAGES DEFAULT_SOURCE = "English" DEFAULT_DEST = "Dutch" class TranslatorApp(tk.Tk): def __init__(self): super().__init__() self.title("Language Translator") self.resizable(width=False, height=False) self.setup_ui() def setup_ui(self): frame = tk.Frame(self) frame.pack(padx=10, pady=10) self.logo = tk.PhotoImage(file="images/logo.png").subsample(5, 5) tk.Label(frame, image=self.logo).grid(row=0, column=0, sticky="w") # Source language combobox languages = [lang.title() for lang in LANGUAGES.values()] self.from_language = ttk.Combobox(frame, values=languages) self.from_language.current(languages.index(DEFAULT_SOURCE)) self.from_language.grid(row=1, column=0, sticky="we") # Arrow icon self.arrows = tk.PhotoImage(file="images/arrow.png").subsample(15, 15) tk.Label(frame, image=self.arrows).grid(row=1, column=1) # Destination language combobox self.to_language = ttk.Combobox(frame, values=languages) self.to_language.current(languages.index(DEFAULT_DEST)) self.to_language.grid(row=1, column=2, sticky="we") if __name__ == "__main__": app = TranslatorApp() app.mainloop()We can get a list of languages from the googletrans module. We also define the default languages for when the application starts up, using constants DEFAULT_SOURCE and DEFAULT_DEST.
To build the language list for the combo boxes we take the LANGUAGES dictionary imported from googletrans and convert it into a list of strings called languages. We use a list comprehension to make all the names start with an uppercase letter, using title().
Next we create two combo boxes, to hold the list of source and destination langauges. The combo boxes are created using the ttk.Combobox class. One to the left and another to the right. Between the combo boxes, we've also added an arrow icon loaded using the tk.PhotoImage class. Again, we've added the icon to the app's window using ttk.Label.
Both combo boxes take frame and values as arguments. The values argument populates the combo boxes with languages. To specify the default language, we use the current() method, looking up the position of our default languages in the languages list with index().
To position the combo boxes inside the frame, we use the grid() geometry manager with the appropriate arguments. Run the application, and you will see the following window:
Source and destination languages
If you click on the sources combo box on the left, then you get the following:
Source language combo box
Similarly, if you click on the destination combo box on the right, you get the following:
Destination combo box
With the source and destination combo boxes in place, let's add three more widgets: two scrollable text widgets and a button. The scrollable text on the left will hold the source text, while the scrollable text on the right will hold the translated text. The button will allow us to run the actual translation.
Get back to the code editor and update the setup_ui() method as follows. Note that we also need to import the ScrollText class:
python import tkinter as tk import tkinter.ttk as ttk from tkinter.scrolledtext import ScrolledText from googletrans import LANGUAGES DEFAULT_SOURCE = "English" DEFAULT_DEST = "Dutch" class TranslatorApp(tk.Tk): def __init__(self): super().__init__() self.title("Language Translator") self.resizable(width=False, height=False) self.setup_ui() def setup_ui(self): frame = tk.Frame(self) frame.pack(padx=10, pady=10) self.logo = tk.PhotoImage(file="images/logo.png").subsample(5, 5) tk.Label(frame, image=self.logo).grid(row=0, column=0, sticky="w") # Source language combobox languages = [lang.title() for lang in LANGUAGES.values()] self.from_language = ttk.Combobox(frame, values=languages) self.from_language.current(languages.index(DEFAULT_SOURCE)) self.from_language.grid(row=1, column=0, sticky="we") # Arrow icon self.arrows = tk.PhotoImage(file="images/arrow.png").subsample(15, 15) tk.Label(frame, image=self.arrows).grid(row=1, column=1) # Destination language combobox self.to_language = ttk.Combobox(frame, values=languages) self.to_language.current(languages.index(DEFAULT_DEST)) self.to_language.grid(row=1, column=2, sticky="we") # Source text self.from_text = ScrolledText( frame, font=("Dotum", 16), width=50, height=20, ) self.from_text.grid(row=2, column=0) # Translated text self.to_text = ScrolledText( frame, font=("Dotum", 16), width=50, height=20, state="disabled", ) self.to_text.grid(row=2, column=2) # Translate button self.translate_button = ttk.Button( frame, text="Translate", command=self.translate, ) self.translate_button.grid(row=3, column=0, columnspan=3, pady=10) def translate(self): pass if __name__ == "__main__": app = TranslatorApp() app.mainloop()In the code snippet, we use the ScrolledText class to create the two scrolled text areas. Both text areas take frame, font, width, and height as arguments. The second text area also takes state as an additional argument. Setting state to "disabled" allows us to create a read-only text area.
Then, we use the ttk.Button class to create a button with frame, text, and command as arguments. The command argument allows us to bind the button's click event to the self.translate() method, which we will define in a moment. For now, we've added a placeholder.
To position all these widgets on the app's window, we use the grid() geometry manager. Now, the app will look like the following:
Translator app's GUI
Our translation app's GUI is ready! Finally, we can start adding functionality to the application.
Implementing the Translation FunctionalityWe'll implement the language translation functionality in the translate() method. This gets the current values from the UI and then uses googletrans to perform the translation. We need a few more imports, and to create the translator instance at the top of the application:
python import tkinter as tk import tkinter.ttk as ttk from tkinter.messagebox import showerror from tkinter.scrolledtext import ScrolledText import httpcore from googletrans import LANGUAGES, Translator DEFAULT_SOURCE = "English" DEFAULT_DEST = "Dutch" translator = Translator()Here we've imported the showerror helper for displaying error boxes in our application. We've imported httpcore which we'll use to handle HTTP errors when accessing the API. Finally, we've added an import for the Translator class from googletrans. This is what handles the actual translation.
To use it, we create an instance of the class as translator.
We'll continue by implementing the translate method. Below we're just showing the function itself:
python class TranslatorApp(tk.Tk): # ... def translate(self): source_language = self.from_language.get() destination_language = self.to_language.get() text = self.from_text.get(1.0, tk.END).strip() if not source_language or not destination_language: showerror( title="Error", message="Make sure to set the source and destination language", ) return if not text: showerror( title="Error", message="Make sure to enter some text to translate", ) return try: translation = self.translator.translate( text, src=source_language, dest=destination_language, ) except httpcore.ConnectError: showerror( title="Error", message="Make sure you have an internet connection", ) return except Exception as e: showerror( title="Error", message=f"An unexpected error occurred: {e}", ) return self.to_text.config(state="normal") self.to_text.delete(1.0, tk.END) self.to_text.insert(tk.END, translation.text) self.to_text.config(state="disabled")The translate() method handles the entire translation process. It starts by retrieving the source and destination languages from the corresponding combo boxes. If either language is not defined, then we display a message to inform the user about the problem. To do this, we use a showerror dialog.
Next, we try to get the input text from the source scrolled area on the left. If the user doesn't provide any text, then we display an error with the appropriate message.
Once we have the source and destination language and some text to translate, we can perform the actual translation. To run this task, we use the translate() method of the self.translator object, which is an instance of googletrans.Translator.
If the call to translate() finds a connection error, then we tell the user to check their internet connection. To handle any other exceptions, we catch the generic Exception class and display an error message with the exception details.
If the translation is successful, then we enable the destination scrolled area, display the translated text, and disable the area again so it remains read-only.
The complete final code is shown below:
python import tkinter as tk import tkinter.ttk as ttk from tkinter.messagebox import showerror from tkinter.scrolledtext import ScrolledText import httpcore from googletrans import LANGUAGES, Translator DEFAULT_SOURCE = "English" DEFAULT_DEST = "Dutch" translator = Translator() class TranslatorApp(tk.Tk): def __init__(self): super().__init__() self.title("Language Translator") self.resizable(width=False, height=False) self.setup_ui() def setup_ui(self): languages = [lang.title() for lang in LANGUAGES.values()] frame = tk.Frame(self) frame.pack(padx=10, pady=10) self.logo = tk.PhotoImage(file="images/logo.png").subsample(5, 5) tk.Label(frame, image=self.logo).grid(row=0, column=0, sticky="w") # Source language combobox self.from_language = ttk.Combobox(frame, values=languages) self.from_language.current(languages.index(DEFAULT_SOURCE)) self.from_language.grid(row=1, column=0, sticky="we") # Arrow icon self.arrows = tk.PhotoImage(file="images/arrow.png").subsample(15, 15) tk.Label(frame, image=self.arrows).grid(row=1, column=1) # Destination language combobox self.to_language = ttk.Combobox(frame, values=languages) self.to_language.current(languages.index(DEFAULT_DEST)) self.to_language.grid(row=1, column=2, sticky="we") # Source text self.from_text = ScrolledText( frame, font=("Dotum", 16), width=50, height=20, ) self.from_text.grid(row=2, column=0) # Translated text self.to_text = ScrolledText( frame, font=("Dotum", 16), width=50, height=20, state="disabled", ) self.to_text.grid(row=2, column=2) # Translate button self.translate_button = ttk.Button( frame, text="Translate", command=self.translate, ) self.translate_button.grid(row=3, column=0, columnspan=3, pady=10) def translate(self): source_language = self.from_language.get() destination_language = self.to_language.get() if not source_language or not destination_language: showerror( title="Error", message="Make sure to set the source and destination language", ) return text = self.from_text.get(1.0, tk.END).strip() if not text: showerror( title="Error", message="Make sure to enter some text to translate", ) return try: translation = translator.translate( text, src=source_language, dest=destination_language, ) except httpcore.ConnectError: showerror( title="Error", message="Make sure you have an internet connection", ) return except Exception as e: showerror( title="Error", message=f"An unexpected error occurred: {e}", ) return self.to_text.config(state="normal") self.to_text.delete(1.0, tk.END) self.to_text.insert(tk.END, translation.text) self.to_text.config(state="disabled") if __name__ == "__main__": app = TranslatorApp() app.mainloop() Using the Translator AppThe video below demonstrates how we can use our app to translate some text from one natural language to another:
Great! You have successfully built a language translator using Python, Tkinter, and the googletrans package.
ConclusionIn this tutorial we built a Translator application using the Tkinter GUI library from the Python standard library. We worked step by step through building the UI using a grid layout, and then implemented the language translation functionality with googletrans.
Try and take what you've learnt in this tutorial & applying it to your own projects!
Spyder IDE: The inside scoop on Spyder 6's new remote development platform
Freexian Collaborators: Tryton 7.0 LTS reaches Debian trixie (by Mathias Behrle, Raphaël Hertzog and Anupa Ann Joseph)
Tryton is a FOSS software suite which is highly modular and scalable. Tryton along with its standard modules can provide a complete ERP solution or it can be used for specific functions of a business like accounting, invoicing etc.
Debian packages for Tryton are being maintained by Mathias Behrle. You can follow him on Mastodon or get his help on Tryton related projects through MBSolutions (his own consulting company).
Freexian has been sponsoring Mathias’s packaging work on Tryton for a while, so that Debian gets all the quarterly bug fix releases as well as the security release in a timely manner.
About Tryton 7.0 LTSLately Mathias has been busy packaging Tryton 7.0 LTS. As the “LTS” tag implies, this release is recommended for production deployments since it will be supported until November 2028. This release brings numerous bug fixes, performance improvements and various new features.
As part of this work, 41 new Tryton modules and 3 dependency packages have been added to Debian, significantly broadening the options available to Debian users and improving integration with Tryton systems.
Running different versions of Tryton on different Debian releasesTo provide extended compatibility, a dedicated Tryton mirror is being managed and is available at https://debian.m9s.biz/debian/. This mirror hosts backports for all supported Tryton series, ensuring availability for a variety of Debian releases and deployment scenarios.
These initiatives highlight MBSolutions’ technical contributions to the Tryton community, made possible by Freexian’s financial backing. Together, we are advancing the Tryton ecosystem for Debian users.
GNU Taler news: libeufin independent security audit report and developer response published
Release GCompris 4.3
Today we are releasing GCompris version 4.3.
It contains bug fixes and graphics improvements on multiple activities.
It is fully translated in the following languages:
- Arabic
- Bulgarian
- Breton
- Catalan
- Catalan (Valencian)
- Greek
- UK English
- Esperanto
- Spanish
- Basque
- French
- Galician
- Croatian
- Hungarian
- Indonesian
- Italian
- Lithuanian
- Latvian
- Malayalam
- Dutch
- Norwegian Nynorsk
- Polish
- Brazilian Portuguese
- Romanian
- Russian
- Slovenian
- Albanian
- Swedish
- Swahili
- Turkish
- Ukrainian
It is also partially translated in the following languages:
- Azerbaijani (97%)
- Belarusian (87%)
- Czech (97%)
- German (96%)
- Estonian (96%)
- Finnish (95%)
- Hebrew (96%)
- Macedonian (90%)
- Portuguese (96%)
- Slovak (84%)
- Chinese Traditional (96%)
You can find packages of this new version for GNU/Linux, Windows, Android, Raspberry Pi and macOS on the download page. Also this update will soon be available in the Android Play store, the F-Droid repository and the Windows store.
Thank you all,
Timothée & Johnny
Parabola GNU/Linux-libre: i686 users - manual intervention required
i686 users will probably be unable to upgrade, due to a problem with the latest archlinux32-keyring 20241114-1
the solution is posted on the bug tracker https://labs.parabola.nu/issues/3679
mark.ie: My LocalGov Drupal contributions for week-ending November 29nd, 2024
This week I fixed lots and lots of accessibility issues.
Bits from Debian: New Debian Developers and Maintainers (September and October 2024)
The following contributors got their Debian Developer accounts in the last two months:
- Joachim Bauch (fancycode)
- Alexander Kjäll (capitol)
- Jan Mojžíš (janmojzis)
- Xiao Sheng Wen (atzlinux)
The following contributors were added as Debian Maintainers in the last two months:
- Alberto Bertogli
- Alexis Murzeau
- David Heilderberg
- Xiyue Deng
- Kathara Sasikumar
- Philippe Swartvagher
Congratulations!
The Drop Times: TDT Is Now the Official Media Partner for DrupalCon Vienna
remotecontrol @ Savannah: Smart gadgets’ failure to commit to software support could be illegal, FTC warns
PyCharm: Simplify ML Workflows With Hugging Face and PyCharm
Ready to boost your workflows with pre-trained ML models?
PyCharm‘s integration with Hugging Face is designed to bring a new level of productivity to your machine learning and development workflows.
This integration helps you seamlessly find and use the best-fit model from the Hugging Face library, access model documentation, and manage models – all in your IDE.
The integration is available starting with PyCharm 2024.2.
Read the blog post to learn more about the integration and how to use it.
What is Hugging Face?Hugging Face is a platform where machine learning and data science developers share pre-trained AI models. The platform provides tools to build, deploy, and train machine learning models.
Key features of the Hugging Face integrationPyCharm’s integration with Hugging Face is designed to streamline workflows for developers, enabling seamless access to pre-trained machine learning models from the IDE. This integration allows you to:
- Simplify model selection and usage.
- Import models as easily as importing any other library, allowing you to stay focused on your code.
- Eliminate distractions caused by switching between tools and browsers.
- Maintain control over your machine storage.
Lysandre Debut, the Chief Open-Source Officer at Hugging Face, shares:
“As a Hugging Face user, even more so than as a Hugging Face team member, the HF integration in PyCharm has been instrumental in speeding up the machine learning workflows I’ve worked on. As a result of this feature, I find myself keeping my focus in the IDE, with much less context switching during development.” Easily find the best model for your task
Looking to use a Hugging Face model but unsure which one fits your needs? Whether you’re building a text classifier, working on image recognition, or exploring other areas, PyCharm simplifies the process for you.
With the Hugging Face integration, you can quickly access a vast library of models tailored to various tasks. Right-click in the editor, select Insert HF Model, and explore models categorized by task type. To make your search even easier, you can filter models by likes, licensing, or specific tags.
For each model, PyCharm provides a detailed model card, including essential information and sample code that you can use. Found the perfect fit? Just click Use Model to insert the necessary code snippet directly into your project and start building immediately.
Seamlessly access model documentationWhen working with machine learning models, quick access to documentation is handy – and PyCharm ensures you stay focused. With the Hugging Face integration, you can instantly view detailed model information without leaving your IDE or interrupting your workflow.
Simply hover over a model name in your code, and PyCharm will display its full model card, including the tasks the model is designed for, date of its last update, its origin, licensing details, and other details.
No more jumping between your browser and IDE – everything you need is right next to your code.
Manage models stored on your machineHugging Face models can take up significant storage space, but PyCharm makes it easy to stay in control. With this integration, you can view the models you’ve downloaded, identify those you no longer need, and declutter with ease.
Just head to the Hugging Face tool window to see and manage your models.
PyCharm helps you to keep your system optimized while ensuring you retain access to the tools you actually need – all from the comfort of your IDE!
Get started with PyCharm integrated with Hugging FacePyCharm is a powerful IDE designed for machine learning, data science, and web development. It has everything you need for productive coding, including intelligent coding assistance (both local and AI-powered), smart navigation, and project-wide refactorings.
It also provides a full suite of integrations tailored to streamline machine learning and data science workflows, including support for Jupyter Notebooks, Databricks, and popular scientific libraries like pandas, Polars, NumPy, scikit-learn, and more.
Use the PyCharm4HF code on the redeem page below to get started with PyCharm for free.
Get a 3-month PyCharm subscription for freeNeed more guidance? Head to the documentation for step-by-step instructions on using Hugging Face with PyCharm.
We’d love to hear your thoughts! Share your experience with the integration in the comments below.
joshics.in: Unleashing Flexibility: How Headless Drupal is Shaping the Future of Content Delivery
Headless Drupal is changing the course for content management systems by offering a fresh approach to how digital content is delivered across platforms.
At its core, headless Drupal separates the backend (where content is stored and managed) from the frontend (where content is displayed). This decoupling allows for a greater range of flexibility and customization in how content is presented to users, leading to faster, more dynamic websites that can easily integrate with a multitude of modern tech stacks.
Why choose headless?The benefits are abundant. By going headless, organizations can seamlessly deploy content across diverse platforms—from mobile apps and kiosks to IoT devices. This means a blog post, product description, or interactive experience can be shared consistently, regardless of where or how it is consumed.
However, embracing headless architecture is not without its challenges. Managing separate systems can introduce complexity. Multiple moving parts can sometimes lead to increased difficulty in synchronizing the backend with various frontends. Fortunately, Drupal's API-first architecture mitigates these challenges by providing a strong foundation for developers to build upon, ensuring a cohesive integration between systems.
The real excitement comes with the capability to pair Drupal's robust backend with cutting-edge front-end technologies like React, Vue.js, or Angular. This combination results in richer, more engaging user experiences that cater to modern audiences' expectations for speed and interactivity. Developers have the freedom to innovate and tailor the user interface to meet the unique needs of their audience, unencumbered by traditional constraints.
Moreover, businesses are positioned to benefit tremendously from headless Drupal. They gain the ability to bring new features to market rapidly, allowing them to stay ahead in today’s fast-paced digital landscape. Scalability becomes less of a concern, as the architecture easily accommodates growth and a wide variety of digital touchpoints.
Headless Drupal doesn't just promise flexibility; it delivers adaptability essential for future-proofing digital strategies. In an era where customer engagement is king, and technology continues to evolve at unprecedented speeds, having a versatile and powerful content management system is indispensable.
The question isn't just whether headless Drupal is the future—it's about understanding how this evolution in content management can redefine your digital strategy to better connect with users across every platform.
Headless Drupal Drupal Planet Add new commentProgramiz: Python List
Bruno Ponne / Coding The Past: How to calculate Z-Scores in Python
If you’ve worked with statistical data, you’ve likely encountered z-scores. A z-score measures how far a data point is from the mean, expressed in terms of standard deviations. It helps identify outliers and compare data distributions, making it a vital tool in data science.
In this guide, we’ll show you how to calculate z-scores in Python using a custom function and built-in libraries like SciPy. You’ll also learn to visualize z-scores for better insights.
A z-score measures how many standard deviations a data point is from the mean. The formula for calculating the z-score of a data point X is:
\[Z_{X} = \frac{X - \overline{X}}{S}\]Where:
- \(Z_{X}\) is the z score of the point \(X\);
- \(X\) is the value for which we want to calculate the Z score;
- \(\overline{X}\) is the mean of the sample;
- \(S\) is the standard deviation of the sample.
A custom function allows you to implement the z-score formula directly. Here’s how to define and use it in Python:
content_copy Copy
def calculate_z(X, X_mean, X_sd): return (X - X_mean) / X_sdThe function takes three arguments:
- a vector X of values for which you want to calculate the z-scores, like a pandas dataframe column, for example;
- the mean of the values in X;
- the standard deviation of the values in X.
Finally, in the return clause, we apply the z-score formula explained above.
To test our function, we will use data from Playfair (1821). He collected data regarding the price of wheat and the typical weekly wage for a “good mechanic” in England from 1565 to 1821. His objective was to show how well-off working men were in the 19th century. This dataset is available in the HistData R package and also on the webpage of Professor Vincent Arel-Bundock, a great source of datasets. It consists of 3 variables: year, price of wheat (in Shillings) and weekly wages (in Shillings).
We will be calculating the z-scores for the weekly wages. First we load the dataset directly from the website, as indicated in the code below.
content_copy Copy
import pandas as pd data = pd.read_csv("https://vincentarelbundock.github.io/Rdatasets/csv/HistData/Wheat.csv") print(data['Wages'].mean()) print(data['Wages'].std()) data["z-score_wages"] = calculate_z(data["Wages"], data["Wages"].mean(), data["Wages"].std())The average weekly wage during the period was 11.58 Shillings, with a standard deviation of 7.34. With this information, we can calculate the Z score for each observation in the dataset. This is done and stored in a new column called “z-score_wages”.
If you check the first row of the data frame, you will find out that in 1565 the z score was around -0.9, that is, the wages were 0.9 standard deviations below the mean of the values for the whole period.
A second option to calculate z-scores in Python is to use the zscore method of the SciPy library as shown below. Ensure you set a policy for handling missing values if your dataset is incomplete.
In the code below, we calculate the z-scores for Wheat prices. If you look at the z-score summary statistics, you will see that the price of wheat varied between -1.13 and 3.65 standard deviations away from the mean in the observed period.
content_copy Copy
from scipy import stats data["z-score_wheat"] = stats.zscore(data["Wheat"], nan_policy="omit") data["z-score_wheat"].describe()Below you can better visualize the basic idea of z scores: to measure how far away a data point is from the mean in terms of standard deviations. This visualization was created in D3, a JavaScript library for interactive data visualization. Click “See average wage” to see the averave wage for the whole period. Then check out how far from the mean each data point is and finally note that the z-score consists of this distance in terms of standard deviation.
1. See Average Wage 2. See Distance to the Mean 3. See Z-Scores ResetThe code below plots the wage z scores over time and shows them as the distance from the point to the mean, as demonstrated in the D3 visualization above. Please consult the lesson ‘Storytelling with Matplotlib - Visualizing historical data’ to learn more about Matplotlib visualizations.
content_copy Copy
# Calculate mean wage mean_wage = data["z-score_wages"].mean() # Create the plot fig, ax = plt.subplots(figsize=(10, 6)) # Scatter plot of wages over years ax.plot(data["Year"], data["z-score_wages"], 'o', color='#FF6885', label="Wage Z-scores", markeredgewidth=0.5) # Add a horizontal line for the mean wage ax.axhline(y=mean_wage, color='gray', linestyle='dashed', label=f"Mean Z-score = {mean_wage:.2f}") # Add gray lines connecting points to the mean for year, wage in zip(data["Year"], data["z-score_wages"]): ax.plot([year, year], [mean_wage, wage], color='gray', linestyle='dotted', linewidth=1) # Customize the plot ax.set_xlabel("Year") ax.set_ylabel("Z-scores") ax.set_title("Z-scores Over Time") ax.legend() # Show the plot plt.show()Have questions or insights? Leave a comment below, and I’ll be happy to help.
Happy coding!
- A z score is a measure of how many standard deviations a data point is away from the mean. It can be easily calculated in Python;
- You can visualize z-scores using traditional python libraries like Matplotlib or Seaborn.
Droptica: How to Migrate Drupal 7 to Drupal 11 with Modules? Guide
The end of Drupal 7 support is approaching (January 5, 2025), which means this system’s users need to migrate to a newer version. This article explains how to move smoothly from Drupal 7 to Drupal 11, the key steps, and what to pay attention to. I encourage you to read the article or watch the video in the “Nowoczesny Drupal” series.
ImageX: Latest & Greatest Tips to Enhance Your Higher Ed Website’s Online Presence
Is your website the driving engine of your higher ed institution and a powerful catalyst for its goals? Is it effectively attracting prospective students, inspiring alumni, and building a vibrant community? There are always new strategies to boost your website's impact and ensure the answer is a resounding "yes"! As a team that specializes in higher education website design & development, we are passionate about sharing useful tips that can help those in this sector.
FSF Events: Free Software Directory meeting on IRC: Friday, November 29, starting at 12:00 EST (17:00 UTC)
MidCamp - Midwest Drupal Camp: Craft Your Perfect Proposal: MidCamp 2025 Session Proposal Workshop
🚀 Ready to take your session ideas to the next level? Whether you're a seasoned speaker or a first-time presenter, the MidCamp 2025 Session Proposal Workshop is here to help you craft standout submissions.
📅 Date: December 12, 2024
🕒 Time: 3:00 PM - 4:00 PM CST
🌐 Location: Virtual via MidCamp Slack (#speakers channel)
This workshop will be led by Aaron Feledy, a seasoned Drupal contributor and experienced speaker. Aaron brings years of expertise in proposal crafting and conference speaking, offering practical advice to help you refine and elevate your session submissions.
Why Attend?Submitting a session proposal can be daunting—but it doesn't have to be! This workshop is designed to guide you through the process, from brainstorming topics to refining your submission. Our expert facilitators will share insider tips on what makes a proposal stand out to reviewers and resonate with attendees.
What You’ll Learn:- How to choose and frame a compelling topic
- Crafting clear, concise, and engaging abstracts
- Tips for tailoring your proposal to different audiences
- Insight into the MidCamp review process
Ready to submit? Session submissions for MidCamp 2025 are now open! Visit the MidCamp 2025 session submission page for guidelines and start your journey to the stage.
How to Join:Simply join the MidCamp Slack and head over to the #speakers channel on December 12th at 3:00 PM CST. No registration required—just jump in and start collaborating!