Python Forum
using last 2 characters of a file name to identify it
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
using last 2 characters of a file name to identify it
#1
For an application I'm creating, a combobox displays all customer names that are inside the active customer orders directory. In the customer order, there is mechanical, electrical etc and sales, which has the order acknowledgement. All customer sales order acknowledgment files have OA at the end of the file, but the start of the name may differ from the customer directory name. For example:

Customer directory name: 937298 Sea World

OA file: 937298 SeaWorld OA.pdf

As you can see, there is no space, which is different (sometimes the naming can be very different, this is just a minor example). Implementing a naming convention would be an option, but would require people to actually listen, and it would be better in the long run to be able to just find and print the order acknowledgement by using the OA at the end of the file. Is there a way I can do this? I was originally using the .get() function which would just use the customer name from the directory, but this is inconsistent due to inconsistent naming. How can I find the file I want by just using OA.pdf at the end of the file? Thank you. Here is my code:

import os
import tkinter as tk
from tkinter import ttk


class JobFileAutomation:

    def __init__(self):

        customer_path = os.listdir('Y:/orders/C-Active Orders/')

        self.root = tk.Tk()
        self.root.geometry('400x100')
        self.root.title('Job File Creator')
        self.root.iconbitmap('E:/jobFile.ico')

        self.mainframe = tk.Frame(self.root, background='white')
        self.mainframe.pack(fill='both', expand=True)

        self.customer_label = ttk.Label(self.mainframe, text='Select customer: ', background='white')
        self.customer_label.grid(row=0, column=0, padx=70)

        self.customer_selection = ttk.Combobox(self.mainframe, values=customer_path, width=40)
        self.customer_selection.grid(row=1, column=0, padx=10, pady=10)


        create_button = ttk.Button(self.mainframe, text='Create', command=self.create_job_file)
        create_button.grid(row=1, column=3)

        self.root.mainloop()
        return

    def create_job_file(self):

        customer_name = self.customer_selection.get()
        # name of file path
        oa_file = f"Y:/orders/C-Active Orders/{customer_name}/1-Sales/{customer_name} OA.pdf"
        os.startfile(oa_file, "print")
        print(customer_name)


if __name__ == '__main__':
    JobFileAutomation()
Edit: never mind, I got it. Being a C++/Arduino programmer has hard wired my brain into thinking these problems will be difficult to solve
Reply
#2
Looks like a job for glob.

This program finds all files in the current directory that have a filename that ends with "e"
from pathlib import Path

print(*Path(".").glob("*e.*"))
Output:
console.py employee.csv enhancedsprite.py image.png interactiveconsole.py mtsbinfile.py paddle.png table.json
If you want to only select png files the pattern for glob would be "*.png".
from pathlib import Path

print(*Path(".").glob("*e.png"))
Output:
image.png paddle.png
Maybe some of my files are uppper case and I want to get those too.
from pathlib import Path

print(*Path(".").glob("*[eE].[pP][nN][gG]"))
Output:
image.png paddle.png WALLE.PNG
You should take a look at pathlib. I find it superior to os for doing anything related to directories and files. Info about pathlib and glob.
https://docs.python.org/3/library/pathlib.html.

If there are no OA files it doesn't make sense to create a window for selecting OA files and creating job files. The code below scans for OA files before making the GUI. If OA files are found, it creates controls for selecting files and creating job files. If no OA files are found it displays an informative message.
import tkinter as tk
from tkinter import ttk
from pathlib import Path


