0% found this document useful (0 votes)
7 views21 pages

Excel Like App Using Python

The document provides a guide to creating a basic spreadsheet application in Python using tkinter for a GUI interface. It includes code examples for setting up a simple spreadsheet that allows users to input values and formulas, evaluate them, and display results. Additionally, it outlines plans for enhancing the application with features like retaining formulas, saving/loading functionality, and preventing circular references.

Uploaded by

koropi8732
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views21 pages

Excel Like App Using Python

The document provides a guide to creating a basic spreadsheet application in Python using tkinter for a GUI interface. It includes code examples for setting up a simple spreadsheet that allows users to input values and formulas, evaluate them, and display results. Additionally, it outlines plans for enhancing the application with features like retaining formulas, saving/loading functionality, and preventing circular references.

Uploaded by

koropi8732
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 21

Excel like app using Python

i want to code in python that lets me create spreadsheet to perform basic arithmetic ops

ChatGPT said:

To create a basic spreadsheet-like tool in Python that can perform basic arithmetic operations (like
addition, subtraction, multiplication, division), you can use openpyxl for working with Excel files or build
a simple terminal-based version using plain Python and maybe pandas.

Here's a minimal terminal-based version to get you started:

✅ Simple Spreadsheet in Terminal

python

CopyEdit

class SimpleSpreadsheet:

def __init__(self):

self.cells = {}

def set_cell(self, cell_name, value):

self.cells[cell_name.upper()] = value

def get_cell(self, cell_name):

return self.cells.get(cell_name.upper(), 0)

def evaluate_formula(self, formula):

try:

# Replace cell names with their values

tokens = formula.split()

for i, token in enumerate(tokens):

if token.isalpha() or (token[:-1].isalpha() and token[-1].isdigit()):

tokens[i] = str(self.get_cell(token))
return eval(" ".join(tokens))

except Exception as e:

return f"Error: {e}"

def display(self):

print("\nSpreadsheet:")

for cell, value in sorted(self.cells.items()):

print(f"{cell}: {value}")

print()

# Example usage

sheet = SimpleSpreadsheet()

sheet.set_cell("A1", 10)

sheet.set_cell("B1", 5)

print("A1 + B1 =", sheet.evaluate_formula("A1 + B1")) # Output: 15

sheet.display()

🧮 Features:

 Set values to cells (like A1, B1, etc.)

 Evaluate formulas with basic arithmetic using cell references

 Display current cell values

🛠 If you want to extend this:

 Add support for reading formulas like "=A1 + B1" and auto-calculating

 Save/load to/from a .csv or .xlsx file (via csv or openpyxl)

 Build a GUI using tkinter or PyQt

Would you prefer a version that saves to an actual Excel file or works with a GUI?
You said:

i need a gui based interface

ChatGPT said:

Great! Let's build a GUI-based spreadsheet-like application in Python that allows you to enter values
and formulas (like =A1+B1) and perform basic arithmetic operations.

We'll use tkinter (Python's built-in GUI library) and support a grid of cells with basic arithmetic parsing.

✅ GUI Spreadsheet in Python with Tkinter

🔧 Features:

 Click and edit cells

 Supports simple formulas like =A1+B1 or =A1*2

 Displays computed results

📦 Requirements:

Only tkinter, which comes with standard Python.

🧾 Code:

python

CopyEdit

import tkinter as tk

from tkinter import messagebox

class SpreadsheetApp:

def __init__(self, master, rows=5, cols=5):

self.master = master

self.rows = rows

self.cols = cols

self.cells = {}

self.entries = {}
self.build_grid()

def build_grid(self):

for row in range(self.rows + 1):

for col in range(self.cols + 1):

if row == 0 and col == 0:

tk.Label(self.master, text="").grid(row=0, column=0)

elif row == 0:

tk.Label(self.master, text=chr(ord('A') + col - 1)).grid(row=0, column=col)

elif col == 0:

