Where could “AI” be actually helpful?

I’m not a big fan of AI. I don’t believe that machines should be thinking for people.
But - I can see a very useful application of AI, or at least limited speech parsing. I have a Nikon Z8 camera, and there are way too many settings for me to remember. It would be really helpful If I could just say to the camera “self timer mode, 10 seconds,” rather than search through the endless menus on the little LCD.

You don’t need AI for that – Google Assistant could carry out simple tasks like that for years now.

Anyway, AI is a fantastic programmer, really top notch, and can improve programming productivity probably tenfold.

Sifting through endless amounts of data. Finding answers hidden in millions of books and scientific papers, it is good for that.

Yeah, but it needs to be built into the camera.

But something like Google Assist is easier to build into a camera than an LLM AI. You need hundreds of gigs for an LLM. Which is within reach for consumer devices, but would add a heck of a lot to the price of something like a camera.

Onboard assistants have always been terrible. If I were the camera maker, and I wanted to include that, I would connect it to your phone using Bluetooth and use your phone’s connection to phone home.

You’re not going to get onboard AI on a camera anytime soon, unless it’s talking to some backend somewhere, somehow.

I’m always fascinated by videos of produce sorting machines (random video). Those are made better by AI.

I’m sure manual sorter jobs are going away but I don’t know that anyone was clamoring for those positions anyway.

Ehhh, really, not so much. It’s great at spitting out code. I have still yet to see a LLM that is anything but hot garbage at troubleshooting a problem. If I delve into the code and tell it what it needs to fix, it’s pretty good. Left to their own devices they tend to come up with solutions such as “Function takes too long to run? Let’s just put a silent timeout exit on it that no one asked for and never mention it!”

Are we talking about an actual intelligence, as opposed to Chat GPT, Claude, etc.? Those don’t seem to have any actual intelligence, and I doubt they’ll ever by useful for answering the big questions. But if we mean something that’s actually intelligent, then the obvious answer would be that they could provide some answers to, or at the very least alternative ways of thinking about (that no human so far has considered) those Big Questions. Explaining the origin of the Big Bang, AKA why is there something rather than nothing. Unifying quantum mechanics with general relativity, AKA what is the fundamental nature of the universe. Explaining consciousness and the associated What Happens After We Die. And so on.

AI is useful in nearly countless situations. As the others mentioned, one of its perks is taking massive data and summarizing/distilling it instantly. You can feed a 4,000-word article into it and say “please summarize this in 200 words in a single paragraph.”

To fully list out all the benefits or uses of AI would be so many, you could exhaust a Dope thread entirely in discussion of it.

Heh, but would you trust it to be accurate? In my experience, I would not.

My experience could not be more different – I ask it to write something for me and most of the time it’s right. If there are error messages or mistakes, I tell it what the messages and mistakes are, it fixes the code.

It wrote a whole Android app for me, beginning to end, just copying from Claude into the Android IDE. It wrote a whole Excel add-in for me, that time mostly just copying in.

OK, check out Claude Code Workflows:

This guy used it to have Claude make a real-time strategy game:

Here’s the game:

I went to Gemini and asked it to make a Minesweeper game, but using 70s colors, that can run in a browser. The first attempt had an error – right-clicking worked, but left-clicking caused it to hang up. It found the source of the error (it used the wrong variable name in a loop, creating an infinite loop), and now it works. Here’s the code – paste it to a file, save it as html, and open in a browser:

Code
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Groovy Sweeper - 1970s Minesweeper</title>
    <style>
        :root {
            --bg-color: #f7f2e7;       /* Warm Retro Cream */
            --text-color: #4e3629;     /* Deep Chocolate Brown */
            --primary-orange: #bd5319; /* Burnt Orange */
            --harvest-gold: #d9742b;   /* Bright Shaded Orange */
            --vintage-gold: #e6b84a;   /* Classic 70s Gold */
            --tile-unrevealed: #bd5319; 
            --tile-revealed: #e6dfcb;   /* Soft Sand Tan */
            --avocado-green: #607d3b;  /* Shag Carpet Green */
        }

        body {
            font-family: 'Courier New', Courier, monospace;
            background-color: var(--bg-color);
            color: var(--text-color);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            min-height: 100vh;
            margin: 0;
            padding: 20px;
        }

        h1 {
            font-size: 2.8rem;
            margin-bottom: 2px;
            color: var(--primary-orange);
            text-shadow: 2px 2px var(--vintage-gold);
            font-weight: bold;
            text-align: center;
            letter-spacing: 2px;
        }

        .subtitle {
            font-style: italic;
            margin-bottom: 25px;
            font-weight: bold;
            font-size: 1.1rem;
        }

        .dashboard {
            display: flex;
            gap: 25px;
            margin-bottom: 25px;
            font-size: 1.2rem;
            font-weight: bold;
            background: #ebdcb9;
            padding: 12px 24px;
            border: 3px solid var(--text-color);
            border-radius: 2px;
            box-shadow: 5px 5px 0px var(--text-color);
            align-items: center;
        }

        .btn {
            background-color: var(--avocado-green);
            color: white;
            border: 2px solid var(--text-color);
            padding: 6px 16px;
            font-family: inherit;
            font-weight: bold;
            cursor: pointer;
            box-shadow: 2px 2px 0px var(--text-color);
        }

        .btn:active {
            transform: translate(2px, 2px);
            box-shadow: 0px 0px 0px var(--text-color);
        }

        #board {
            display: grid;
            grid-template-columns: repeat(9, 42px);
            grid-template-rows: repeat(9, 42px);
            gap: 3px;
            background-color: var(--text-color);
            padding: 6px;
            border: 4px solid var(--text-color);
            box-shadow: 8px 8px 0px var(--text-color);
        }

        .tile {
            width: 42px;
            height: 42px;
            background-color: var(--tile-unrevealed);
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.4rem;
            font-weight: bold;
            cursor: pointer;
            user-select: none;
            border-top: 2px solid rgba(255,255,255,0.2);
            border-left: 2px solid rgba(255,255,255,0.2);
            border-right: 2px solid rgba(0,0,0,0.2);
            border-bottom: 2px solid rgba(0,0,0,0.2);
            box-sizing: border-box;
        }

        .tile:hover {
            background-color: var(--harvest-gold);
        }

        .tile.revealed {
            background-color: var(--tile-revealed);
            border: 1px solid rgba(78, 54, 41, 0.2);
            cursor: default;
        }

        .tile.mine {
            background-color: #a13d2d;
        }

        .tile.flagged {
            background-color: var(--vintage-gold);
        }

        /* Funky retro numbers */
        .n-1 { color: #1c5270; }
        .n-2 { color: #2e6129; }
        .n-3 { color: #a13d2d; }
        .n-4 { color: #512da8; }
        .n-5 { color: #8d6e63; }
        .n-6 { color: #00796b; }
        .n-7 { color: #212121; }
        .n-8 { color: #757575; }

        .status-message {
            margin-top: 30px;
            font-size: 1.6rem;
            font-weight: bold;
            min-height: 2.5rem;
            text-align: center;
        }
    </style>
</head>
<body>

    <h1>GROOVY SWEEPER</h1>
    <div class="subtitle">Can you dig it?</div>

    <div class="dashboard">
        <div>Mines: <span id="mine-count">10</span></div>
        <div>Time: <span id="timer">0</span>s</div>
        <button class="btn" id="reset-btn">New Game</button>
    </div>

    <div id="board"></div>

    <div class="status-message" id="status"></div>

    <script>
        const ROWS = 9;
        const COLS = 9;
        const MINES = 10;

        let board = [];
        let gameOver = false;
        let timerInterval = null;
        let timeElapsed = 0;
        let firstClick = true;

        const boardElement = document.getElementById('board');
        const mineCountElement = document.getElementById('mine-count');
        const timerElement = document.getElementById('timer');
        const statusElement = document.getElementById('status');
        const resetBtn = document.getElementById('reset-btn');

        function initGame() {
            boardElement.innerHTML = '';
            statusElement.innerText = '';
            gameOver = false;
            firstClick = true;
            timeElapsed = 0;
            timerElement.innerText = '0';
            clearInterval(timerInterval);
            mineCountElement.innerText = MINES;
            
            board = [];
            for (let r = 0; r < ROWS; r++) {
                board[r] = [];
                for (let c = 0; c < COLS; c++) {
                    board[r][c] = {
                        r: r,
                        c: c,
                        isMine: false,
                        isRevealed: false,
                        isFlagged: false,
                        neighborMines: 0
                    };
                    
                    const tileEl = document.createElement('div');
                    tileEl.classList.add('tile');
                    tileEl.dataset.row = r;
                    tileEl.dataset.col = c;
                    
                    // Left click to dig
                    tileEl.addEventListener('click', () => handleLeftClick(r, c));
                    // Right click to flag
                    tileEl.addEventListener('contextmenu', (e) => {
                        e.preventDefault();
                        handleRightClick(r, c);
                    });
                    
                    boardElement.appendChild(tileEl);
                    board[r][c].element = tileEl;
                }
            }
        }

        function startTimer() {
            timerInterval = setInterval(() => {
                timeElapsed++;
                timerElement.innerText = timeElapsed;
            }, 1000);
        }

        function placeMines(exceptR, exceptC) {
            let minesPlaced = 0;
            while (minesPlaced < MINES) {
                const r = Math.floor(Math.random() * ROWS);
                const c = Math.floor(Math.random() * COLS);
                
                // Keep the first click and its perimeter completely safe
                if (!board[r][c].isMine && (Math.abs(r - exceptR) > 1 || Math.abs(c - exceptC) > 1)) {
                    board[r][c].isMine = true;
                    minesPlaced++;
                }
            }

            // Calculate numbers for neighboring mines
            for (let r = 0; r < ROWS; r++) {
                for (let c = 0; c < COLS; c++) {
                    if (board[r][c].isMine) continue;
                    let count = 0;
                    for (let dr = -1; dr <= 1; dr++) {
                        for (let dc = -1; dc <= 1; dc++) {
                            const nr = r + dr;
                            const nc = c + dc;
                            if (nr >= 0 && nr < ROWS && nc >= 0 && nc < COLS && board[nr][nc].isMine) {
                                count++;
                            }
                        }
                    }
                    board[r][c].neighborMines = count;
                }
            }
        }

        function handleLeftClick(r, c) {
            if (gameOver || board[r][c].isFlagged || board[r][c].isRevealed) return;

            if (firstClick) {
                firstClick = false;
                placeMines(r, c);
                startTimer();
            }

            revealTile(r, c);
            checkWinCondition();
        }

        function handleRightClick(r, c) {
            if (gameOver || board[r][c].isRevealed) return;

            const tile = board[r][c];
            tile.isFlagged = !tile.isFlagged;
            
            if (tile.isFlagged) {
                tile.element.classList.add('flagged');
                tile.element.innerText = '✌️'; 
            } else {
                tile.element.classList.remove('flagged');
                tile.element.innerText = '';
            }

            const flaggedCount = board.flat().filter(t => t.isFlagged).length;
            mineCountElement.innerText = Math.max(0, MINES - flaggedCount);
        }

        function revealTile(r, c) {
            if (r < 0 || r >= ROWS || c < 0 || c >= COLS) return;
            const tile = board[r][c];
            if (tile.isRevealed || tile.isFlagged) return;

            tile.isRevealed = true;
            tile.element.classList.add('revealed');

            if (tile.isMine) {
                explode();
                return;
            }

            if (tile.neighborMines > 0) {
                tile.element.innerText = tile.neighborMines;
                tile.element.classList.add(`n-${tile.neighborMines}`);
            } else {
                // Cascade open adjacent blank cells
                for (let dr = -1; dr <= 1; dr++) {
                    for (let dc = -1; dc <= 1; dc++) {
                        revealTile(r + dr, c + dc);
                    }
                }
            }
        }

        function explode() {
            gameOver = true;
            clearInterval(timerInterval);
            statusElement.innerText = "Bummer! Game over, man. 💥";
            statusElement.style.color = "#a13d2d";

            for (let r = 0; r < ROWS; r++) {
                for (let c = 0; c < COLS; c++) {
                    const tile = board[r][c];
                    if (tile.isMine) {
                        tile.element.classList.add('mine');
                        tile.element.innerText = '💣';
                    }
                }
            }
        }

        function checkWinCondition() {
            // Check if every tile on the board is either a mine or has been revealed
            const won = board.flat().every(tile => tile.isMine || tile.isRevealed);

            if (won && !gameOver) {
                gameOver = true;
                clearInterval(timerInterval);
                statusElement.innerText = "Groovy! You cleared the field! 🕺✨";
                statusElement.style.color = "var(--avocado-green)";
            }
        }

        resetBtn.addEventListener('click', initGame);
        initGame();
    </script>
</body>
</html>

First prompt:
“I want you to make a Minesweeper game that will work in a browser, so I guess in HTML and Javascript. The color scheme should be reminiscent of the 70s”

Second prompt:
“It doesn’t seem to work. Right-click puts down the peace sign, but left click doesn’t actually reveal a square and the page hangs up”

Reply from Gemini:
" Ah, man, what a total bummer! You are completely right, and that freeze is 100% on me.

If you look closely at the checkWinCondition function I gave you, I accidentally wrote an infinite loop. In the inner loop, I typed r++ instead of c++—so poor c never reached the end, the browser got stuck spinning its wheels forever, and the whole page hung up. Talk about a hidden mine.

Here is the clean, fully repaired code. I completely stripped out that broken loop and streamlined the win-check logic so it runs perfectly smooth."

That’s actually something it is extremely good at.

I find it to be extremely useful as a search-engine-on-steroids. Like you can tell it to find you the top ten based on your criteria, and explain its reasoning. And you can tell it to ask you clarification questions if it needs to.

As far as your camera goes, I’d just configure a button to be the 10 second self timer. Or I’d imagine you have configurable modes like my Canon EOS R does (C1, C2), and you can probably set one of those to be your “self timer mode”. I can’t imagine a more modern Nikon doesn’t have similar functionality. And I’ll also bet Nikon’s got a remote app that connects to your phone via Bluetooth as well, and you can probably do it from there.

“Hello, this is CableInternet’s AI, and this line is for people having technical problems with their internet or their television service. What are you calling about today?”

“Hi! I’m unable to connect to any outside resources but all my devices are getting valid IP addresses, I mean not the 169 dot whatever self-assigned ones but the kind that the internet router gives them.”

“Is this only for your devices such as computers, phones, and tablets that browse the internet, or are you also unable to receive a television signal?”

“We have television, but the television box is plugged into a different cable modem so I’m not sure that’s relevant?”

“Let’s see…our records show that you have two cable modems, one of them supplied by us, which your television module is using, and the other is a third party cable modem that receives our signal for internet service. That matches what I see on the signal tracking dashboard…can you verify that your third party cable modem is an ARRIS model xyz-123?”

Yes, that’s correct"

“I am able to ping that device, so it is making connection to the wide area network. Can you look at the display and tell me which lights are lit up and whether any of them is blinking?”

“The first two lights are on solid but the next two are blinking”

“That’s consistent with a node connection problem linking the wide area network to the signal trunk. Please hold on a moment while I check… yes, there are multiple similar reports in your region. I have submitted a ticket. If your service is not restored in an hour please call back and give this case number: ABC 123 ZYXYZ”.

versus

“Hello, you have reached CableInternet. Please press 1 if you are having a technical issue”

beep

“Please press 1 if you have no internet. Please press 2 if you have no television signal.”

beep

“Please press 1 if your device is a computer. Please press 2 if your device is a cell phone or tablet”.

beep

etc

Heh, that’s half of the problem. When the problem with the software doesn’t actually generate an error or cause a crash, it just returns incomplete data or is incorrect in some way, the LLM really does seem to struggle to figure out the issue. I’ve run into a similar situation with both Claude Code and Codex several times. The software it’s written does not work right, but doesn’t generate an error. Hours spent trying to get it to figure out a solution are a waste of time, as it is hallucination city. The only thing that works at that point is going through the code and diagnosing the problem myself.

I’m not sure LLM models really qualify as ‘AI’ in the strong general sense.

But I do find them useful for a couple of things.

First, they are sometimes capable of identifying a half-remembered book or film from very limited information. Something which might have take a lot of googling 10 years ago, and might only have been possible by human experts.

Second, as a writer, once I have them trained to my story world and environment, they occasionally come up with small real-world ‘grounding’ details, often sensory, that I wouldn’t have thought of myself. Of course, I check these and use them judiciously.

They’re rubbish at music so far though. Suno can create something slick and superficially professional sounding: but it has no soul.

Fellow Z8 owner. Yeah, I would love something like that built into the camera! Last year I had to get my Z8 repaired, and when it came back from Nikon, it was overwritten with someone else’s custom settings (some photographer from Phoenix, as his author info was in there.) And stupidly I did not save my settings to a card before sending it out to Nikon. ChatGPT helped me a lot in figuring out where certain custom settings were, because I sure as hell didn’t remember, and I didn’t feel like sifting through an online manual (why the hell couldn’t this thing come with a printed manual for as much as I paid for it!) And when my camera was acting unexpectedly, I could query it to tell me what custom setting might be causing it. I think by now I almost have it back to where I want it. :slight_smile: But it would have been so convenient to be able to talk to the camera to just do it.

The self-timer was just an example. There are hundreds of settings that are hidden in the menu tree. I’d like to be able to just tell the camera what I want to do.

/Kramer “ Why don’t you just tell me the name of the movie you just selected"