Day 20,626

Runes drawn (all reversed):
ᚱ Raidho — blocked path
ᛋ Sowilo — dimmed light
ᚨ Ansuz — lost voice

I Ching ䷽: Hexagram 62 – Small Exceeding
Two old yins change: caution in small steps, not grand strides.

#runes #iching #divination #omens #synchronicity

The road is blocked. The light is dim. The voice is lost. All three runes reversed.

Hexagram 62: Small Exceeding Fly low. Speak little. Walk soft. This is not the time for bold moves – but for quiet strength and subtle steps.

Overall Message:

You are being asked to step lightly, speak less, listen more, and not rush forward—even if you’re itching to. The universe cautions against grand gestures or bold moves right now. The path is unclear, energy is low, and signals are crossed.

Runes Summary (Reversed):

Raidho reversed: The road is blocked or misaligned. You’re being asked to pause your journey or reassess the direction you’re heading.

Sowilo reversed: Your usual source of strength, confidence, or success may feel dimmed. Don’t chase recognition or progress for now—regain your inner balance.

Ansuz reversed: Communication—internal or external—is scrambled. Be wary of what you hear and what you say. Reflection trumps expression now.

These runes together suggest a spiritual fog, where intuition, clarity, and direction are all obstructed. It’s a sign to retreat inward and wait for the mist to clear.

Hexagram 62 – Small Exceeding (䷽)

This hexagram is about paying attention to the small details, not making big moves. You may feel pressured to act boldly, but the I Ching warns: “Small things may be done; great things should not be done.”

You are like a bird flying low to avoid danger—humble, cautious, and precise.

Changing Lines (two Old Yins → Yang):

Both bottom lines are changing, which means a transition is underway, but slowly. These are inner, foundational energies—suggesting an internal change of stance, like your base assumptions or beliefs shifting. Your challenge isn’t external—it’s how you carry yourself through uncertainty.

Unified Interpretation:

This is a time of inner realignment.
Don’t travel far. Don’t shout into the wind. Don’t chase the spotlight.
Instead: observe, listen, rest, and make micro-adjustments. Your strength will return, clarity will come, and your voice will rise again—but only after stillness.

A storm is passing. You’re not meant to ride it—you’re meant to wait it out in quiet wisdom.

Quick file renamer

Wrote this to clean up data from OUT-prefixed image files that I mistakenly saved without an extension on my tablet. I’m keeping my hand in to stay on top of Python for the hell of it. Since I was too lazy to rely on something else to do the job, I figured I could write something faster than a search engine would give me solid results.

I’d guess it took me longer to write comment lines than the code itself.

import os