tk.Label(self.master, text=str(row)).grid(row=row, column=0)

else:

entry = tk.Entry(self.master, width=10)

entry.grid(row=row, column=col)

coord = f"{chr(ord('A') + col - 1)}{row}"

entry.bind("<FocusOut>", lambda e, c=coord: self.evaluate_cell(c))

self.entries[coord] = entry

tk.Button(self.master, text="Evaluate All", command=self.evaluate_all).grid(row=self.rows + 1,


column=0, columnspan=self.cols + 1)

def evaluate_cell(self, coord):

entry = self.entries[coord]

content = entry.get()

if content.startswith("="):

try:

formula = content[1:]

for key in self.entries:


val = self.entries[key].get()

if val.startswith("="):

continue # skip unresolved formulas

formula = formula.replace(key, val)

result = eval(formula)

entry.delete(0, tk.END)

entry.insert(0, str(result))

except Exception as e:

messagebox.showerror("Error", f"Error evaluating {coord}: {e}")

def evaluate_all(self):

for coord in self.entries:

self.evaluate_cell(coord)

if __name__ == "__main__":

root = tk.Tk()

root.title("Simple Spreadsheet")

app = SpreadsheetApp(root)

root.mainloop()

🧪 Try:

 Type 10 into A1, and =A1*2 into B1. Click away to auto-evaluate or hit "Evaluate All".

🧠 Next Steps (Optional Ideas):

 Add save/load to file

 Expand to larger grid

 Support for more complex formulas (SUM, ranges)

 Undo/redo, copy-paste
Would you like help adding file saving/loading or more spreadsheet functions like SUM() or cell
highlighting?

You said:

please explain each line of code

ChatGPT said:

Sure! Let's go line by line through the GUI spreadsheet code to explain exactly what's happening. This
will help you understand how the application is structured and how everything works.

🔍 Line-by-Line Explanation

python

CopyEdit

import tkinter as tk

from tkinter import messagebox

 Imports the tkinter GUI toolkit.

 tk is used for building the interface.

 messagebox is used to show pop-up error messages.

🧱 SpreadsheetApp Class

python

CopyEdit

class SpreadsheetApp:

 Defines a class to encapsulate all the spreadsheet logic.

python

CopyEdit

def __init__(self, master, rows=5, cols=5):

 The constructor initializes the spreadsheet with a default 5x5 grid.

 master is the main window (passed in from root later).

python

CopyEdit
self.master = master

self.rows = rows

self.cols = cols

self.cells = {}

self.entries = {}

 self.master: stores the main window.

 self.rows and self.cols: number of rows and columns.

 self.entries: stores cell widgets like {"A1": <Entry widget>}.

🔧 Build the Grid

python

CopyEdit

self.build_grid()

 Calls a method to build the grid of Entry boxes and labels.

🧱 Method: build_grid

python

CopyEdit

def build_grid(self):

 Sets up the visible spreadsheet grid.

python

CopyEdit

for row in range(self.rows + 1):

for col in range(self.cols + 1):

 Loops through each row and column. Adds 1 to include the header row/column (e.g., A, B, 1, 2).

python

CopyEdit

if row == 0 and col == 0:

tk.Label(self.master, text="").grid(row=0, column=0)


 Top-left corner is blank (no label).

python

CopyEdit

elif row == 0:

tk.Label(self.master, text=chr(ord('A') + col - 1)).grid(row=0, column=col)

 Top row: shows column headers (A, B, C, ...).

python

CopyEdit

elif col == 0:

tk.Label(self.master, text=str(row)).grid(row=row, column=0)

 First column: shows row headers (1, 2, 3, ...).

python

CopyEdit

else:

entry = tk.Entry(self.master, width=10)

entry.grid(row=row, column=col)

 For all other cells, create an editable text box (Entry).

python

CopyEdit

coord = f"{chr(ord('A') + col - 1)}{row}"

 Generates cell names like "A1", "B2", etc.

python

CopyEdit

