Friday, July 18, 2025

Using AI to retrieve genre and synopsis from book titles

I have several thousand epub files. They are named in such a way that there is usually the author and title. I can use the epub-metadata library in python to get the title. I’d like to be able to use AI and google to get the genre and synopsys. I have the Google One Pro edition which gives me the Gemini Pro but you could also use it’s free version. You need to go to the Google AIStudio to get your API key. Create an environment variable GOOGLE_API_KEY with your key and the genai library will automatically find it. Otherwise you can pass the API key directly when you create the instance of the client. See Using Gemini API keys for examples. I then created a tiny python script as a proof of concept.

Title: the emperors new mind

('Genre: Science, Physics, Mathematics, Computer Science, Philosophy of Mind, ' 'Artificial Intelligence\n' 'Synopsys: Roger Penrose, a renowned physicist and mathematician, presents a ' 'controversial argument that human consciousness cannot be fully explained by ' 'classical computation or algorithms, directly challenging the foundations of ' "'strong AI.' Drawing upon concepts from quantum mechanics, general " "relativity, and Gödel's incompleteness theorems, he proposes that " 'non-computable processes are essential to understanding the mind, suggesting ' 'a deeper connection between consciousness and the fundamental laws of ' 'physics.')

"""
Google Books API Integration Script

This script uses Google's Gemini AI API to retrieve genre and synopsis information
for books based on their titles. It constructs a query using the book title and
the Google Books URL format, then uses the Gemini AI model to generate a response
with genre and synopsis information.

Requirements:
- Google Gemini API key set as environment variable 'GEMINI_API_KEY'
- google-generativeai package installed

Usage:
    python test_google_book_api.py
    (The script will prompt for a book title)
"""

import pprint  # For pretty-printing the API response
from google import genai  # Google's Generative AI library

# The client gets the API key from the environment variable `GEMINI_API_KEY`.
# Google Books URL format: https://www.google.ca/books/edition/title


def aibook(title):
    """
    Query the Gemini AI model for book genre and synopsis information.
    
    This function creates a Gemini AI client, constructs a prompt with the book title
    and desired output format, then returns the generated text response.
    
    Args:
        title (str): The title of the book to query
        
    Returns:
        str: The formatted response text containing genre and synopsis information
        
    Example output format:
        Genre: Fiction, Science Fiction, Dystopian
        Synopsis: A story about...
    """
    # Initialize the Gemini AI client
    client = genai.Client()
    
    # Generate content using the Gemini model with a formatted prompt
    response = client.models.generate_content(
        model="gemini-2.5-flash",  # Using the Gemini 2.5 Flash model for fast responses
        contents=f"""
        book url https://www.google.ca/books/edition/{title}/
        provide the genre and synopsis of the book
        use the format 
        line 1 Genre: genre1, genre2, etc
        line 2 Synopsys: the synopsys     
        """
    )
    
    # Return the text portion of the response
    return response.text


# Execute only if run as a script, not when imported as a module
if __name__ == "__main__":
    # Prompt the user for a book title, pass it to the aibook function,
    # and pretty-print the results
    pprint.pp(aibook(input('Title: ')))

Saturday, July 5, 2025

You Are Not Expected to Understand This - How 26 Lines of Code Changed the World

This collection of texts explores the **profound impact of code and software on various aspects of society**, from its early conceptualisation to modern-day applications. It discusses how **human decisions, biases, and ingenious solutions are embedded within code**, influencing everything from space exploration and the internet's structure to social interactions and public safety. The sources examine **pivotal moments in computing history**, such as the development of programming languages like BASIC and COBOL, the invention of email, and the rise of digital gaming. Furthermore, they highlight **critical challenges like software vulnerabilities and ethical dilemmas**, including the unintended consequences of algorithms in policing and advertising, and the ongoing struggle for digital privacy and inclusivity. Ultimately, the compilation underscores that **code is not merely technical but a deeply human endeavour** with far-reaching societal implications.