def rename_out_files_interactive_with_options():
    “””
    Interactively renames files in a user-chosen folder (with common path options)
    that start with ‘OUT’. Shows files with no extensions before adding ‘.jpg’.
    This code is designed to be run in a PyDroid environment.
    “””
    print(“— PyDroid File Renamer —“)

    # Step 1: Allow user to choose the folder with common options
    common_paths = {
        ‘1’: os.path.join(os.path.expanduser(‘~’), ‘Download’),
        ‘2’: ‘/sdcard/Download’,
        ‘3’: ‘/storage/emulated/0/Download’,
        ‘4’: ‘/sdcard/DCIM’ # Common for camera photos
    }

    selected_folder = None
    while selected_folder is None:
        print(“\nChoose a folder to process:”)
        print(”  1) Your common Downloads folder (e.g., /storage/emulated/0/Download)”)
        print(”  2) /sdcard/Download”)
        print(”  3) /storage/emulated/0/Download (Often the same as 1 or 2)”)
        print(”  4) /sdcard/DCIM (For camera photos)”)
        print(”  C) Enter a custom path”)
        print(”  Q) Quit”)

        choice = input(“Enter your choice (1, 2, 3, 4, C, or Q): “).strip().upper()

        if choice == ‘Q’:
            print(“Exiting the script. No files were modified.”)
            return

        if choice in common_paths:
            path_attempt = common_paths[choice]
            if os.path.isdir(path_attempt):
                selected_folder = path_attempt
                print(f”Selected folder: {selected_folder}”)
            else:
                print(f”Warning: The chosen common path ‘{path_attempt}’ does not exist or is not a directory.”)
                print(“Please ensure this path is correct for your device, or try a different option.”)
        elif choice == ‘C’:
            custom_path = input(“Enter the full custom path: “).strip()
            if os.path.isdir(custom_path):
                selected_folder = custom_path
                print(f”Selected folder: {selected_folder}”)
            else:
                print(f”Error: ‘{custom_path}’ is not a valid directory. Please try again.”)
        else:
            print(“Invalid choice. Please enter 1, 2, 3, 4, C, or Q.”)

    target_folder = selected_folder

    print(f”\n— Scanning for ‘OUT’ files in: {target_folder} —“)
    files_to_process = []
    files_with_extensions = []

    try:
        for filename in os.listdir(target_folder):
            if filename.startswith(“OUT”):
                file_path = os.path.join(target_folder, filename)

                if os.path.isfile(file_path):
                    name, ext = os.path.splitext(filename)
                    if not ext:  # No extension
                        files_to_process.append(filename)
                    else:
                        files_with_extensions.append(filename)
                else:
                    print(f”Skipping ‘{filename}’: Is a directory.”)

    except PermissionError:
        print(“\nPermission denied: PyDroid may need storage permissions to access the chosen folder.”)
        print(“Please go to PyDroid settings (or Android app settings) and grant storage permissions.”)
        return
    except FileNotFoundError:
        print(f”\nError: The folder ‘{target_folder}’ was not found. This should not happen if previous checks passed.”)
        print(“Please verify the path and PyDroid’s storage permissions.”)
        return
    except Exception as e:
        print(f”\nAn unexpected error occurred during scanning: {e}”)
        return

    # Step 2: Show files with no extensions before running
    if not files_to_process and not files_with_extensions:
        print(f”\nNo files starting with ‘OUT’ were found in ‘{target_folder}’.”)
        return

    print(“\n— Found files starting with ‘OUT’ —“)
    if files_to_process:
        print(“\nThe following ‘OUT’ files currently have NO extension and will have ‘.jpg’ added:”)
        for filename in files_to_process:
            print(f”- {filename}”)
    else:
        print(“No ‘OUT’ files found without an extension that need ‘.jpg’ added.”)

    if files_with_extensions:
        print(“\nThe following ‘OUT’ files already have an extension and will be skipped:”)
        for filename in files_with_extensions:
            print(f”- {filename}”)
    else:
        print(“No ‘OUT’ files found that already have an extension.”)

    if not files_to_process:
        print(“\nNo files to rename. Exiting.”)
        return

    # Step 3: Confirmation before renaming
    print(“\n— Renaming Confirmation —“)
    confirm = input(“Do you want to proceed with renaming these files? (yes/no): “).lower().strip()

    if confirm == ‘yes’:
        files_renamed_count = 0
        print(“\n— Starting Renaming Process —“)
        for filename in files_to_process:
            original_file_path = os.path.join(target_folder, filename)
            name, _ = os.path.splitext(filename)
            new_name = name + “.jpg”
            new_file_path = os.path.join(target_folder, new_name)
            try:
                os.rename(original_file_path, new_file_path)
                print(f”Renamed: ‘{filename}’ to ‘{new_name}'”)
                files_renamed_count += 1
            except OSError as e:
                print(f”Error renaming ‘{filename}’: {e}”)
            except Exception as e:
                print(f”An unexpected error occurred while renaming ‘{filename}’: {e}”)

        print(f”\nFinished renaming. Total files renamed: {files_renamed_count}”)
    else:
        print(“\nRenaming cancelled by user. No files were modified.”)

# Call the function to run the interactive renaming process
if __name__ == “__main__”:
    rename_out_files_interactive_with_options()

Day 20, 625

Runes Whisper:
❄ Isa (rev) – frozen flow
🌱 Ingwaz – seed of fire
🌅 Dagaz (rev) – dawn delayed

I Ching:
Hexagram 4: Youthful Folly
Wisdom knocks, but waits.
Changing lines: 6→7, 9→8
The fool becomes the seeker.

Modifying code to fit in 300 chars or less, still needs tweaking

Python rune / I Ching code

With clipboard

import tkinter as tk
import random
from datetime import datetime

# Elder Futhark Runes with meanings
runes = [
    (“Fehu”, “Wealth, prosperity”),
    (“Uruz”, “Strength, health”),
    (“Thurisaz”, “Conflict, protection”),
    (“Ansuz”, “Communication, insight”),
    (“Raidho”, “Journey, travel”),
    (“Kenaz”, “Knowledge, creativity”),
    (“Gebo”, “Gift, generosity”),
    (“Wunjo”, “Joy, harmony”),
    (“Hagalaz”, “Disruption, hail”),
    (“Nauthiz”, “Need, resistance”),
    (“Isa”, “Stillness, ice”),
    (“Jera”, “Harvest, reward”),
    (“Eihwaz”, “Endurance, transformation”),
    (“Perthro”, “Mystery, fate”),
    (“Algiz”, “Protection, higher self”),
    (“Sowilo”, “Success, vitality”),
    (“Tiwaz”, “Justice, leadership”),
    (“Berkano”, “Birth, growth”),
    (“Ehwaz”, “Movement, change”),
    (“Mannaz”, “Humanity, cooperation”),
    (“Laguz”, “Flow, intuition”),
    (“Ingwaz”, “Fertility, potential”),
    (“Dagaz”, “Breakthrough, awakening”),
    (“Othala”, “Heritage, inheritance”)
]

# I Ching full 64 hexagrams
hexagrams = {
    “111111”: (1, “Creative Force”),
    “000000”: (2, “Receptive Earth”),
    “100010”: (3, “Difficulty at the Beginning”),
    “010001”: (4, “Youthful Folly”),
    “111010”: (5, “Waiting”),
    “010111”: (6, “Conflict”),
    “010000”: (7, “The Army”),
    “000010”: (8, “Holding Together”),
    “111011”: (9, “Taming the Power of the Small”),
    “110111”: (10, “Treading”),
    “111000”: (11, “Peace”),
    “000111”: (12, “Standstill”),
    “101111”: (13, “Fellowship with Men”),
    “111101”: (14, “Great Possession”),
    “001000”: (15, “Modesty”),
    “000100”: (16, “Enthusiasm”),
    “100110”: (17, “Following”),
    “011001”: (18, “Work on the Decayed”),
    “110000”: (19, “Approach”),
    “000011”: (20, “Contemplation”),
    “100101”: (21, “Biting Through”),
    “101001”: (22, “Grace”),
    “000001”: (23, “Splitting Apart”),
    “100000”: (24, “Return”),
    “100111”: (25, “Innocence”),
    “111001”: (26, “Great Taming”),
    “100001”: (27, “Nourishment”),
    “011110”: (28, “Great Exceeding”),
    “010010”: (29, “Danger”),
    “101101”: (30, “Clinging Fire”),
    “001110”: (31, “Influence”),
    “011100”: (32, “Endurance”),
    “001111”: (33, “Retreat”),
    “111100”: (34, “Great Power”),
    “000101”: (35, “Progress”),
    “101000”: (36, “Darkening of the Light”),
    “101011”: (37, “Family”),
    “110101”: (38, “Opposition”),
    “001010”: (39, “Obstruction”),
    “010100”: (40, “Deliverance”),
    “110001”: (41, “Decrease”),
    “100011”: (42, “Increase”),
    “111110”: (43, “Breakthrough”),
    “011111”: (44, “Coming to Meet”),
    “000110”: (45, “Gathering Together”),
    “011000”: (46, “Pushing Upward”),
    “010110”: (47, “Oppression”),
    “011010”: (48, “The Well”),
    “101110”: (49, “Revolution”),
    “011101”: (50, “The Cauldron”),
    “100100”: (51, “The Arousing”),
    “001001”: (52, “Keeping Still”),
    “001011”: (53, “Gradual Progress”),
    “110100”: (54, “Marrying Maiden”),
    “101100”: (55, “Abundance”),
    “001101”: (56, “The Wanderer”),
    “011011”: (57, “Gentle Wind”),
    “110110”: (58, “Joyous Lake”),
    “010011”: (59, “Dispersion”),
    “110010”: (60, “Limitation”),
    “110011”: (61, “Inner Truth”),
    “001100”: (62, “Small Exceeding”),
    “101010”: (63, “After Completion”),
    “010101”: (64, “Before Completion”)
}

def cast_runes():
    chosen = random.sample(runes, 3)
    result = []
    for name, meaning in chosen:
        reversed = random.choice([True, False])
        if reversed:
            result.append((f”{name} (reversed)”, f”Blocked or inverted: {meaning}”))
        else:
            result.append((name, meaning))
    return result

def cast_i_ching():
    lines = []
    binary = “”
    for _ in range(6):
        tosses = [random.choice([2, 3]) for _ in range(3)]
        total = sum(tosses)
        if total == 6:
            lines.append(“Old Yin (6) – changing to Yang”)
            binary = “0” + binary
        elif total == 7:
            lines.append(“Young Yang (7)”)
            binary = “1” + binary
        elif total == 8:
            lines.append(“Young Yin (8)”)
            binary = “0” + binary
        elif total == 9:
            lines.append(“Old Yang (9) – changing to Yin”)
            binary = “1” + binary
    hex_info = hexagrams.get(binary, (“?”, “Unknown Hexagram”))
    return lines[::-1], hex_info

def days_since_birth():
    return (datetime.today() – datetime(1969, 2, 2)).days

def cast_all():
    rune_results = cast_runes()
    i_ching_lines, (hex_num, hex_name) = cast_i_ching()
    days = days_since_birth()

    output_text = “Runes Drawn:\n”
    for i, (name, meaning) in enumerate(rune_results, 1):
        output_text += f” {i}. {name} – {meaning}\n”

    output_text += “\nI Ching Hexagram (bottom to top):\n”
    for line in i_ching_lines:
        output_text += f” – {line}\n”
    output_text += f”\nHexagram #{hex_num}: {hex_name}\n”
    output_text += f”\nDays since Feb 2, 1969: {days} days”

    output.delete(“1.0”, tk.END)
    output.insert(tk.END, output_text)
    cast_all.result_text = output_text

def share_result():
    try:
        root.clipboard_clear()
        root.clipboard_append(cast_all.result_text)
        root.update()
        status_label.config(text=”Copied to clipboard!”)
    except:
        status_label.config(text=”Copy failed”)

# GUI setup (night mode)
root = tk.Tk()
root.title(“Runes & I Ching”)
root.configure(bg=”#1a1a1a”)
root.geometry(“380×640”)

title = tk.Label(root, text=”Rune & I Ching Caster”, font=(“Helvetica”, 16, “bold”), bg=”#1a1a1a”, fg=”white”)
title.pack(pady=10)

cast_button = tk.Button(root, text=”Cast Runes + I Ching”, command=cast_all, font=(“Helvetica”, 13),
                        bg=”#333″, fg=”white”)
cast_button.pack(pady=5)

share_button = tk.Button(root, text=”Share Results”, command=share_result, font=(“Helvetica”, 13),
                         bg=”#555″, fg=”white”)
share_button.pack(pady=5)

output = tk.Text(root, height=26, width=44, font=(“Courier”, 10), wrap=”word”,
                 bg=”#121212″, fg=”#dddddd”, insertbackground=”white”)
output.pack(padx=10, pady=10)

status_label = tk.Label(root, text=””, font=(“Helvetica”, 10), bg=”#1a1a1a”, fg=”#00cc99″)
status_label.pack()

cast_all.result_text = “”

root.mainloop()

Day 20,624

Testing more python playthings , daily casts

Runes Drawn:
1. Othala (reversed) – Blocked or inverted: Heritage, inheritance
2. Ingwaz – Fertility, potential
3. Tiwaz – Justice, leadership

I Ching Hexagram (bottom to top):
– Young Yin (8)
– Young Yang (7)
– Young Yang (7)
– Young Yin (8)
– Old Yin (6) – changing to Yang
– Old Yang (9) – changing to Yin

Hexagram #18: Work on the Decayed

Speaking of Thundarr on a recent podcast I was listening to (https://podcasts.apple.com/us/podcast/swords-and-scrolls/id1740596089?i=1000718152383), it seems there is about a 4% of that one asteroid hitting the moon

https://science.nasa.gov/blogs/planetary-defense/2025/04/02/nasa-update-on-the-size-estimate-and-lunar-impact-probability-of-asteroid-2024-yr4/#:~:text=Experts%20at%20NASA’s%20Center%20for,not%20alter%20the%20Moon’s%20orbit.

Theoretically big enough to create a mile wide crater and raise enough dust to upset some of our satellites for a bit. No word if it will split in half and usher in a new world of savagery, super-science, and sorcery.

Watched midway through the second season of Poker Face. I really liked season one, but two is kind of sucking for me right now. Maybe I’m in a bad mood, or maybe it just isn’t good this season?

I love 70s detective shows like Columbo, Rockford, etc., and it had that vibe with a modern sensibility in season one. Season two feels like it dropped the ball.

They need to get a clue

Day 20,623

Current reads in public domain – Clark Ashton Smith – http://www.eldritchdark.com/


If you ever feel imposter syndrome, just know there’s an FBI forensics expert out there who doctored the Epstein footage and somehow has no idea what Metadata is.

The only positive thing to come from Trump’s rise to power for me is the realization that there is literally nothing, not a singular position on this planet, that I am not qualified for.


Written by my friend CR, who has a farm with horses:

I say this with the greatest sincerity.
I enjoy my daily trips to the manure pile.
It’s an earthy mound of wonders. Full of life and surprises.
What will I find today?
An entire colony of faerie mushroom?
Colorful beetles?
A swarm of swallowtail butterflies?
A copperhead?
A sleepy fawn?
Turkey feathers?
Honestly, if all piles of poo were this diverse and productive, the world would be a better place.


https://photos.app.goo.gl/EpMrYAMSXT3vdvHc6

Day 20,622

While I like all the Superman logo variants, this is the one I first discovered back in the 70s, and is still what I think of rather than the current movie Alex Ross “slash” or golden age “police shield.”

I like the S as kind of bold, condensed, with a distinct top serif and a bulb at the end.

Hero system die roller in python

import random

def roll_d6(n=1):
    return [random.randint(1, 6) for _ in range(n)]

def knockback_roll(modifier=0):
    knockback = sum(roll_d6(2)) – modifier
    knockback = max(knockback, 0)
    print(f”Knockback Roll (2d6 – {modifier}): {knockback} = {knockback * 2} meters\n”)
    return knockback

def normal_damage_dice(n, show_knockback=False):
    rolls = roll_d6(n)
    stun = sum(rolls)
    body = sum(1 if r == 1 else 2 if r in [2, 3, 4, 5] else 3 for r in rolls)
    print(f”[Normal Damage] Rolled: {rolls}”)
    print(f”STUN: {stun} | BODY: {body}”)
    if show_knockback:
        knockback_roll()
    print()
    return rolls, stun, body

def killing_damage_dice(n, show_knockback=False):
    rolls = roll_d6(n)
    body = sum(rolls)

    hit_location_roll = roll_d6(3)
    total = sum(hit_location_roll)
    if total <= 3:
        multiplier = 1
    elif total <= 6:
        multiplier = 2
    elif total <= 8:
        multiplier = 3
    elif total <= 11:
        multiplier = 4
    else:
        multiplier = 5

    stun = body * multiplier
    print(f”[Killing Damage] Rolled: {rolls}”)
    print(f”BODY: {body} | Hit Location Roll: {hit_location_roll} (x{multiplier}) | STUN: {stun}”)
    if show_knockback:
        knockback_roll()
    print()
    return rolls, body, stun

def skill_roll(target_number):
    roll = sum(roll_d6(3))
    success = roll <= target_number
    print(f”\n[Skill Roll] Roll: {roll} vs Target: {target_number} –> {‘Success!’ if success else ‘Failure.’}\n”)
    return roll, success

def main():
    print(“=== HERO SYSTEM DICE ROLLER ===”)
    while True:
        print(“\nChoose a roll type:”)
        print(“1. Normal Damage”)
        print(“2. Killing Damage”)
        print(“3. Skill Roll”)
        print(“4. Quit”)

        choice = input(“Enter your choice (1-4): “).strip()

        if choice in [‘1’, ‘2’]:
            num_dice = int(input(“How many dice per roll? “))
            num_sets = int(input(“How many sets to roll? “))
            use_knockback = input(“Include knockback? (y/n): “).strip().lower() == ‘y’
            kb_mod = 0
            if use_knockback:
                try:
                    kb_mod = int(input(“Knockback modifier (usually 0): “))
                except:
                    print(“Invalid modifier, defaulting to 0.”)

            for i in range(num_sets):
                print(f”\n— Set {i+1} —“)
                if choice == ‘1’:
                    normal_damage_dice(num_dice, show_knockback=use_knockback)
                else:
                    killing_damage_dice(num_dice, show_knockback=use_knockback)

        elif choice == ‘3’:
            target = int(input(“Enter skill roll target number: “))
            skill_roll(target)

        elif choice == ‘4’:
            print(“Goodbye!”)
            break
        else:
            print(“Invalid option. Please choose 1-4.”)

if __name__ == “__main__”:
    main()