Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

Python Made a script that can create notes, read and delete notes. (also create folders)

fh1

Active Coder
hello i haven’t used this website in a while, but i wanted to show one of my scripts and ask for some feedback to make it a bit better 🙂
Python:
import os
createdNotes = []
createdFolders = []
print("Welcome to the note app!")
while True:
    createnote = input("Type create to create a note (or folder), press R to read one, press V to view all notes and folders you made, press D to delete a note or a folder or press E to exit.\n ")
    createnote = createnote.lower()
    
    if createnote == "d":
        removeNote = input(f"Which note or folder would you like to delete? (type in the note or folder) notes: {createdNotes}. folders: {createdFolders} ")
        try:
            os.remove(removeNote)
            print("Deleted!")
            continue
        except:
            print("An error occured, file doesn't exist.")
        try:
            os.rmdir(removeNote)
            print("Deleted!")
            continue
        except:
            print("An error occured, folder doesn't exist.")
    elif createnote == "v":
        print(f"Your notes: {createdNotes}. Your folders: {createdFolders}")
    
    elif createnote == "r":
        readnote = input("What note would you like to read? ")
        try:
                read = open(readnote, "r")
                print(read.read())
                read.close()
                continue
          
        except:
                print("An error has occured.")
                continue
    elif createnote == "e":
        print("goodbye")
        break
          
    elif createnote == "create":
        createnote2 = input("Type write to write on a existing note, type folder to create a folder, or type create to make a new note.")
        createnote2 = createnote2.lower()
        
        if createnote2 == "folder":
            nameFolder = input("What would you like to name your folder? ")
            try:
                os.mkdir(nameFolder)
                print("Folder made!")
                createdFolders.append(nameFolder)
                continue
            except:
                print("An error has occured")
        elif createnote2 == "write":
            whichnote = input("What note would you like to write on?")
            try:
                note = open(whichnote, "a")
                whatToWrite = input("What would you like to note? ")
                append = open(whichnote, "a")
                append.write(whatToWrite)
                print("noted!")
                append.close()
                continue
                
            except:
                    print("an error occured.")
                    continue
        elif createnote2 == "create":
            namenote = input("What would you like to name your note? ")
            try:
                    note = open(namenote, "x")
                    createdNotes.append(namenote)
                    whatToWrite = input("What would you like to note? ")
                    append = open(namenote, "a")
                    append.write(whatToWrite)
                    print("noted!")
                    append.close()
                    continue
                    
            except:
                print("an error occured")
                continue


wow this website changed a lot. If you experience errors please tell me.
 
Nice script. Think I would look at making the folders a category and writing the notes in a category. Use a json file to hold the structure for easy viewing.
Just a thought.
 
Last edited:
Although far from being complete, I took your project to another step. Created a gui. Here is what I have as of now.



Changed code to use ttk.Treeview instead of tk.Listbox. Have a little more controll over formatting.


Todo:
  • Create toplevel window to enter category name
  • writing the code to add, delete, update categories - toplevel window
  • write the code for adding, deleting, updating note.txt
  • Optimize code


Python:
import tkinter as tk
from tkinter import ttk
from pathlib import Path
import os
from PIL import ImageTk, Image
path = Path(__file__).parent


class Note:
    def __init__(self):
        self.path = Path(__file__).parent

    def write(self, folder, file):
        pass

    def edit(self, folder, file):
        pass

    def delete(self, folder, file):
        pass

    def get_notes(self, folder):
        notes = os.listdir(f'{path}/default/{folder}')
        if len(notes) > 0:
            return notes
        return False


class Folder:
    '''
        The purpose of this class is to create or
        remove folders
    '''
    def __init__(self):
        ''' Create the base directory '''
        self.path = f'{Path(__file__).parent}/default'
        if not os.path.exists(self.path):
            os.mkdir(self.path)

    def create(self, folder=None):
        ''' Create category/folder for notes '''
        if not os.path.exists(f'{self.path}/{folder}'):
            os.makedirs(f'{self.path}/{folder}')

    def delete(self, folder=None):
        ''' Method will delete category/folder and its contents '''
        if os.path.exists(f'{self.path}/{folder}'):
            files = os.listdir(f'{self.path}/{folder}')
            if len(files) > 0:
                for file in files:
                    os.remove(f'{self.path}/{folder}/{file}')
            os.rmdir(f'{self.path}/{folder}')
            return True
        return False

    def get_folders(self):
        folders = os.listdir(self.path)
        if len(folders) > 0:
            return folders
        return False
    
