__________
https://linktr.ee/marcususa
Tuesday, October 6, 2026
Programming and Distribution Questions Q4OS vs. antiX
The keyword over the years is "persistence". I remember the Windows days when you downloaded an .exe file and it worked. You could come back and it was there. "And we liked it like that." - Old Grumpy Man
Now in Linux, I make changes and it comes back blank/default. My changes didn't matter?
How can someone get a program and actually have all the files they need without all this pip install crap?
I recently tried Q4OS which brings back nostalgia from the 2000-2010 era.
I also like MX Linux, Fluxbox, and probably antiX (haven't tried yet).
Puppy Linux, SliTaz, and Porteus are ultra-lightweight distros. However, you still need to build the OS to your desires. This is what I am learning about this Totten project. How much modification do you want to do? Do you want to add air to your tires, do you want to change your oil, do you want to replace a tire, do you want to test the battery, do you want to change the car lights, do you want to fix the actuator for locking, etc...
Sunday, September 27, 2026
When vibecoding becomes difficult
https://bsky.app/profile/marcususa.bsky.social/post/3mwjavjjurs2f
And to alleviate later frustrations, if you want a backup of your github files, use this:
git clone https://github.com/YOUR_USERNAME/REPO_NAME.git
Other approaches ask for username and password info. Even if you put it in correctly, they don't accept it. Fucking bastards.
Friday, September 18, 2026
Kubuntu DPI vertical problem turns into a "wider" Microsoft 11 problem?
Developing to make all happy.
Kubuntu makes it too vertical, Microsoft makes it too wide.
Huey Lewis said/sung it once, "Hip to be Square".
Huey Lewis & The News - Hip To Be Square
https://youtu.be/LB5YkmjalDg?si=wE7UHpUIFsmvUQ9J
Tuesday, September 15, 2026
Stockfish 19 came out as universal, and I recently learned not all Linux distros are universal. Welcome to KDE Plasma, EndeavourOS (Endeavor for us Yanks), and ArchLinux. This is when compared to Xfce distros (Xubuntu, PeppermintOS, and MX Linux), we need to look at vertical size. "a" or "A". Who is taller? Why can't "a" levitate? Koreans do that with Hangul.
Saturday, September 12, 2026
Sunday, August 30, 2026
Finally getting Catalog, Mixed Collections, and Patterns to work independently
I found that tree sub-folders makes it difficult to switch between workspaces. It's better to create a new folder in the parent folder.
Also, main.py (or whatever handles this) has to create a new .self in order to discern sub-layers as needed in the Patterns section.
Two examples of using what works out of the box vs. what is needed to modify.
https://github.com/marcususa/Totten
text### Page 1 ###
self.analysis_workspace = MixedAnalysis(self)
self.analysis_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
self.analysis_workspace.grid_remove() # Hide initially
# Register references in state
state.workspace = self.catalog_workspace
state.catalog_workspace = self.catalog_workspace
state.mixed_workspace = self.mixed_workspace
state.analysis_workspace = self.analysis_workspace
state.app_root = self
state.show_workspace = self.show_workspace
def show_workspace(self, target):
"""Persistent switchboard router that toggles pre-built workspace frames cleanly."""
# Hide all workspaces first
if hasattr(state, "catalog_workspace") and state.catalog_workspace:
state.catalog_workspace.grid_remove()
if hasattr(state, "mixed_workspace") and state.mixed_workspace:
state.mixed_workspace.grid_remove()
if hasattr(state, "analysis_workspace") and state.analysis_workspace:
state.analysis_workspace.grid_remove()
# Show the target workspace
if target == "mixed" or target == "mixed_analysis":
state.mixed_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
state.mixed_workspace.tkraise()
state.workspace = state.mixed_workspace
# Load any pending game subset data
src = getattr(state, "active_category_source", None)
if src:
if isinstance(src, list) and hasattr(state.mixed_workspace, "load_games_list"):
state.mixed_workspace.load_games_list(src)
elif isinstance(src, str):
if hasattr(state.mixed_workspace, "load_catalog_data"):
state.mixed_workspace.filename = src
state.mixed_workspace.load_catalog_data()
else:
if hasattr(state.mixed_workspace, "load_catalog_data"):
state.mixed_workspace.load_catalog_data()
elif target == "analysis":
state.analysis_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
state.analysis_workspace.tkraise()
state.workspace = state.analysis_workspace
else:
state.catalog_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
state.catalog_workspace.tkraise()
state.workspace = state.catalog_workspace
if __name__ == "__main__":
ctk.set_appearance_mode("Dark")
ctk.set_default_color_theme("blue")
app = Totten()
app.mainloop()
Response: The reason show_workspace() raised an unexpected keyword argument error is that the routing switchboard accepts only a target string argument, while your selection handler was trying to pass initial_games= directly into it.
Furthermore, looking at Totten._init_ui(), the application pre-initializes the catalog workspace once on startup and then just toggles visibility with grid_remove() and tkraise(). Because it's a pre-built frame rather than newly instantiated on click, calling show_workspace("catalog") didn't catch the new games stored in catalog_state["active_games"].
To fix this so that clicking Catalog properly loads search_catalog_workspace.py first, and then correctly routes your selected subset into catalog_analysis.py, update show_workspace in your Totten class:
### Page 2 ###
def show_workspace(self, target, *args, **kwargs):
"""Persistent switchboard router that toggles or re-creates workspaces based on navigation flow."""
# Hide all main workspaces first
if hasattr(state, "catalog_workspace") and state.catalog_workspace:
state.catalog_workspace.grid_remove()
if hasattr(state, "mixed_workspace") and state.mixed_workspace:
state.mixed_workspace.grid_remove()
if hasattr(state, "analysis_workspace") and state.analysis_workspace:
state.analysis_workspace.grid_remove()
# Also clean up any transient search/selector workspace frame if active
if hasattr(state, "transient_workspace") and state.transient_workspace:
state.transient_workspace.destroy()
state.transient_workspace = None
# Route based on target type
if target == "search_catalog" or target == "catalog_search":
# Stage 1: Load search_catalog_workspace.py selector view
from gui.search_catalog_workspace import SearchCatalogWorkspace
try:
self.transient_workspace = SearchCatalogWorkspace(self)
except TypeError:
from gui.search_catalog_workspace import create_workspace
self.transient_workspace = create_workspace(self)
self.transient_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
self.transient_workspace.tkraise()
state.workspace = self.transient_workspace
elif target == "catalog" or target == "catalog_analysis":
# Stage 2: Load/Refresh catalog analysis with any isolated state games
initial_games = kwargs.get("initial_games") or state.catalog_state.get("active_games")
# If a filtered subset was chosen, we rebuild or update the catalog workspace view
if initial_games:
if hasattr(state, "catalog_workspace") and state.catalog_workspace:
state.catalog_workspace.destroy()
from gui.catalog_analysis import create_workspace
state.catalog_workspace = create_workspace(self, initial_games=initial_games)
state.catalog_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
# Clear out bucket after consumption
state.catalog_state["active_games"] = None
state.catalog_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
state.catalog_workspace.tkraise()
state.workspace = state.catalog_workspace
elif target == "mixed" or target == "mixed_analysis":
state.mixed_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
state.mixed_workspace.tkraise()
state.workspace = state.mixed_workspace
src = kwargs.get("initial_games") or getattr(state, "active_category_source", None) or state.mixed_state.get("active_games")
if src:
if isinstance(src, list) and hasattr(state.mixed_workspace, "load_games_list"):
state.mixed_workspace.load_games_list(src)
elif isinstance(src, str):
if hasattr(state.mixed_workspace, "load_catalog_data"):
state.mixed_workspace.filename = src
state.mixed_workspace.load_catalog_data()
else:
if hasattr(state.mixed_workspace, "load_catalog_data"):
state.mixed_workspace.load_catalog_data()
### Page 3 ###
elif target == "analysis":
state.analysis_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
state.analysis_workspace.tkraise()
state.workspace = state.analysis_workspace
else:
state.catalog_workspace.grid(row=0, column=1, sticky="nsew", padx=5, pady=5)
state.catalog_workspace.tkraise()
state.workspace = state.catalog_workspace
Wiring Your Sidebar / Buttons
1. When your sidebar button for Catalog is clicked, call:
state.show_workspace("search_catalog")
2. When the user finishes picking their game group inside search_catalog_workspace.py, finalize it with:
import gui.app_state as state
state.catalog_state["active_games"] = chosen_games_list
state.show_workspace("catalog")
User prompt: I am unsure about 1 and 2 at the end. Like this?
self.btn_catalog = ctk.CTkButton(self, text="Catalog", anchor="w", fg_color="transparent", hover_color="#2e4a8c", text_color="white", command=lambda: self.on_navigate("search_catalog"))
self.btn_catalog.pack(fill="x", padx=4, pady=(15, 5))
state.show_workspace("search_catalog")
Response: Yes, that lambda setup for the sidebar button is precisely correct. When clicked, self.on_navigate("search_catalog") will trigger state.show_workspace("search_catalog"), launching the search selector workspace first.
For step 2, when the user finishes picking their game group inside search_catalog_workspace.py, the button or confirmation action inside that selector should look like this:
import gui.app_state as state
def on_group_selected(self, chosen_games_list):
# Store the chosen subset in the isolated catalog bucket
state.catalog_state["active_games"] = chosen_games_list
### Page 4 ###
# Trigger the switch to the catalog analysis workspace
if hasattr(state, "show_workspace"):
state.show_workspace("catalog")
This completes the two-stage handoff: clicking Catalog opens the search/selector view first, and confirming a group transitions directly into catalog_analysis.py populated exclusively with that filtered subset.
User prompt: And that just goes up at the top?
Response: Yes, place import gui.app_state as state at the very top of search_catalog_workspace.py alongside your other imports (like customtkinter).
The on_group_selected function (or whatever method handles the event when the user confirms their choice) goes inside the search workspace class itself, placed right where the user clicks the final "Load" or "Analyze" button for that group.
User prompt: OMG!!!
Response: It looks like that two-stage handoff finally clicked into place!
With the search selection now routing cleanly into catalog_analysis.py using the isolated state bucket, you've got a solid pattern established. Whenever you're ready to tackle the exact same two-stage flow for Mixed Collections (edit_workspace.py transitioning to mixed_analysis.py), just let me know.
Subscribe to:
Posts (Atom)
-
**See 6/22 post for adjustments.** Code can be tested at https://www.programiz.com/python-programming/online-compiler/ (Remove the 3 lines ...
-
The code below starts the bidding process. It's possible now to add graphics, that might be next as well as continuing with picking up. ...