Saturday, June 28, 2025

Raspberry Pi Weather Clock

 I have a 2 line by 16 character LCD display with a I2C interface. I wanted to use it as a clock and date display which also could display the current weather.


Date and Time display
Date and Time Display


Weather Display
Weather Display
I am using a raspberry pi 5 to run a python script to drive the display using the GPIO pins

Rapsberry Pi 5 clock/weather


You will need an API key to open weather openweatherapi. Put your api key in an .env file as openweathermapapikey=yourkey. The python script uses the dotenv library to read this and use your API key. This is a free service with usage limitations. You will need to change the parameters to the open weather API to use you city and units.

        params = {
            "q": "Etobicoke,Ontario,CA",
            "units": "metric",  # For Celsius
            "appid": OPENWEATHERMAPAPIKEY  # API key
        }

#!/usr/bin/env python3
"""
lcd_weatherclock.py - A program that displays a clock on an LCD screen
and shows weather information for 10 seconds when a button is pressed.
"""

from LCD import LCD
import datetime
import time
import requests
import os
from dotenv import load_dotenv
from gpiozero import Button
import threading

# Load environment variables from .env file
load_dotenv()

# Initialize LCD
lcd = LCD(2, 0x27, True)
lcd.clear()

# Initialize button with debounce
button = Button(21, pull_up=True, bounce_time=0.2)  # 200ms debounce time

# Global variables
display_mode = "clock"  # Can be "clock" or "weather"
weather_timer = None

def get_etobicoke_weather():
    """
    Get current weather for Etobicoke, Ontario, Canada using OpenWeatherMap API
    """
    try:
        # OpenWeatherMap API endpoint for current weather
        url = "https://api.openweathermap.org/data/2.5/weather"

        # Get APP ID for weather api
        OPENWEATHERMAPAPIKEY = os.getenv("openweathermapapikey")
        # Parameters for Etobicoke, Ontario, Canada
        params = {
            "q": "Etobicoke,Ontario,CA",
            "units": "metric",  # For Celsius
            "appid": OPENWEATHERMAPAPIKEY  # API key
        }

        # Make the API request
        response = requests.get(url, params=params)

        # Check if the request was successful
        if response.status_code == 200:
            # Parse the JSON response
            weather_data = response.json()

            # Extract relevant information
            temperature = weather_data["main"]["temp"]
            condition = weather_data["weather"][0]["main"]
            humidity = weather_data["main"]["humidity"]

            return {
                "temperature": temperature,
                "condition": condition,
                "humidity": humidity
            }
        else:
            return {"error": f"API Error: {response.status_code}"}

    except Exception as e:
        return {"error": f"Error: {str(e)}"}

def display_weather(lcd):
    """
    Display weather data on the LCD
    """
    global display_mode
    
    # Set display mode to weather
    display_mode = "weather"
    
    # Show loading message
    lcd.clear()
    lcd.message("Weather...")
    
    # Get weather data
    weather_data = get_etobicoke_weather()
    
    lcd.clear()
    if "error" in weather_data:
        lcd.message("Weather Error")
        lcd.message(weather_data["error"][:16], 2)  # Truncate to fit LCD width
    else:
        # Format and display weather information
        temp_str = f"Temp: {weather_data['temperature']:.1f}C"
        cond_str = f"{weather_data['condition']} {weather_data['humidity']}%"

        lcd.message(temp_str)
        lcd.message(cond_str, 2)
    
    # Set a timer to switch back to clock after 10 seconds
    global weather_timer
    if weather_timer:
        weather_timer.cancel()
    weather_timer = threading.Timer(10.0, switch_to_clock)
    weather_timer.start()

def switch_to_clock():
    """
    Switch display back to clock mode
    """
    global display_mode
    display_mode = "clock"
    # The main loop will update the display on the next iteration

