Python Forum
[split] How to ask Smart Questions (thread title expansion) - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: Homework (https://python-forum.io/forum-9.html)
+--- Thread: [split] How to ask Smart Questions (thread title expansion) (/thread-41613.html)



[split] How to ask Smart Questions (thread title expansion) - saifalikhan9 - Feb-17-2024

import tkinter as tk
from tkinter import ttk, messagebox
from reportlab.pdfgen import canvas

class GuillotineCuttingOptimizer:
    def __init__(self, stock_width, stock_length, stock_quantity, cut_sizes):
        self.stock_width = stock_width
        self.stock_length = stock_length
        self.stock_quantity = stock_quantity
        self.cut_sizes = cut_sizes
        self.sheets_needed = 0
        self.remaining_stock_area = 0
        self.cut_plan = []

    def optimize_cutting_plan(self):
        self.cut_sizes.sort(key=lambda x: x[0] * x[1], reverse=True)

        stock_area = self.stock_width * self.stock_length * self.stock_quantity
        remaining_stock_area = stock_area
        sheets_needed = 0
        cut_plan = []

        while self.cut_sizes:
            sheet_area = stock_area
            current_cut_plan = []

            while self.cut_sizes:
                cut_width, cut_length, cut_quantity = self.cut_sizes.pop(0)

                if cut_width <= self.stock_width and cut_length <= self.stock_length:
                    current_cut_plan.append((cut_width, cut_length, cut_quantity))
                    sheet_area -= cut_width * cut_length * cut_quantity

            if sheet_area < stock_area:
                sheets_needed += 1
                remaining_stock_area -= sheet_area
                cut_plan.extend(current_cut_plan)

        self.sheets_needed = sheets_needed
        self.remaining_stock_area = remaining_stock_area
        self.cut_plan = cut_plan

class GuillotineApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Guillotine Cutting Planner")

        # Variables
        self.stock_width_var = tk.DoubleVar()
        self.stock_length_var = tk.DoubleVar()
        self.stock_quantity_var = tk.IntVar()
        self.cut_width_var = tk.DoubleVar()
        self.cut_length_var = tk.DoubleVar()
        self.cut_quantity_var = tk.IntVar()
        self.cut_sizes = []

        # Create and place widgets
        self.create_widgets()

    def create_widgets(self):
        # Stock Sheet Entry
        stock_frame = ttk.LabelFrame(self.root, text="Stock Sheet")
        stock_frame.grid(row=0, column=0, padx=10, pady=10, sticky="ew")

        self.create_label_entry(stock_frame, "Width:", self.stock_width_var, 0)
        self.create_label_entry(stock_frame, "Length:", self.stock_length_var, 1)
        self.create_label_entry(stock_frame, "Quantity:", self.stock_quantity_var, 2)

        # Cut Sizes Entry
        cuts_frame = ttk.LabelFrame(self.root, text="Cut Sizes")
        cuts_frame.grid(row=1, column=0, padx=10, pady=10, sticky="ew")

        self.create_label_entry(cuts_frame, "Width:", self.cut_width_var, 0)
        self.create_label_entry(cuts_frame, "Length:", self.cut_length_var, 1)
        self.create_label_entry(cuts_frame, "Quantity:", self.cut_quantity_var, 2)

        ttk.Button(self.root, text="Optimize", command=self.optimize_and_display).grid(row=2, column=0, pady=20)
        ttk.Button(self.root, text="Export to PDF", command=self.export_to_pdf).grid(row=3, column=0, pady=10)

        # Canvas for Drawing
        self.canvas = tk.Canvas(self.root, bg="white", width=800, height=600)
        self.canvas.grid(row=0, column=1, rowspan=4, padx=10, pady=10, sticky="nsew")

        # Make canvas resizable
        self.root.grid_rowconfigure(0, weight=1)
        self.root.grid_columnconfigure(1, weight=1)

        # Bind canvas resize event
        self.canvas.bind("<Configure>", self.on_canvas_resize)

    def create_label_entry(self, frame, label_text, variable, row):
        ttk.Label(frame, text=label_text).grid(row=row, column=0, padx=5, pady=5, sticky="e")
        ttk.Entry(frame, textvariable=variable).grid(row=row, column=1, padx=5, pady=5, sticky="w")

    def on_canvas_resize(self, event):
        # Redraw the cut sizes when the canvas is resized
        self.display_cut_sizes(self.cut_sizes)

    def optimize_and_display(self):
        try:
            stock_width = float(self.stock_width_var.get())
            stock_length = float(self.stock_length_var.get())
            stock_quantity = int(self.stock_quantity_var.get())

            cut_width = float(self.cut_width_var.get())
            cut_length = float(self.cut_length_var.get())
            cut_quantity = int(self.cut_quantity_var.get())

            if cut_width > 0 and cut_length > 0 and cut_quantity > 0:
                self.cut_sizes.append((cut_width, cut_length, cut_quantity))
            else:
                messagebox.showerror("Error", "Please enter valid positive values for Cut Width, Length, and Quantity.")

            optimizer = GuillotineCuttingOptimizer(stock_width, stock_length, stock_quantity, self.cut_sizes)
            optimizer.optimize_cutting_plan()

            self.display_stock_size(stock_width, stock_length, stock_quantity)
            self.display_optimization_results(optimizer)
            self.display_cut_sizes(optimizer.cut_plan)
            messagebox.showinfo("Optimized Calculation",
                                f"Optimized Cutting Plan:\nTotal sheets needed: {optimizer.sheets_needed}\nRemaining stock area: {optimizer.remaining_stock_area:.2f} mm²")

        except ValueError:
            messagebox.showerror("Error", "Please enter valid numeric values.")

    def display_stock_size(self, stock_width, stock_length, stock_quantity):
        # Clear previous drawings on the canvas
        self.canvas.delete("stock_size")

        # Calculate total dimensions of stock sheet
        total_width = stock_width * stock_quantity
        total_length = stock_length

        # Draw the stock sheet rectangle
        self.canvas.create_rectangle(10, 10, total_width + 10, total_length + 10,
                                     outline="black", fill="lightgreen", tags="stock_size")

        # Display stock size dimensions
        self.canvas.create_text(total_width / 2 + 10, total_length / 2 + 10,
                                text=f"Stock Size\n{stock_width} mm x {stock_length} mm x {stock_quantity}",
                                fill="black", anchor="center", tags="stock_size")

    def display_cut_sizes(self, cut_plan):
        # Clear previous drawings on the canvas
        self.canvas.delete("cut_sizes")

        # Calculate total dimensions of stock sheet and cut sizes
        total_width = max(self.stock_width_var.get(), *map(lambda x: x[0], cut_plan))
        total_length = max(self.stock_length_var.get(), *map(lambda x: x[1], cut_plan))

        # Calculate scale factor based on canvas size and total dimensions
        scale_factor = min(self.canvas.winfo_width() / total_width, self.canvas.winfo_height() / total_length)

        current_x = 10
        current_y = 10

        for cut_width, cut_length, cut_quantity in cut_plan:
            # Scale dimensions for better visibility
            scaled_width = cut_width * scale_factor
            scaled_length = cut_length * scale_factor

            # Draw the cut size rectangle
            for _ in range(cut_quantity):
                self.canvas.create_rectangle(current_x, current_y, current_x + scaled_width, current_y + scaled_length,
                                             outline="black", fill="lightblue", tags="cut_sizes")

                # Display cut size dimensions
                self.canvas.create_text(current_x + scaled_width / 2, current_y - 5,
                                        text=f"{cut_width} mm", fill="black", anchor="s", tags="cut_sizes")

                self.canvas.create_text(current_x - 5, current_y + scaled_length / 2,
                                        text=f"{cut_length} mm", fill="black", anchor="e", tags="cut_sizes")

                # Display cut size quantity
                self.canvas.create_text(current_x + scaled_width / 2, current_y + scaled_length + 5,
                                        text=f"Qty: {cut_quantity}", fill="black", anchor="n", tags="cut_sizes")

                current_y += scaled_length  # Remove the gap between cut sizes

        # Adjust the canvas scroll region based on the actual drawing dimensions
        self.canvas.config(scrollregion=self.canvas.bbox("all"))

    def display_optimization_results(self, optimizer):
        # Display optimization results on the canvas
        result_text = f"Optimization Results:\nTotal sheets needed: {optimizer.sheets_needed}\nRemaining stock area: {optimizer.remaining_stock_area:.2f} mm²"
        self.canvas.create_text(400, 500, text=result_text, fill="black", anchor="center", tags="optimization_results")

    def export_to_pdf(self):
        try:
            pdf_filename = "cutting_plan.pdf"
            pdf = canvas.Canvas(pdf_filename, pagesize=(800, 600))
            self.display_stock_size_to_pdf(pdf, float(self.stock_width_var.get()), float(self.stock_length_var.get()), int(self.stock_quantity_var.get()))
            self.display_cut_sizes_to_pdf(pdf, self.cut_sizes)
            self.display_optimization_results_to_pdf(pdf)  # Pass optimizer object here
            pdf.save()
            messagebox.showinfo("PDF Export", f"The cutting plan has been exported to {pdf_filename}")

        except Exception as e:
            messagebox.showerror("Error", f"An error occurred while exporting to PDF: {str(e)}")

    def display_stock_size_to_pdf(self, pdf, stock_width, stock_length, stock_quantity):
        # Calculate total dimensions of stock sheet
        total_width = stock_width * stock_quantity
        total_length = stock_length

        # Draw the stock sheet rectangle on PDF
        pdf.rect(10, 10, total_width + 10, total_length + 10, fill=1)

        # Display stock size dimensions on PDF
        pdf.drawCentredString(total_width / 2 + 10, total_length / 2 + 10,
                              f"Stock Size\n{stock_width} mm x {stock_length} mm x {stock_quantity}")

    def display_cut_sizes_to_pdf(self, pdf, cut_plan):
        current_x = 10
        current_y = 10

        for cut_width, cut_length, cut_quantity in cut_plan:
            # Scale dimensions for better visibility
            scale_factor = 10
            scaled_width = cut_width * scale_factor
            scaled_length = cut_length * scale_factor

            # Draw the cut size rectangle on PDF
            for _ in range(cut_quantity):
                pdf.rect(current_x, current_y, scaled_width, scaled_length, fill=1)

                # Display cut size dimensions on PDF
                pdf.drawCentredString(current_x + scaled_width / 2, current_y - 5, f"{cut_width} mm")
                pdf.drawRightString(current_x - 5, current_y + scaled_length / 2, f"{cut_length} mm")

                # Display cut size quantity on PDF
                pdf.drawCentredString(current_x + scaled_width / 2, current_y + scaled_length + 5, f"Qty: {cut_quantity}")

                current_y += scaled_length + 10

    def display_optimization_results_to_pdf(self, pdf):
        # Display optimization results on PDF
        result_text = f"Optimization Results:\nTotal sheets needed: {self.sheets_needed}\nRemaining stock area: {self.remaining_stock_area:.2f} mm²"
        pdf.drawCentredString(400, 500, result_text)

if __name__ == "__main__":
    root = tk.Tk()
    app = GuillotineApp(root)
    root.mainloop()
I need help to finding best 2d cutting optimization cutting plan on cutting layout.
It is not working to display well calculated and quality results for the same.