class JobFileAutomation(tk.Tk):
    """A GUI for creating job files."""

    def __init__(self, order_dir: str = "Y:/orders/C-Active Orders"):
        super().__init__()
        self.title("Job File")
        icon_file = Path(__file__) / "jobFile.ico"  # Look for icon in same folder as source file.
        if icon_file.exists():
            self.iconbitmap(icon_file)

        frame = tk.Frame(self, background="white")
        frame.pack(fill="both", expand=True)

        # Scan customer folders for OA files.  Add OA files to dictionary.
        self.oa_files = {}
        for customer in Path(order_dir).iterdir():
            if customer.is_dir():
                oa_files = list(customer.glob(f"1-Sales/*{customer.name}*OA.pdf"))
                if len(oa_files) > 0:
                    self.oa_files[customer.name] = oa_files[0]

        if self.oa_files:
            # Create combobox for selecting customer oa file.
            ttk.Label(frame, text="Customer", background=frame["bg"]).grid(row=0, column=0, padx=(10, 2), pady=10)
            customer_names = list(self.oa_files)
            self.customer = tk.StringVar(frame, customer_names[0])
            ttk.Combobox(frame, textvariable=self.customer, values=customer_names).grid(
                row=0, column=1, padx=(0, 10), pady=10
            )
            # Press button to create job file from OA file.
            ttk.Button(frame, text="Create Job File", command=self.create_job_file).grid(
                row=1, column=0, columnspan=2, padx=10, pady=(0, 10), sticky="ew"
            )
        else:
            tk.Label(frame, text="Did not find any customer OA files.", bg=frame["bg"]).grid(
                row=0, column=0, padx=70, pady=50
            )


    def create_job_file(self):
        """For now, just print path to stdout."""
        print(self.oa_files[self.customer.get()].absolute())


if __name__ == "__main__":
    JobFileAutomation().mainloop()
I changed JobFileAutomation to be tk window instead of a tk window factory. Python classes support inheritance, may as well take advantage of it.

Notice the class has only 2 instance variables; the StringVar used to get the customer selection, and the dictionary mapping customer names to OA files. These are the only things used outside the __init__(). Don't create instance variables for things you only use once.
CAD79 likes this post
Reply
#3
Not sure I understand the question correctly:

Quote:How can I find the file I want by just using OA.pdf at the end of the file?

How do we know exactly which file you are looking for?

import re

fn = 'C:\\937298 Sea World\937298 SeaWorld OA.pdf'
g = re.compile(r'[\S\s]*OA\.pdf')
res = g.search(fn)
Gives:

Output:
res.group() 'C:\\937298 Sea World\937298 SeaWorld OA.pdf'
And why must Windoze have a backslash?
Reply
#4
Because CP/M used a forward a slash?

I think it is because DOS utilities used "/" where UNIX would use "-" in the command line. When folders were added to DOS, and it suddenly needed a file delimiter, "/" was already taken, so "\" was used. I don't think escape sequences in strings were ever considered. Who needs "\n" when print automatically does a carriage return/linefeed. Nobody was ever going to run C on a microcomputer.
Pedroski55 likes this post
Reply
#5
(Jul-11-2024, 04:22 PM)deanhystad Wrote: Looks like a job for glob.

This program finds all files in the current directory that have a filename that ends with "e"
from pathlib import Path

print(*Path(".").glob("*e.*"))
Output:
console.py employee.csv enhancedsprite.py image.png interactiveconsole.py mtsbinfile.py paddle.png table.json
If you want to only select png files the pattern for glob would be "*.png".
from pathlib import Path

print(*Path(".").glob("*e.png"))
Output:
image.png paddle.png
Maybe some of my files are uppper case and I want to get those too.
from pathlib import Path

print(*Path(".").glob("*[eE].[pP][nN][gG]"))
Output:
image.png paddle.png WALLE.PNG
You should take a look at pathlib. I find it superior to os for doing anything related to directories and files. Info about pathlib and glob.
https://docs.python.org/3/library/pathlib.html.

If there are no OA files it doesn't make sense to create a window for selecting OA files and creating job files. The code below scans for OA files before making the GUI. If OA files are found, it creates controls for selecting files and creating job files. If no OA files are found it displays an informative message.
import tkinter as tk
from tkinter import ttk
from pathlib import Path