def display_clock(lcd, force_update=False):
    """
    Display clock on the LCD
    """
    now = datetime.datetime.now()
    currenttime = now.strftime("%H:%M:%S")
    currentdate = now.strftime("%d-%m-%Y")
    
    # Only update if time/date changed or force update is requested
    if force_update or currenttime != display_clock.lasttime or currentdate != display_clock.lastdate:
        lcd.clear()
        lcd.message('%02d:%02d:%02d' % (now.hour, now.minute, now.second), 1)
        lcd.message('%02d-%02d-%04d' % (now.day, now.month, now.year), 2)
        display_clock.lasttime = currenttime
        display_clock.lastdate = currentdate

# Initialize static variables for display_clock function
display_clock.lasttime = ''
display_clock.lastdate = ''

def button_pressed():
    """Function called when button is pressed"""
    global display_mode
    if display_mode == "clock":
        display_weather(lcd)

# Assign callback function to button press event
button.when_pressed = button_pressed

# Display welcome message
lcd.message("Weather Clock")
lcd.message("Starting...", 2)
time.sleep(2)
lcd.clear()

# Main loop
try:
    while True:
        if display_mode == "clock":
            display_clock(lcd)
        time.sleep(0.1)
except KeyboardInterrupt:
    # Clean up on exit
    if weather_timer:
        weather_timer.cancel()
    lcd.clear()
    print("\nExiting program")





Thursday, April 17, 2025

Vegetative Electron Microscopy

 In episode 64 of the AI Inside podcast, titled "Vegetative Electron Microscopy Doesn't Exist", Jason and Jeff discuss the  hallucination of "Vegetative Electron Microscopy" by leading AI tools.

I decided to see what the latest Gemini deep research 2.5 pro thinks it is.

I asked it to explain the meaning of Vegetative Electron Microscopy.

I copied the result to a Google Doc

Scroll down to the conclusion and the first paragraph states,

The investigation undertaken in this report confirms that the phrase "Vegetative Electron Microscopy" is not a standard, recognised term within the scientific field of electron microscopy.1 Its appearance in the scientific literature is anomalous and has been linked to several potential sources, including technical errors in digital text processing (AI/OCR errors), mistranslations from other languages (specifically Persian), or its use as a marker or artifact associated with fraudulent publications generated by paper mills.1 The fact that the phrase has been explicitly corrected to "scanning electron microscopy" in at least one publication further underscores its erroneous nature.

Monday, March 17, 2025

GIMP 3.0 Released

 After 7 years, the new version, 3.0, of GIMP (GNU Image Manipulation Program) has been released.


Death Is Not Final - The Debate

 The Open To Debate site debated the statement "Death is not finale". The moderator-in-chief John Donvan does his usual great moderator job.

For the statement is Eben Alexander, Neurosurgeon, Author of ‘Proof of Heaven’ and Raymond Moody, Medical Doctor, Author of ‘Life After Life’.

Against is Sean Carroll, Physicist & writer and Steven Novella, Academic Neurologist at the Yale School of Medicine.

From the web site "If consciousness is just the workings of neurons and synapses, how do we explain the phenomenon of near-death experience? By some accounts, about 3% of the U.S. population has had one: an out-of-body experience often characterized by remarkable visions and feelings of peace and joy, all while the physical body is close to death. To skeptics, there are more plausible, natural explanations, like oxygen deprivation. Is the prospect of an existence after death “real” and provable by science, or a construct of wishful thinking about our own mortality?"

Amy Webb Launches 2025 Emerging Tech Trend Report | SXSW LIVE

Amy Webb, a popular American futurist and author, who appears regularly on the Twit.tv network, appeared on the South by South West 2025 event. Her presentation is available on Youtube.

Amy Webb Launches 2025 Emerging Tech Trend Report | SXSW LIVE

Look for the 2025 forecast from the Future Today Institute at https://ftsg.com/.