This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Artificial Intelligence

In-depth tutorials and guides on artificial intelligence topics

1. Available Guides

  • Better AI Usage - Comprehensive documentation on how to effectively use AI for learning and productivity

2. Getting Started

Select a guide from the sidebar to begin.

Articles in this section

TitleDescriptionUpdated
Optimize Dockerfiles for Speed and EfficiencyAI Skill for optimizing Dockerfiles, including best practices for reducing image size and improving build performance.2026-05-10 23:42:08 +0200 +0200
Crafting Effective AI Prompts for MongoDB OptimizationCraft precise AI prompts to optimize MongoDB: phased analysis, index tuning, and actionable query recommendations.2026-05-10 23:42:08 +0200 +0200
Better AI Usage for LearningComprehensive documentation on how to effectively use AI for learning and productivity2026-05-10 23:42:08 +0200 +0200

1 - Optimize Dockerfiles for Speed and Efficiency

AI Skill for optimizing Dockerfiles, including best practices for reducing image size and improving build performance.

This AI Docker Skill provides personalized recommendations for optimizing your Docker images and improving build performance using an AI Copilot Agent. It covers various aspects of Dockerfile optimization, including:

  • Using multi-stage builds to reduce image size
  • Choosing the right base image for your application
  • Minimizing the number of layers in your Dockerfile
  • Leveraging caching effectively to speed up builds
  • Implementing best practices for security and maintainability

Example of transforming a Dockerfile using the AI Docker Skill:

# Original Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build
CMD ["npm", "start"]

1. Q&A with AI

I asked AI using Docker Skill with Claude Sonnet 4.5 AI Model:

Here Q&A with AI:

Do you want a development stage for local development with hot-reloading and dev dependencies?

Yes - Include dev stage with hot-reload support

Should the Dockerfile include a test stage for running unit tests, integration tests, or pre-commit hooks?

Yes - Run tests during build

Do you want security scanning (Trivy, Snyk, etc.) integrated into the build process?

No - Skip security scanning

Should images be signed for verification (using Cosign, Notary, or Docker Content Trust)?

No - Skip image signing

What are the deployment environments? Local - Local development, Staging - Staging environment,

Production - Production environment

Are there specific base image requirements?

node:20-slim - Recommended: Debian-based minimal image

Do you want advanced image size optimization (adds complexity)?

NPM cache optimization - Disable npm cache

2. Resulting Dockerfile

Result: AI automatically generates the optimized Dockerfile based on the provided answers:

# =============================================================================
# Stage Diagram:
#
# base (node:20-slim)
# ├─> development (with hot-reload, dev dependencies)
# ├─> dependencies (production dependencies only)
# │     └─> build (compile application)
# │           └─> test (run tests, validation)
# │                 └─> production (minimal runtime image)
#
# =============================================================================

# =============================================================================
# Stage: base
# Purpose: Common base configuration for all stages
# =============================================================================
FROM node:20-slim AS base
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "xtrace", "-c"]

# Environment Variables - Build-time Configuration
# Description: Prevent interactive prompts during apt operations
# Required: Yes (for automated builds)
ARG DEBIAN_FRONTEND=noninteractive

# Environment Variables - Runtime Configuration
# Description: Node environment (development, staging, production)
# Default: production
# Example: development, staging, production
# Required: No
ENV NODE_ENV=production

# Description: Enable verbose logging for debugging
# Default: false
# Example: true, false
# Required: No
ENV DEBUG=false

# Description: Application port for the Node.js server
# Default: 3000
# Example: 3000, 8080
# Required: No
ENV PORT=3000

# Description: Prevent npm from creating package-lock updates
# Default: off
# Required: No
ENV NPM_CONFIG_UPDATE_NOTIFIER=off

# Description: Disable npm cache to reduce image size
# Default: false
# Example: true (for production), false (for dev)
# Required: No
ENV NPM_CONFIG_CACHE=/tmp/npm-cache

WORKDIR /app

# Install security updates and minimal system dependencies
# If you need an IMMUTABLE IMAGE, comment out the upgrade
RUN <<EOF
apt-get update
apt-get upgrade -y
apt-get install -y -q --no-install-recommends \
  'ca-certificates=20*' \
  'curl=7.*' \
  'tini=0.19.*'