entry.bind("<FocusOut>", lambda e, c=coord: self.evaluate_cell(c))

 When the user leaves the cell (focus out), it tries to evaluate it.

python

CopyEdit

self.entries[coord] = entry

 Stores the entry widget in a dictionary keyed by its cell name.


▶ Button to Evaluate All

python

CopyEdit

tk.Button(self.master, text="Evaluate All", command=self.evaluate_all).grid(row=self.rows + 1,


column=0, columnspan=self.cols + 1)

 Adds a button at the bottom to evaluate all formulas in all cells.

🧠 Method: evaluate_cell

python

CopyEdit

def evaluate_cell(self, coord):

 Evaluates a single cell (e.g., when user exits that cell).

python

CopyEdit

entry = self.entries[coord]

content = entry.get()

 Gets the cell's content (user input).

python

CopyEdit

if content.startswith("="):

 Checks if the content is a formula (starts with =).

python

CopyEdit

try:

formula = content[1:]

 Strips the = to get the actual formula (e.g., A1+B1).

python

CopyEdit
for key in self.entries:

val = self.entries[key].get()

if val.startswith("="):

continue # skip unresolved formulas

 Replaces all cell references in the formula with actual numbers.

 Skips unresolved formulas (to avoid circular errors).

python

CopyEdit

formula = formula.replace(key, val)

 Replaces, for example, A1 with its value (10).

python

CopyEdit

result = eval(formula)

 Evaluates the formula using Python’s eval() function (e.g., "10 + 5" → 15).

python

CopyEdit

entry.delete(0, tk.END)

entry.insert(0, str(result))

 Replaces the formula in the cell with the result.

python

CopyEdit

except Exception as e:

messagebox.showerror("Error", f"Error evaluating {coord}: {e}")

 Shows an error message if something goes wrong during evaluation.

🧠 Method: evaluate_all

python

CopyEdit

def evaluate_all(self):
for coord in self.entries:

self.evaluate_cell(coord)

 Loops through all cells and evaluates each one.

▶ Main Program Execution

python

CopyEdit

if __name__ == "__main__":

root = tk.Tk()

root.title("Simple Spreadsheet")

app = SpreadsheetApp(root)

root.mainloop()

 This part creates the main window and runs the app:

o tk.Tk() → creates the main GUI window

o SpreadsheetApp(root) → builds the app inside the window

o mainloop() → keeps the window open

🧪 Try Example

1. Run the script.

2. In cell A1, type: 10

3. In B1, type: =A1*2

4. Click outside or press "Evaluate All" — B1 should now say 20.

Would you like to extend this to:

 Keep formulas in the cell after evaluation?

 Add saving/loading functionality?

 Handle circular references or advanced functions?

Let me know!

You said:
yes definetely

ChatGPT said:

Awesome! Let's gradually enhance your spreadsheet app with the following features:

✅ Upgrade Plan

1. Retain formulas in cells


Currently, formulas are replaced by values. We'll keep the formula and display the value
separately.

2. Add Save/Load to file


Save the spreadsheet (including formulas) to a file and reload it later.

3. Prevent circular references


Detect if a formula refers to itself directly or indirectly (basic validation).

We'll tackle these features step-by-step. First, let’s enhance the app to:

🔁 1. Keep formulas while displaying evaluated values

🔧 Update Explanation:

 Store raw content (e.g., =A1+2) internally.

 Show the evaluated result visually, but keep the original input when editing again.

🧾 Modified Code (Part 1 – Preserve Formulas):

Replace your current class with the one below (other code stays the same):

python

CopyEdit

class SpreadsheetApp:

def __init__(self, master, rows=5, cols=5):

self.master = master

self.rows = rows

self.cols = cols

self.entries = {}
self.formulas = {} # NEW: Store formulas per cell

self.build_grid()

def build_grid(self):

for row in range(self.rows + 1):

for col in range(self.cols + 1):

if row == 0 and col == 0:

tk.Label(self.master, text="").grid(row=0, column=0)

elif row == 0:

tk.Label(self.master, text=chr(ord('A') + col - 1)).grid(row=0, column=col)

elif col == 0:

tk.Label(self.master, text=str(row)).grid(row=row, column=0)

else:

coord = f"{chr(ord('A') + col - 1)}{row}"

entry = tk.Entry(self.master, width=10)

entry.grid(row=row, column=col)

entry.insert(0, "") # empty cell

entry.bind("<FocusIn>", lambda e, c=coord: self.show_formula(c))

entry.bind("<FocusOut>", lambda e, c=coord: self.save_and_evaluate(c))

self.entries[coord] = entry

tk.Button(self.master, text="Evaluate All", command=self.evaluate_all).grid(row=self.rows + 1,


column=0, columnspan=self.cols + 1)

def show_formula(self, coord):

# Show formula when user clicks into the cell

entry = self.entries[coord]

if coord in self.formulas:
entry.delete(0, tk.END)

entry.insert(0, self.formulas[coord])

def save_and_evaluate(self, coord):

entry = self.entries[coord]

content = entry.get()

self.formulas[coord] = content

self.evaluate_cell(coord)

def evaluate_cell(self, coord):

entry = self.entries[coord]

content = self.formulas.get(coord, "")

if content.startswith("="):

try:

formula = content[1:]

for key in self.entries:

val = self.formulas.get(key, self.entries[key].get())

if val.startswith("="):

continue

formula = formula.replace(key, val)

result = eval(formula)

entry.delete(0, tk.END)

entry.insert(0, str(result))

except Exception as e:

entry.delete(0, tk.END)

entry.insert(0, "ERR")

messagebox.showerror("Error", f"Error in {coord}: {e}")

else:

entry.delete(0, tk.END)
entry.insert(0, content)

def evaluate_all(self):

for coord in self.entries:

self.evaluate_cell(coord)

✅ What’s New:

 self.formulas: Keeps raw formulas like "=A1+5".

 On focus-in, you see the formula again.

 On focus-out, the formula is saved and the value is shown.

 Evaluating doesn’t overwrite the formula anymore.

🧪 Test It:

1. Enter 10 in A1

2. Enter =A1*2 in B1

3. Click elsewhere — value shows as 20

4. Click back on B1 — formula =A1*2 reappears

Would you like me to now add:

 📂 Save/Load to file?

 🛑 Circular reference detection?

Let’s continue!

You said:

that would be great.

ChatGPT said:

Excellent! Let’s move forward and add Save/Load functionality to your spreadsheet. This will allow
users to store their spreadsheet (including formulas) and reload it later.

📂 Step 2 – Add Save & Load


We’ll store data in a simple format:

 Save as a JSON file, mapping cell names (like "A1") to their formulas or values.

 Example:

json

CopyEdit

{"A1": "10", "B1": "=A1*2"}

🧾 Updated Code: Add Save & Load Buttons

Add this below the evaluate_all() method in your SpreadsheetApp class:

python

CopyEdit

import json

from tkinter import filedialog

def save_to_file(self):

file_path = filedialog.asksaveasfilename(defaultextension=".json",

filetypes=[("JSON files", "*.json")])

if file_path:

try:

with open(file_path, "w") as f:

json.dump(self.formulas, f)

messagebox.showinfo("Saved", "Spreadsheet saved successfully!")

except Exception as e:

messagebox.showerror("Save Error", f"Could not save file: {e}")

def load_from_file(self):

file_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])

if file_path:

try:
with open(file_path, "r") as f:

loaded_data = json.load(f)

self.formulas = loaded_data

self.update_all_cells()

messagebox.showinfo("Loaded", "Spreadsheet loaded successfully!")

except Exception as e:

messagebox.showerror("Load Error", f"Could not load file: {e}")

def update_all_cells(self):

for coord in self.entries:

if coord in self.formulas:

self.evaluate_cell(coord)

else:

self.entries[coord].delete(0, tk.END)

🧱 Add Buttons to GUI

In your build_grid() method, below the "Evaluate All" button line, add:

python

CopyEdit

tk.Button(self.master, text="Save", command=self.save_to_file).grid(row=self.rows + 2, column=0,


columnspan=self.cols // 2)

tk.Button(self.master, text="Load", command=self.load_from_file).grid(row=self.rows + 2,


column=self.cols // 2, columnspan=self.cols // 2)

✅ What’s New:

 save_to_file() → Opens a save dialog and writes formulas to a .json file.

 load_from_file() → Loads saved formulas and refreshes the spreadsheet.

 update_all_cells() → Reevaluates loaded data across the grid.


🧪 Try It Out:

1. Enter 10 in A1, =A1*2 in B1

2. Click Save

3. Clear your spreadsheet or close app

4. Click Load, choose the file — your formulas and values should return

🔄 Next Step: Detect Circular References?

Would you like a basic protection mechanism that prevents formulas like A1 = B1 + 1 and B1 = A1 + 1
from looping infinitely?

Let me know — I can show you how to build a simple dependency tracker for that.

You said:

thats the most required part, what do you think

ChatGPT said:

You're absolutely right — circular reference detection is critical for any spreadsheet app. Without it,
formulas that depend on each other in a loop (like A1 = B1 + 1 and B1 = A1 + 1) will create infinite loops
or incorrect results.

🚨 Why Circular Detection is Essential

❌ Problem Without It:

plaintext

CopyEdit

A1 = B1 + 1

B1 = A1 + 1

This results in infinite recursion: A1 needs B1 → B1 needs A1 → repeat.

✅ With Detection:

We can warn the user: “Circular reference detected involving A1 and B1”.

🧠 Plan: Simple Dependency Tracker

Key Idea:

 While evaluating a cell (e.g., A1), keep track of the path of dependent cells.
 If a cell reappears in that path → circular reference!

✅ Step 3 – Add Circular Reference Detection

🧾 Modified evaluate_cell() with dependency tracking:

Replace your existing evaluate_cell() with this version:

python

CopyEdit

def evaluate_cell(self, coord, visited=None):

if visited is None:

visited = set()

if coord in visited:

self.entries[coord].delete(0, tk.END)

self.entries[coord].insert(0, "CIRC")

messagebox.showerror("Circular Reference", f"Circular reference detected at {coord}")

return

visited.add(coord)

entry = self.entries[coord]

content = self.formulas.get(coord, "")

if content.startswith("="):

try:

formula = content[1:]

for key in self.entries:

val = self.formulas.get(key, self.entries[key].get())

if val.startswith("="):

self.evaluate_cell(key, visited.copy())

val = self.entries[key].get()
formula = formula.replace(key, val)

result = eval(formula)

entry.delete(0, tk.END)

entry.insert(0, str(result))

except Exception as e:

entry.delete(0, tk.END)

entry.insert(0, "ERR")

messagebox.showerror("Error", f"Error in {coord}: {e}")

else:

entry.delete(0, tk.END)

entry.insert(0, content)

✅ How It Works:

 visited: a set of all cells currently being evaluated in this chain.

 When we re-visit the same cell (e.g., A1 → B1 → A1), we detect the loop.

 Shows "CIRC" in the cell and displays an error message.

🧪 Test It:

1. Set A1 = B1 + 1

2. Set B1 = A1 + 1

3. You should get:

o A message: "Circular reference detected at A1"

o A1 shows CIRC, B1 shows CIRC

✅ What We’ve Achieved So Far

Feature Status

Basic GUI spreadsheet ✅

Formula parsing ✅
Feature Status

Formula retention ✅

Save/load to file ✅

Circular detection ✅

Would you like to:

 Add support for more functions like SUM(A1,B1)?

 Expand the grid size dynamically?

 Export to .xlsx (Excel) format?

Let me know where you’d like to go next!

You might also like