class Window:
    def __init__(self, parent):
        self.parent = parent

        # Configure window values
        parent.columnconfigure(0, weight=1)
        parent.rowconfigure(0, weight=1)
        parent.geometry('800x700')
        parent.title('Tkinter Notes')

        # Container for holding all widgets
        container = tk.Frame(parent)
        container.grid(column=0, row=0, sticky='news')
        container.grid_columnconfigure(0, weight=3)
        container.grid_columnconfigure(1, weight=0)
        container.grid_rowconfigure(2, weight=3)

        # Create the header for the app
        header = tk.Label(container, text='My Notes', padx=5, pady=5)
        header.grid(column=0, row=0, sticky='new', padx=2, pady=0)
        header.configure(
            font = (None, 40, 'bold'),
            fg = '#fffaaa',
            bg = '#ffa500'
        )

        # Create a container for holding the menu links
        menu_container = tk.LabelFrame(container, text='Options')
        menu_container.grid(column=0, row=1, sticky='ew', padx=1, pady=0)

        # Some common values for the links
        common = {'fg':'blue', 'cursor':'hand2'}

        # Create empty list for holding labels
        self.buttons = []

        # A list of button we want
        buttons =['New Category', 'Delete Category', 'New Note', 'Delete Note']

        # Label will be of equal size
        for index in range(len(buttons)):
            menu_container.grid_columnconfigure(index, weight=3)

        # Create the labels and bind to the enter and leave events
        for index, button in enumerate(buttons):
            self.buttons.append(tk.Label(menu_container, text=button))
            self.buttons[index].grid(column=index, row=0, sticky='new', padx=12, pady=4)
            self.buttons[index].bind('<Enter>', lambda event, index=index: self.hover_in(index))
            self.buttons[index].bind('<Leave>', lambda event, index=index: self.hover_out(index))
            self.buttons[index].configure(**common)

        # Mid is a container for holding treeviews and scrollbars
        mid = tk.Frame(container)
        mid.grid(column=0, row=2, sticky='news', padx=3, pady=3)
        mid.grid_columnconfigure(0, weight=3)
        mid.grid_columnconfigure(1, weight=0)
        mid.grid_columnconfigure(2, weight=3)
        mid.grid_columnconfigure(3, weight=0)
        mid.grid_rowconfigure(0, weight=3)

        # Create style so we can add some spacing in between tree items
        style = ttk.Style()
        style.configure('MyStyle.Treeview', rowheight=25)

        # Left tree is for displaying categories
        self.left = ttk.Treeview(mid, show='headings', columns=('Categories'), selectmode='browse')
        self.left.grid(column=0, row=0, sticky='news', padx=1,pady=1)
        self.left.heading(0, text='Categories')
        self.left.configure(style='MyStyle.Treeview')
    
        # Right tree is for displaying notes in a category
        self.right = ttk.Treeview(mid, show='headings', columns=('Notes'), selectmode='browse')
        self.right.grid(column=2, row=0, sticky='news', padx=1,pady=1)
        self.right.heading(0, text='Notes')
        self.right.configure(style='MyStyle.Treeview')

        # Configure scrollbars for the left and right treeviews
        leftscroll = ttk.Scrollbar(mid, orient='vertical', command=self.left.yview)
        leftscroll.grid(column=1, row=0, sticky='ns')
        self.left.configure(yscrollcommand=leftscroll.set)

        rightscroll = ttk.Scrollbar(mid, orient='vertical', command=self.left.yview)
        rightscroll.grid(column=3, row=0, sticky='ns')
        self.right.configure(yscrollcommand=rightscroll.set)
 
        frame = tk.LabelFrame(container, text='Selected Note')
        frame.grid(column=0, row=3, sticky='news', padx=1, pady=1)
        frame.grid_columnconfigure(0, weight=3)

        # textarea will be for displaying note text
        self.textarea = tk.Text(frame, height=10, wrap='word')
        self.textarea.grid(column=0, row=0, sticky='news')
        scrollbar = tk.Scrollbar(frame, orient='vertical', command=self.textarea.yview)
        scrollbar.grid(column=1, row=0, sticky='ns')
        self.textarea.configure(yscrollcommand=scrollbar.set, state='disabled')

        # Lines below are for the footer images and text
        footer_container = tk.Frame(container)
        footer_container.grid(column=0, row=4, sticky='news', padx=1, pady=1)
    
        label = tk.Label(footer_container, text='™ my-python©')
        label.grid(column=0, row=0, padx=10, pady=4)
        image = Image.open(f'{path}/my-python-logo.png')
        image = ImageTk.PhotoImage(image.resize((40,30)))
        image.tmp = image
        label.configure(font=(None, 14, 'normal'), compound='left')

        label['image'] = image
        label = tk.Label(footer_container, anchor='w')
        label.grid(column=1, row=0, padx=2, pady=4)
        image = Image.open(f'{path}/python-logo-generic.png')
        image = ImageTk.PhotoImage(image.resize((80,30)))
        image.tmp = image
        label.configure(font=(None, 14, 'normal'))
        label['image'] = image

        label = tk.Label(footer_container, text='Tkinter')
        label.grid(column=2, row=0, padx=10, pady=4)
        image = Image.open(f'{path}/tcllogo.png')
        image = ImageTk.PhotoImage(image.resize((40,30)))
        image.tmp = image
        label.configure(font=(None, 14, 'normal'), compound='left')
        label['image'] = image

    def hover_in (self, index):
        ''' Method for giving a hover effect over label text '''
        self.buttons[index]['fg'] = 'red'

    def hover_out(self, index):
        ''' Return label text to original color '''
        self.buttons[index]['fg'] = 'blue'