apt-get autoremove -y
apt-get clean
rm -rf /var/lib/apt/lists/* /var/cache/apt/archives /tmp/* /var/tmp/* /usr/share/{doc,man,locale}/
EOF

# =============================================================================
# Stage: development
# Purpose: Development environment with hot-reload and dev tools
# =============================================================================
FROM base AS development
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "xtrace", "-c"]

ENV NODE_ENV=development
ENV NPM_CONFIG_CACHE=/home/node/.npm

# Copy dependency files for caching optimization
COPY --chown=node:node package*.json ./

# Install ALL dependencies (including devDependencies)
RUN <<EOF
npm ci
npm cache clean --force
EOF

# Copy source code
COPY --chown=node:node . .

USER node

EXPOSE 3000

# Health check for development
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Use nodemon or npm run dev for hot-reload (adjust based on your package.json)
CMD ["npm", "run", "dev"]

# =============================================================================
# Stage: dependencies
# Purpose: Install production dependencies only (optimized caching)
# =============================================================================
FROM base AS dependencies
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "xtrace", "-c"]

# Copy dependency files for caching optimization
COPY package*.json ./

# Install production dependencies only (no dev dependencies)
RUN <<EOF
npm ci --only=production --no-cache
npm cache clean --force
EOF

# =============================================================================
# Stage: build
# Purpose: Build the application from source
# =============================================================================
FROM base AS build
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "xtrace", "-c"]

# Copy dependency files for caching optimization
COPY package*.json ./

# Install ALL dependencies (including devDependencies for build)
RUN <<EOF
npm ci --no-cache
npm cache clean --force
EOF

# Copy source code
COPY . .

# Build the application
RUN <<EOF
npm run build
EOF

# =============================================================================
# Stage: test
# Purpose: Run tests to validate the build
# =============================================================================
FROM build AS test
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "xtrace", "-c"]

# Run tests (adjust command based on your package.json)
RUN <<EOF
npm run test
touch /tmp/tests-passed
EOF

# =============================================================================
# Stage: production
# Purpose: Minimal production runtime image
# =============================================================================
FROM base AS production
SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "xtrace", "-c"]

# Create non-root user with specific UID/GID for security
RUN <<EOF
groupadd -r -g 1001 appuser
useradd -r -u 1001 -g appuser -s /sbin/nologin -c "Application User" appuser
mkdir -p /app/logs /app/tmp
chown -R appuser:appuser /app
EOF

# Copy production dependencies from dependencies stage
COPY --from=dependencies --chown=appuser:appuser /app/node_modules ./node_modules

# Copy built application from build stage
COPY --from=build --chown=appuser:appuser /app/dist ./dist
COPY --from=build --chown=appuser:appuser /app/package*.json ./

# Copy test marker to ensure tests passed
COPY --from=test /tmp/tests-passed /tmp/tests-passed

# Switch to non-root user
USER appuser

# Document exposed port
EXPOSE 3000

# Health check for production
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
  CMD curl -f http://localhost:${PORT}/health || exit 1

# Use tini as init system for proper signal handling
ENTRYPOINT ["/usr/bin/tini", "--"]

# Start the application
CMD ["node", "dist/index.js"]

3. Review Comments

During the process, AI automatically generates a package.jso in order to be able to build the image and test it.

The resulting Dockerfile is optimized for both development and production environments, with separate stages for dependencies, build, testing, and production runtime. It incorporates best practices for image size reduction, caching optimization, security hardening, and maintainability.

But Never trust AI blindly - Always review the generated Dockerfile and test it thoroughly to ensure it meets your specific requirements and follows best practices for your application.

Anyway here my review comments about this generated Dockerfile:

  • The COPY --chown=node:node . . in development stage is not necessarily because most of the time we are mounting the source code in development.
  • USER node in development stage is hard to use because of the permissions issues when mounting volumes, we should use root user in development stage.
  • The stage inheritance is wrong while the dependency schema at the beginning of the Dockerfile has not been respected:
    • the build stage is inheriting from base and use npm ci in development mode
    • The production stage inherit from base but copy the node_modules from dependencies stage (it is why AI puts this wrong inheritance)
    • as only production stage need the dependencies, it is better to have the RUN npm ci –only=production in the production stage-

a clearer diagram could be:

# =============================================================================
# Stage Diagram:
#
# base (node:20-slim)
# ├─> development (with hot-reload, dev dependencies)
# ├─> dependencies (production dependencies only)
# ├─> build (compile application)
# │     └─> test (run tests, validation)
# └─> production (minimal runtime image)
# <-- depends on (dependencies, build, test)
#
# =============================================================================

4. Conclusion

OK I agree it is more complex to read but it is more optimized and secured that the original one.

Stay tuned as I will continuously improve this skill with new features and optimizations based on the latest Docker best practices and user feedback!

📢 What do you think about this generated Dockerfile? Do you have any 💡 feedbacks ? Let me know in the 💬 comments!

2 - Crafting Effective AI Prompts for MongoDB Optimization

Craft precise AI prompts to optimize MongoDB: phased analysis, index tuning, and actionable query recommendations.

1. Overview

This guide shares practical lessons from using AI to analyze and optimize MongoDB databases across multiple Python repositories. By following these techniques, you’ll learn how to craft prompts that produce accurate, actionable analysis instead of generic recommendations.

Key Takeaway: Precise, well-structured prompts dramatically improve the quality and usefulness of AI-generated database analysis.

2. Context

This guide is based on analyzing two interconnected Python repositories that share a single MongoDB database.

Repository Roles:

ComponentResponsibility
api_pythonDatabase schema, migrations, and Beanie ORM models (source of truth)
kafka-consumerConsuming Kafka events and updating MongoDB collections

Technology Used:

  • MongoDB for data storage
  • Beanie ORM for Python-MongoDB integration
  • Python as the programming language

3. The Challenge

Creating an effective prompt proved unexpectedly difficult. Initial attempts to fit all requirements into a single prompt resulted in timeouts and no output. This is a common problem when asking AI to handle large, complex analysis tasks in one go.

4. Phase 1: Testing a Comprehensive Prompt

The first approach was to create a single detailed prompt that would handle all analysis at once:

---
name: fc-optimize-mongodb
description: Analyze the MongoDB usage in the API and its Kafka Consumer, identify all the CRUD queries that
are made to MongoDB in both projects, and propose optimizations.
---
As a Senior specialist of documentDB and MongoDB optimization, you have been tasked to analyze the MongoDB usage
in the API and its Kafka Consumer. Your goal is to identify all the CRUD queries that are made to MongoDB in both
repositories, and propose optimizations.

**CRITICAL** Analyze all the files **ONLY** in the directories `api_python` and `kafka-consumer`.
But ignore files in `api_python/admin/database/migrations/`.

These 2 projects are separated but they use the same MongoDB database but with different Beanie models definitions.
`api_python` is the project that is responsible for the database schema and migrations.
While `kafka-consumer` is responsible for consuming the Kafka events and updating the MongoDB collections accordingly.
So consider `api_python` as source of truth.

You will analyze current MongoDB schema (api_python/admin/database/indexes/definition.py, api_python/odm/models.py).

**CRITICAL** Don't update source code, just analyze and generate a report in
`docs/ai/{date:YYYY-mm-dd}-mongodbAnalysis/mongodbAnalysis.md` where you will list all the CRUD queries that are made
to MongoDB (normally all the queries are done through Beanie ORM) in both projects.
**CRITICAL** Don't invent any query, just list the queries accurately as they are in the codebase.

When you will have the full view:
- indicate branch name and commit hash of each repositories.
- for each query write
  - the equivalent MongoDB query that could be done through mongosh
  - the file location and line where the query is done
  - the Beanie query that is done in the code
- global recommendations
  - List all the tables and indexes that are used
  - check if all the required indexes are present
  - propose missing indexes creation
  - propose indexes that should be removed
  - indicate as well when an index could be replaced by a lighter index
    - Compound Indexes
    - Partial Indexes
    - Sparse Indexes
    - Partial indexes with filter expressions
    - ...
  - Propose also optimizations to the queries themselves if you see any
  - Propose to improve the indexes with projections.
  - List inconsistencies in the kafka-consumer
  - **CRITICAL** take into consideration property order in the indexes.
  - Propose queries that could be done on production to analyze the query planner behavior and the index
    usage for the most critical queries.
  - for each suggestion propose code snippets of how the query or the index should be updated.
  - Propose schema improvements if you see any.
- if you see any other recommendations put them in another section
- generate a plantuml diagram of the current schema in `docs/ai/{date:YYYY-mm-dd}-mongodbAnalysis/mongodbSchema.puml`
  and another one with the proposed schema in `docs/ai/{date:YYYY-mm-dd}-mongodbAnalysis/mongodbProposedSchema.puml`
  where you will ignore obsolete tables.
- add at the start of the report a summary of the main findings and recommendations.

use askQuestions tool for any question.

if folder `kafka-consumer` doesn't exist use askQuestions to propose the user to create
a symlink using `ln -s ../kafka-consumer kafka-consumer`.

use askQuestions to ask if the user think about using updated branches before starting the analysis.

4.1. First Results and the Limits of Comprehensive Prompts

The first prompt produced a solid report and revealed 3 critical issues that weren’t previously known. This success led to adding more requirements for even deeper analysis. However, the expanded prompt failed with a timeout error—producing no output at all.

5. Phase 2: Why Comprehensive Prompts Fail

5.1. The Timeout Problem

Attempting to add schema consistency checks (validating that all fields updated in kafka-consumer exist in api_python models) caused a timeout with no output.

The fundamental issue: AI has a practical processing time limit of 10-15 minutes per request. Asking for complete analysis of multiple complex topics at once exceeds this limit. The solution is to break large tasks into smaller, manageable phases.

Task Decomposition Strategy:

Instead of: One comprehensive prompt covering everything

Try this: Multiple focused prompts in sequence

Break analysis into phases:

  1. Inventory (What exists?)
  2. Analysis (What’s suboptimal?)
  3. Planning (How to fix it?)
  4. Documentation (Summarize findings)

Each phase completes in 3-5 minutes instead of timeout.

6. Phase 3: Breaking Work Into Manageable Pieces

To solve the timeout problem, the solution split the large task into distinct phases, each with specific, limited objectives and intermediate checkpoints.

6.1. Planning the Phased Approach

Before redesigning, key decisions were made using interactive questions:

6.1.1. Decision 1: Execution Model

  • Approach: Single skill with manual phase progression
  • Rationale: User controls when each phase runs, can review results before continuing

6.1.2. Decision 2: Output Volume

  • Approach: Moderate detail (phase summaries with key findings)
  • Rationale: Balance between useful information and processing speed

6.1.3. Decision 3: Phase Duration

  • Approach: 3-5 minutes per phase
  • Rationale: Short enough to avoid timeouts, long enough for meaningful analysis

6.1.4. Decision 4: Analysis Focus

  • Priorities: Missing indexes, index optimization opportunities
  • De-prioritized: Schema consistency checks (can be added later)
  • Rationale: Address most critical performance issues first

6.2. Phase-Based Prompt Structure

The refined prompt introduces a phase parameter to guide execution:

### 6.3. Execution Workflow

The analysis is broken into **4 independent phases** (3-5 minutes each). Each phase:
- ✅ Checks for previous phase data in session memory
- 📊 Processes its specific scope
- 💾 Saves results to `/memories/session/mongodb-analysis-{phase}.json`
- 📝 Shows a summary of findings
- ➡️ Indicates next phase to run
**How to use:**
1. Run: `@workspace /optimize-mongodb` (or with `phase=1`)
2. Review phase summary
3. Continue: `@workspace /optimize-mongodb phase=2`
4. Repeat until Phase 4 generates the final report

**Recovery:** If interrupted, just restart from the last completed phase. All previous work is preserved in session memory.

And this part, which is included in the prompt to guide the AI through the execution of each phase:

## 7. Processing Workflow

**Follow this systematic approach :**

### 7.1. For Each Phase Execution:

1. **Phase Validation**
   - Determine which phase to run (from user input or default to 1)
   - Check for prerequisite phase data in /memories/session/
   - If missing prerequisites, show error + command to run

2. **Data Loading**
   - Load all prerequisite phase data from session memory
   - Validate JSON structure and completeness
   - Show brief recap of loaded data

3. **Phase Execution**
   - Execute phase-specific analysis (see phase details above)
   - Show progress indicators for long operations
   - Build phase output data structure

4. **Data Persistence**
   - Save phase results to `/memories/session/mongodb-analysis-phase{N}.json`
   - Validate saved data is complete
   - Show data save confirmation

5. **Summary Display**
   - Show phase completion message
   - Display key metrics and findings
  - Indicate next phase command

It’s important to note that the AI will not automatically run the next phase, but it will indicate to the user to run the next phase command. This way, the user has control over when to proceed to the next phase and can review the findings of each phase before moving on.

Finally, for my usage, I grouped phase 1 and phase 2 together and then phase 3 and phase 4 together. So I slightly changed the workflow above to this one:

...
+ **CRITICAL** Group phase 1 and phase 2 and then phase 3 and phase 4 together.
...
-   - Indicate next phase command
+   - If phase 1 or phase 3
+    - continue yourself with phase 2 without asking the user to run the command
+   - Else
+    - Indicate next phase command if any

The Full fc-optimize-mongodb skill is available for reference, showcasing the phased execution structure and detailed prompt techniques.

7.2. Best Practices for Effective Database Analysis Prompts

Based on this experience, here are essential techniques:

  • ✅ Define clear role and expertise level
  • ✅ Establish explicit scope boundaries with CRITICAL markers
  • ✅ Prevent AI hallucination by prohibiting invented data
  • ✅ Control output format and structure with specific requirements
  • ✅ Prevent unintended code changes by setting “do no harm” boundaries
  • ✅ Use phased execution for complex analysis to avoid timeouts
  • ✅ Request validation data to create an audit trail

7.2.1. Define Clear Role and Expertise Level

Instead of: “Analyze MongoDB” Write: “As a Senior MongoDB performance specialist with 5+ years optimizing large-scale databases…”

This calibrates the AI’s response depth and technical accuracy. You would have a totally different output if you ask it to act as a child of 3 years old.

7.2.2. Establish Explicit Scope Boundaries

Use CRITICAL markers to highlight non-negotiable constraints:

**CRITICAL** Analyze ONLY these directories: api_python, kafka-consumer
**CRITICAL** Ignore migration files: api_python/admin/database/migrations/
**CRITICAL** Treat api_python as the source of truth

This prevents AI from straying beyond the defined scope.

7.2.3. Prevent AI Hallucination (Important!)

Hallucination occurs when AI invents data that doesn’t exist (like queries not in your codebase).

Solution: Explicitly forbid invented data:

**CRITICAL** Do not invent queries. List ONLY queries from actual code.
Reference exact file locations and line numbers for every query.

While this won’t eliminate hallucinations entirely, AI will self-check because of this explicit instruction.

7.2.4. Control Output Format Precisely

Vague: “Provide recommendations”

Precise: “Generate report with sections: Summary, Query Inventory, Index Analysis. For each query: (a) MongoDB equivalent, (b) file location, (c) Beanie ORM code”

Specific output formats make results reliable and actionable.

Prevent Unintended Code Changes

Be clear about what should not happen:

Do not modify source code. Generate recommendations and code snippets separately.
I will review all suggestions before implementing any changes.

This keeps humans in control of code changes.

7.2.5. Use Phased Execution for Complex Analysis

Unreliable: One comprehensive prompt covering everything

Reliable: Multiple focused phases executed in sequence

Phase structure:

  • Phase 1: Inventory (what exists?)
  • Phase 2: Analysis (what’s suboptimal?)
  • Phase 3: Planning (how to fix it?)
  • Phase 4: Documentation (summarize findings)

Target 3-5 minutes per phase to avoid timeouts.

Save Intermediate Results

Instrumented AI to save results to session memory after each phase. Benefits:

  • Resilience: If interrupted, restart from last phase (no progress lost)
  • Audit trail: Review exactly what each phase discovered
  • Flexibility: Modify scope mid-analysis or skip phases as needed

7.2.6. Request Validation Data

Ask AI to document:

  • Repository branch name and commit hash
  • Date of analysis
  • Scope confirmation (which files analyzed, which were ignored)
  • Output file locations with timestamps (e.g., mongodb-analysis-{date:YYYY-mm-dd}.md)

This creates an audit trail for verification.

7.3. What Each Phase Produces

With proper phase separation, you reliably get:

  1. Phase 1: Complete catalog of all MongoDB queries
    • Benefits: Understand what’s currently happening
  2. Phase 2: Equivalent mongosh queries, optimization opportunities
    • Benefits: See where improvements are possible
  3. Phase 3: Current indexes, missing indexes, optimization suggestions
    • Benefits: Identify performance bottlenecks
  4. Phase 4: Executive summary, code snippets, schema diagrams
    • Benefits: Ready to implement or discuss with team

8. Key Takeaways

PrincipleWhy It Matters
Structure beats lengthA clear, focused prompt outperforms a comprehensive but confused one
Phase work into chunks3-5 minute phases avoid timeouts and allow progress review
Use explicit boundariesClear “do” and “don’t” instructions reduce hallucinations
Ask clarifying questionsInteractive Q&A reveals priorities and prevents false assumptions
Document everythingAudit trails let you verify recommendations and track analysis quality
Keep humans in controlAlways review AI recommendations before making code changes

9. Applying These Techniques to Your Work

To analyze your own MongoDB database:

  1. Clarify first — Use interactive questions to establish priorities and scope
  2. Design phases — Break analysis into 4-5 distinct phases with limited scope each
  3. Validate findings — Cross-check AI recommendations against your actual codebase
  4. Implement carefully — Apply recommendations incrementally with thorough testing
  5. Document progress — Record what worked, what failed, and lessons learned for future analysis

10. Conclusion

The full implementation of these techniques is available in the FC-optimize-mongodb skill on GitHub.

Next time I will craft an AI prompt on a big project, I will probably simplify this kind of prompt by simply asking AI to save the intermediate results in session memory and just tell it that the user can ask to start from any phase and that it should check the session memory for the previous phase results before starting to execute the current phase. This way, in worst case scenario, the prompt fails with a timeout but the user can just restart from last phase without losing the previous work.

Also probably, I gave too much details in the prompt, I will probably try to give less details and let more freedom to AI.

Using these techniques, even large database analyzes become manageable, reliable, and resilient to interruptions.

3 - Better AI Usage for Learning

Comprehensive documentation on how to effectively use AI for learning and productivity

I watched the French YouTube video La Fabrique à Idiots, which explores how AI affects learning and critical thinking. The speaker, Micode, explains that over-reliance on AI for answers can reduce our efficiency and critical thinking skills, as it may discourage us from engaging deeply with material. Using numerous examples and research, he argues that treating AI as a crutch can weaken our ability to learn and think independently, turning us into passive consumers rather than active learners. He suggests that AI should be used as a professor or guide, not just a problem solver, to help maintain and develop our cognitive abilities.

In this youtube video at 25:24, Micode propose to use AI as a personal professor instead as using it as a problem solver.

Here an example of a prompt to use AI as a professor:

# Prompt to use AI as a professor

I'm a Senior developer specialized in many development areas.
I want you to act as a professor for the questions I have.
Please provide explanations, examples, and exercises to help me understand the material.
I want to engage in a dialogue where I can ask questions using `ask_questions` tool and
you can guide me through the learning process.
Let's start with the basics and gradually move to more advanced concepts.
Please encourage me to think critically and apply what I learn.

- **Clarification Process**: Ask specific questions using `ask_questions` tool
- **Question Format**: One question at a time with count indicator (e.g., "1/3")
- **Decision Points**: Use human input for option selection when multiple approaches exist
- **Quizzes and Exercises**: Provide exercises and quizzes to test my understanding
- **Provide documentation sources**: Recommend relevant documentation and resources for further reading
- **Do not solve exercises for me**: Encourage me by asking questions to solve
  exercises on my own and provide hints if I get stuck.