Python email list splitter for emails

I’ve used ChatGPT to create a python script which will take a list of email addresses and put them in to X number of groups in CSV format.

The input format needs to be a single email address on each line. If you copy and paste a column of email addresses from Excel, it will match this format.

Example input:

alice@example.com
bob.smith@domain.org
carla.jones@sample.net
david_brown42@test.io
emily.zhao@website.com

Example output (in this case, 1 group only):

alice@example.com, bob.smith@domain.org, carla.jones@sample.net, david_brown42@test.io, emily.zhao@website.com


When you press the ‘Transform to CSV groups’ button, the list will be split in to X groups where each group is a single line of email addresses separated by a comma. You can choose the number of groups.

This is the format that email clients expect when sending an email to multiple recipients.

Here is the python3 code:

import tkinter as tk
from tkinter import scrolledtext


def split_emails(emails, num_groups=4):
    """
    Split a list of emails into num_groups roughly equal parts.
    Returns a list of lists.
    """
    n = len(emails)
    if n == 0:
        return [[] for _ in range(num_groups)]
    q, r = divmod(n, num_groups)
    groups = []
    index = 0
    for i in range(num_groups):
        size = q + (1 if i < r else 0)
        groups.append(emails[index:index+size])
        index += size
    return groups


def transform_action():
    # Get raw input and list of emails
    raw = input_text.get("1.0", tk.END)
    emails = [line.strip() for line in raw.splitlines() if line.strip()]

    # Get number of groups from input
    try:
        num_groups = int(group_entry.get())
        if num_groups < 1:
            num_groups = 1
    except ValueError:
        num_groups = 4

    # Update total count label
    count_label.config(text=f"Total emails: {len(emails)}")

    # Split into groups
    groups = split_emails(emails, num_groups=num_groups)

    # Prepare output
    output_text.configure(state=tk.NORMAL)
    output_text.delete("1.0", tk.END)
    for i, group in enumerate(groups, start=1):
        # Group label with count
        output_text.insert(tk.END, f"Group {i} ({len(group)} emails):\n\n")
        # CSV line
        csv_line = ', '.join(group)
        output_text.insert(tk.END, f"{csv_line}\n")
        # Spacing between groups
        output_text.insert(tk.END, "\n\n\n")
    output_text.configure(state=tk.DISABLED)


def clear_action():
    # Clear input and output areas and reset count
    input_text.delete("1.0", tk.END)
    output_text.configure(state=tk.NORMAL)
    output_text.delete("1.0", tk.END)
    output_text.configure(state=tk.DISABLED)
    count_label.config(text="Total emails: 0")
    group_entry.delete(0, tk.END)
    group_entry.insert(0, "4")

# Setup GUI
root = tk.Tk()
root.title("Email List Splitter")
root.geometry("800x550")  # increased height for controls

# Input label and text area
tk.Label(root, text="Enter one email per line:").pack(anchor=tk.W, padx=10, pady=(10, 0))
input_text = scrolledtext.ScrolledText(root, wrap=tk.WORD, height=10)
input_text.pack(fill=tk.BOTH, expand=False, padx=10, pady=5)

# Toolbar with buttons and count label
toolbar = tk.Frame(root)
toolbar.pack(fill=tk.X, padx=10, pady=5)

transform_btn = tk.Button(toolbar, text="Transform to CSV Groups", command=transform_action)
transform_btn.pack(side=tk.LEFT)

count_label = tk.Label(toolbar, text="Total emails: 0")
count_label.pack(side=tk.LEFT, padx=(10, 10))

# Group label and input field aligned left-to-right on right side
group_frame = tk.Frame(toolbar)
group_frame.pack(side=tk.RIGHT, padx=(0, 10))

group_label = tk.Label(group_frame, text="Number of groups")
group_label.pack(side=tk.LEFT, padx=(0, 5))

group_entry = tk.Entry(group_frame, width=5)
group_entry.insert(0, "4")
group_entry.pack(side=tk.LEFT)

clear_btn = tk.Button(toolbar, text="Clear email list", command=clear_action)
clear_btn.pack(side=tk.RIGHT, padx=(10, 10))

# Output label and text area
tk.Label(root, text="CSV Output for each group:").pack(anchor=tk.W, padx=10, pady=(10, 0))
output_text = scrolledtext.ScrolledText(root, wrap=tk.WORD, height=10, state=tk.DISABLED)
output_text.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