class Controller:
    ''' Controller class communicates between the Window class and other two classes '''
    def __init__(self,note,folder,window):
        # Create instance variables
        self.note = note
        self.folder = folder
        self.window = window

        # Configure bind commands
        window.buttons[0].bind('<1>', self.add_category)
        window.buttons[1].bind('<1>', self.delete_category)
        window.buttons[2].bind('<1>', self.add_note)
        window.buttons[3].bind('<1>', self.delete_note)

        # Configure treeview binds
        self.window.left.bind('<ButtonRelease-1>', self.get_notes)

        # Call method to populate the categories treeview
        self.show_categories()

    def add_category(self, name=None):
        print('adding a category')

    def delete_category(self, name=None):
        print('deleting category')

    def add_note(self, category=None, name=None):
        print('adding note')

    def delete_note(self, category=None, name=None):
        print('deleting note')
    def show_categories(self):
        ''' Method grabs categories/folders and displays in left treeview '''

        # Clear the tree
        self.window.left.delete(*self.window.left.get_children())

        # Get the categories/folders
        categories = self.folder.get_folders()

        # Sort in ascending order
        categories.sort()
    
        # Check for category folders
        if len(categories) > 0:
            # Set tags to alternate row colors
            self.window.left.tag_configure('odd', background='#ffffff')
            self.window.left.tag_configure('even', background='#dcefff')
        
            # Loop through categories and insert
            for index, category in enumerate(categories):
                color = 'even' if index % 2 == 0 else 'odd'
                self.window.left.insert('', index, text=f'{category}', values=(f'{" "*2}{category}',), tags=(color,))
        else:
            pass

    def get_notes(self, event):
        ''' Method grabs notes if any and displays in right treeview '''

        # Clear the tree
        children = self.window.right.get_children()

        if len(children) > 0:
            self.window.right.delete(*self.window.right.get_children())

        # Get tree focus and item selected
        tree_item = self.window.left.focus()
        item = self.window.left.item(tree_item).get('text')
        self.window.right.heading(0, text=f'Notes - {item}')

        # Make call to notes and check if there are any - if so insert into tree
        # Else display a message
        notes = self.note.get_notes(item)
        if notes:
            self.window.right.tag_configure('odd', background='#ffffff')
            self.window.right.tag_configure('even', background='#dcefff')
            for index, note in enumerate(notes):
                color = 'even' if index % 2 == 0 else 'odd'
                self.window.right.insert('', index, text='', values=(f'{" "*2}{note.removesuffix('.txt')}',), tags=(color,))
        else:
            self.window.right.insert('', str(0), text=f'', values=(f'{" "*2}No notes for {item}',))
 
if __name__ == '__main__':
    root = tk.Tk()
    controller = Controller(Note(), Folder(), Window(root))
    root.mainloop()
 

