7  Operators

7.1 The Wall

AI gave you a calculation that used // and % and you thought // was a comment. It was not. It was integer division. The result was wrong because you did not know what the operators did, so you could not tell whether AI had used the right ones.

In another case, AI wrote if x and y > 10: and you assumed it checked whether both x and y were greater than 10. It did not. It checked whether x was truthy and y was greater than 10. Subtle, silent, wrong.

This chapter fixes that.

7.2 Thinking Session

7.2.1 Getting Oriented

NoteThinking Session Prompt

What operators does Python have beyond the basic +, -, *, /? I keep seeing //, %, **, and, or, not, ==, !=, is, in, can you organise them into categories and explain when each one is used? Focus on the ones that AI uses most often in generated code.

Your AI should group them: arithmetic (+, -, *, /, //, %, **), comparison (==, !=, <, >, <=, >=), logical (and, or, not), membership (in, not in), and identity (is, is not). If it lists bitwise operators, you can skip those for now.

7.2.2 Go Deeper

NoteThinking Session Prompt

What is the difference between / and // in Python? And between == and is? These confuse me when I see them in AI-generated code. Give me examples where using the wrong one causes bugs.

TipWhat to Look For

/ gives a float (7 / 2 is 3.5), // gives an integer (7 // 2 is 3). == checks value equality, is checks identity (same object in memory). The classic trap: x == None works but x is None is correct. AI usually gets this right, but not always.

NoteThinking Session Prompt

How does Python evaluate compound conditions? What does if x and y > 10 actually check? And what about if x or y? I want to understand operator precedence in conditions because AI writes these frequently.

7.2.3 Challenge It

NoteThinking Session Prompt

What does each of these evaluate to, and why?

10 / 3
10 // 3
10 % 3
2 ** 10
"hello" * 3
"py" in "python"
not ""
True + True
TipWhat to Look For

10 / 3 is 3.333..., 10 // 3 is 3, 10 % 3 is 1 (remainder). 2 ** 10 is 1024 (exponentiation). "hello" * 3 is "hellohellohello" (string repetition). "py" in "python" is True (substring check). not "" is True (empty string is falsy). True + True is 2 (booleans are integers).

7.2.4 What You Should Have Learned

  • // is integer division, % is remainder, ** is exponentiation
  • == checks value, is checks identity (use is for None)
  • and and or short-circuit. They do not always evaluate both sides
  • in checks membership in strings, lists, and dictionaries
  • Empty strings, zero, None, and empty collections are all falsy

7.3 The Gap

Operators are the glue in AI-generated code. Every condition, every calculation, every loop test uses them. Now when you see if count % 5 == 0: you know it checks whether count is a multiple of 5. When you see if name and len(name) > 0: you know the and short-circuits, if name is empty, it never checks the length.

In the Building Session, you will add smarter response logic to your chatbot based on message properties.

7.4 Building Session

7.4.1 The Spec

Make your chatbot respond differently based on message characteristics:

  • Respond to questions (input contains “?”)
  • Respond differently to long messages (more than 50 characters) vs short ones
  • Track whether the user has asked any questions using a boolean
  • Use in to check for keywords

7.4.2 Prompt It

NoteBuilding Session Prompt

Update my chatbot to v0.7. Add operator-based response logic:

  • If the input contains “?”, treat it as a question and respond with “Good question! I’m still learning…”
  • If the message is longer than 50 characters, respond with “That’s a lot to take in!”
  • If the message contains “python” or “coding” (use in), respond enthusiastically
  • Track a boolean has_asked_question that becomes True when the user asks their first question
  • Use the modulo operator: every 5th message, add “(milestone!)” to the response

Keep the existing features from v0.6.

7.4.3 Read the Code

Your AI will produce something like this:

"""PyBot v0.7: Operator-based responses."""
BOT_NAME = "PyBot"
VERSION = "0.7"

user_name = input(f"{BOT_NAME}: What's your name? ").strip()
while not user_name:
    user_name = input("Please enter your name: ").strip()

print(f"Hello, {user_name}! Type 'quit' to exit, 'help' for commands.")

message_count = 0
has_asked_question = False

while True:
    user_input = input(f"{user_name}: ").strip()

    if not user_input:
        print(f"{BOT_NAME}: Type something! Try 'help'.")
        continue

    if user_input.lower() == "quit":
        print(f"{BOT_NAME}: Goodbye, {user_name}!")
        break

    message_count += 1
    milestone = " (milestone!)" if message_count % 5 == 0 else ""

    if "?" in user_input:
        has_asked_question = True
        response = "Good question! I'm still learning..."
    elif "python" in user_input.lower() or "coding" in user_input.lower():
        response = "I love that topic!"
    elif len(user_input) > 50:
        response = "That's a lot to take in!"
    else:
        response = f"You said '{user_input}'"

    print(f"{BOT_NAME}: {response}{milestone}")
TipWhat to Notice

"?" in user_input uses the in operator for substring check. message_count % 5 == 0 uses modulo to detect every 5th message. has_asked_question = True is a boolean flag. It starts False and flips once. The or in the keyword check means either match triggers the response.

7.4.4 Stretch It

NoteBuilding Session Prompt

Add a “stats” command that shows: total messages, whether any questions have been asked (True/False), and the average message length (total characters // message count).

7.5 Your Chatbot So Far

  • Ch 1-2: Basic loop, structure, comments
  • Ch 3-4: Type recognition, name memory, message count
  • Ch 5-6: Formatted output, input validation, help
  • Ch 7: Question detection, keyword matching, milestones

7.6 Quick Reference

# Arithmetic
7 / 2       # 3.5 (float division)
7 // 2      # 3   (integer division)
7 % 2       # 1   (remainder)
2 ** 10     # 1024 (exponentiation)

# Comparison
x == y      # equal
x != y      # not equal
x is None   # identity (use for None)

# Logical
x and y     # both true (short-circuits)
x or y      # either true (short-circuits)
not x       # negation

# Membership
"py" in "python"        # True
5 in [1, 2, 3, 4, 5]   # True
"key" in my_dict        # True (checks keys)

# Falsy values
# False, 0, 0.0, "", [], {}, None