class JobFileAutomation(tk.Tk):
    """A GUI for creating job files."""

    def __init__(self, order_dir: str = "Y:/orders/C-Active Orders"):
        super().__init__()
        self.title("Job File")
        icon_file = Path(__file__) / "jobFile.ico"  # Look for icon in same folder as source file.
        if icon_file.exists():
            self.iconbitmap(icon_file)

        frame = tk.Frame(self, background="white")
        frame.pack(fill="both", expand=True)

        # Scan customer folders for OA files.  Add OA files to dictionary.
        self.oa_files = {}
        for customer in Path(order_dir).iterdir():
            if customer.is_dir():
                oa_files = list(customer.glob(f"1-Sales/*{customer.name}*OA.pdf"))
                if len(oa_files) > 0:
                    self.oa_files[customer.name] = oa_files[0]

        if self.oa_files:
            # Create combobox for selecting customer oa file.
            ttk.Label(frame, text="Customer", background=frame["bg"]).grid(row=0, column=0, padx=(10, 2), pady=10)
            customer_names = list(self.oa_files)
            self.customer = tk.StringVar(frame, customer_names[0])
            ttk.Combobox(frame, textvariable=self.customer, values=customer_names).grid(
                row=0, column=1, padx=(0, 10), pady=10
            )
            # Press button to create job file from OA file.
            ttk.Button(frame, text="Create Job File", command=self.create_job_file).grid(
                row=1, column=0, columnspan=2, padx=10, pady=(0, 10), sticky="ew"
            )
        else:
            tk.Label(frame, text="Did not find any customer OA files.", bg=frame["bg"]).grid(
                row=0, column=0, padx=70, pady=50
            )


    def create_job_file(self):
        """For now, just print path to stdout."""
        print(self.oa_files[self.customer.get()].absolute())


if __name__ == "__main__":
    JobFileAutomation().mainloop()
I changed JobFileAutomation to be tk window instead of a tk window factory. Python classes support inheritance, may as well take advantage of it.

Notice the class has only 2 instance variables; the StringVar used to get the customer selection, and the dictionary mapping customer names to OA files. These are the only things used outside the __init__(). Don't create instance variables for things you only use once.

Thank you, your input was very useful! I'm trying to wrap my head around that code first then I'm going to implement it into the real code. It definitely looks better, and the GUI is a little cleaner, I just need to make the combo box a little wider to fit in all the customer names as some of them are pretty long!

Also, there are always OA files on the record; there are about 35 orders currently active, which all have OA files. If the window didn't open up from not having found any OA files, we'd go out of business, haha
Reply
#6
Get the max length of the strings in values and use that as the width. If customer_names is the list of values for the combobox, either of these will return the length of the longest name.
length = len(max(customer_names, key=len))
length = max(len(customer) for customer in customer_names)
Also, there are always OA files on the record; there are about 35 orders currently active, which all have OA files. If the window didn't open up from not having found any OA files, we'd go out of business, haha
It is poor practice to make assumptions about things that will "always be" or "never be". I have a shelf of notebooks that I've filled over the years cataloging bugs in software I've written. I bet half the notes are about something my customer swore could "never happen", but yet it happened
CAD79 likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Need help to identify CNA for automation qatester 0 548 May-31-2024, 09:24 AM
Last Post: qatester
  identify not white pixels in bmp flash77 17 7,763 Nov-10-2023, 09:21 PM
Last Post: flash77
  error "cannot identify image file" part way through running hatflyer 0 1,994 Nov-02-2023, 11:45 PM
Last Post: hatflyer
  guys please help me , pycharm is not able to identify my xlsx file CrazyGreenYT7 1 2,685 Jun-13-2021, 02:22 PM
Last Post: Larz60+
  Need to identify only files created today. tester_V 5 7,365 Feb-18-2021, 06:32 AM
Last Post: tester_V
  Split Characters As Lines in File quest_ 3 3,405 Dec-28-2020, 09:31 AM
Last Post: quest_
  get two characters, count and print from a .txt file Pleiades 9 5,078 Oct-05-2020, 09:22 AM
Last Post: perfringo
  Reading integers from a file; the problem may be the newline characters JRWoodwardMSW 2 2,955 Jul-14-2020, 02:27 AM
Last Post: bowlofred
  Remove escape characters / Unicode characters from string DreamingInsanity 5 21,602 May-15-2020, 01:37 PM
Last Post: snippsat
  CSV file escaping characters lokhtar 2 4,434 Dec-09-2019, 06:48 PM
Last Post: lokhtar

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020