Attachments

  • Kazam_screenshot_00001.png
    Kazam_screenshot_00001.png
    34.4 KB · Views: 10
Last edited:
Hey, nice work on the script! It’s a cool little app you’ve built. I gave it a test run and thought I’d drop some feedback that might help make it even better:

Better Error Handling: Instead of catching all errors with a general except, you could be more specific. For example, if a file doesn’t exist, Python can tell you that directly:

Python:
try:
    os.remove(removeNote)
except FileNotFoundError:
    print("Hmm, I couldn’t find that file. Maybe check the name again?")
except Exception as e:
    print(f"Oops, something went wrong: {e}")

This way, it’s easier to figure out what’s actually causing the issue if something breaks.

Don’t Forget the Notes: Right now, if you close the program, it forgets which notes and folders you made (RIP notes). You could use os.listdir() to scan the current directory and show actual files and folders, so it doesn’t rely on the lists you’re keeping in memory:

Python:
createdNotes = [f for f in os.listdir() if os.path.isfile(f)]
createdFolders = [f for f in os.listdir() if os.path.isdir(f)]

This way, even if you restart the program, it will still remember everything you’ve created.

File Checks: If you’re about to read or delete a file, it’s good practice to check if it actually exists before trying to do anything with it. Saves some frustration later:

Python:
if os.path.exists(readnote):
    with open(readnote, "r") as file:
        print(file.read())
else:
    print("That note seems to have vanished into thin air…")

Accidental Exits: Maybe add a confirmation when someone tries to exit—just in case they hit ‘E’ by mistake and didn’t mean to close the app. You know, those clumsy finger moments.

Note Overwrite Alert: If someone tries to create a note with the same name as an existing one, it’ll overwrite the old one, which might not be what they want. You could add a little check to avoid accidental overwrites:

Python:
if os.path.exists(namenote):
    print("A note with that name already exists! Want to choose a different name?")

Cleaner Interface: You don’t really need all the continue statements after print()—the loop will keep going on its own, so the code can be a bit cleaner without them.

Overall, you’re on the right track, and with a few tweaks, this could be a really smooth note app. Keep it up, and feel free to hit me up if you want to bounce more ideas around!
 
Hey, nice work on the script! It’s a cool little app you’ve built. I gave it a test run and thought I’d drop some feedback that might help make it even better:

Better Error Handling: Instead of catching all errors with a general except, you could be more specific. For example, if a file doesn’t exist, Python can tell you that directly:

Python:
try:
    os.remove(removeNote)
except FileNotFoundError:
    print("Hmm, I couldn’t find that file. Maybe check the name again?")
except Exception as e:
    print(f"Oops, something went wrong: {e}")

This way, it’s easier to figure out what’s actually causing the issue if something breaks.

Don’t Forget the Notes: Right now, if you close the program, it forgets which notes and folders you made (RIP notes). You could use os.listdir() to scan the current directory and show actual files and folders, so it doesn’t rely on the lists you’re keeping in memory:

Python:
createdNotes = [f for f in os.listdir() if os.path.isfile(f)]
createdFolders = [f for f in os.listdir() if os.path.isdir(f)]

This way, even if you restart the program, it will still remember everything you’ve created.

File Checks: If you’re about to read or delete a file, it’s good practice to check if it actually exists before trying to do anything with it. Saves some frustration later:

Python:
if os.path.exists(readnote):
    with open(readnote, "r") as file:
        print(file.read())
else:
    print("That note seems to have vanished into thin air…")

Accidental Exits: Maybe add a confirmation when someone tries to exit—just in case they hit ‘E’ by mistake and didn’t mean to close the app. You know, those clumsy finger moments.

Note Overwrite Alert: If someone tries to create a note with the same name as an existing one, it’ll overwrite the old one, which might not be what they want. You could add a little check to avoid accidental overwrites:

Python:
if os.path.exists(namenote):
    print("A note with that name already exists! Want to choose a different name?")

Cleaner Interface: You don’t really need all the continue statements after print()—the loop will keep going on its own, so the code can be a bit cleaner without them.

Overall, you’re on the right track, and with a few tweaks, this could be a really smooth note app. Keep it up, and feel free to hit me up if you want to bounce more ideas around!
Ok! Thank you for the feedback (sorry it took me 20 days to reply xD)
 

New Threads

Latest posts

Buy us a coffee!

Back
Top Bottom