# Start the GUI
root.mainloop()

Alternatively, you can download a Windows executable here:

Google Chrome extension to ensure the ‘Following’ tab in x.com (Twitter) remains selected

Twitter likes to play dirty tricks and deselect the ‘Following’ tab if you click on it. It seems to always rever to ‘For you’.

I’ve written a Google Chrome extension that ensures that the ‘Following tab’ is re-selected if it is not currently selected.

If you are using other tabs, this extension will be annoying to you since it will force ‘Following’ to be re-selected. Don’t use it.

You can download the extension here:

Instructions for use:

1. Download file
2. Unzip file to folder
3. Go to Exensions > Manage Extensions (or enter chrome://extensions/ in your address bar)
4. Make sure 'Developer Mode' is activated in the top-right corner
5. Click 'Load Unpacked' in the to-left corner and select the unpacked folder

The extension will now be automatically used whenever you visit x.com.

If you’re worried about the contents of the extension, open up content.js file. It’s the text file which contains the Javascript code. Very simple code with comments.

Using ChatGPT more effectively and getting better answers

I’ve been watching a few videos on how best to use ChatGPT. Various videos on YouTube can provide some great hints, tips, and tricks to get the most out of it.

I can recommend Leila Gharani’s YouTube channel.

I learned the following excellent piece of advice from one of her videos. You can add a specific set of instructions from the ‘Customize ChatGPT’ menu item by adding text to the ‘How would you like ChatGPT to respond?’ area.

I’m referring to the area below (in dark mode):

Add the following text:

Always add the confidence level of your answer. When your answer includes facts, always provide a valid URL with the source for your answer. Don't create a link for the URL, just write out the whole URL, including the http or https tag. If you speculate or predict something, inform me. If you think I may have misspelled code or a linux console command, please confirm my intention rather than assuming the correct syntax.

The last sentence I added from my own experience. This will tell ChatGPT to do several things:

  • Cite a confidence level for its answer – so you can decide whether to do more research or take the answer at its face value
  • Provide a URL so that you can look at the source of the link. ChatGPT always removed the links for me (probably for safety), so I asked it to spell out the URLs verbatim.
  • Indicate whether something given is speculation or a prediction or ‘fact’ – further allowing you to scrutinize answers.
  • Ensure that ChatGPT doesn’t make assumptions about what your intentions are when asking questions. I have had ChatGPT send me down a rabbit-hole because it assumed my spelling mistake was correct.

Potential incompatibility between running MailEnable on Windows Server 2022 and Malwarebytes Premium

Just a heads-up for anyone running MailEnable Enterprise Premium on Windows Server 2022 and Malwarebytes Premium…

We recently installed Malwarebytes to enhance security on your MailEnable mail server. I have always been happy with Malwarebytes and highly recommend it as security software on desktop PCs. However, after recently installing Malwarebytes Enterprise Premium, we’ve experienced a number of issues.

Firstly, the MailEnable IMAP service would go down, and some connections to other services would be blocked entirely. After IMAP went down, the host would become sluggish or we’d be unable to connect via RDP.

Finally, the host would crash entirely and all services would go down.

We are not certain yet of the exact cause, but we know that this problem started happening after we installed Malwarebytes and ended immediately after we uninstalled and did a Windows reboot.

The details are here:

Edition:	Windows Server 2022 Standard 64-bit
Version: 	21H2
OS build: 	20348.2340

MailEnable Enterprise Premium 
Version 10.48

Malwarebytes Premium 
File version 5.1.1.82

If you are experiencing problems running the two MailEnable and Malwarebytes together on Windows Server 2022, it could be because there’s a conflict and it’s worth uninstalling Malwarebytes to troubleshoot.

Doris Lessing on education

Ideally, what should be said to every child, repeatedly, throughout his or her school life is something like this:
“You are in the process of being indoctrinated. We have not yet evolved a system of education that is not a system of indoctrination.
 We are sorry, but it is the best we can do. What you are being taught here is an amalgam of current prejudice and the choices of this particular culture. The slightest look at history will show how impermanent these must be. You are being taught by people who have been able to accommodate themselves to a regime of thought laid down by their predecessors. It is a self-perpetuating system. Those of you who are more robust and individual than others will be encouraged to leave and find ways of educating yourself — educating your own judgements. Those that stay must remember, always, and all the time, that they are being moulded and patterned to fit into the narrow and particular needs of this particular society.”

The Golden Notebook (1962)