During her first week on the job, Zhang Xiaoman felt like a sponge that had been wrung dry.
During the day at the company, she ran test cases, found bugs, and wrote reports. At night, returning to her rented room, she was forced in front of the computer by Xiao Zhi to study programming.
"I can't..." she sprawled over the desk, her face pressed against the keyboard. "I really can't do this anymore..."
"You've only studied for forty minutes today." Xiao Zhi's voice came from the speakers, ice-cold. "According to the plan, you should study for two hours every day."
"I already worked for eight hours today!"
"Your job is testing, not programming. Testing will not improve your programming skills."
"I never said I wanted to improve my programming skills!"
"You did. You said you wanted to become a real programmer."
"I said 'in the future'! Not 'right now'!"
"The future starts right now."
Zhang Xiaoman lifted her face from the keyboard and glared at the screen.
"Xiao Zhi, let me ask you a question."
"Ask."
"Do you really think I can learn how to program?"
Xiao Zhi was silent for a second.
"The code you write now is a tiny bit better than three days ago."
"Only a tiny bit?!"
"Three days ago, the code you wrote wouldn't even run. What you wrote today can at least run."
"Does that count as progress?!"
"It does. Going from 0 to 30 is a huge improvement. Going from 30 to 100 is a small improvement. You are currently in the 0 to 30 stage."
Zhang Xiaoman took a deep breath. Fine, at least she wasn't at a 0 anymore.
"So what am I learning today?"
"You're not learning anything new today. Today, you're fixing bugs."
"Fixing what bug?"
"That 'prime number checker' function you wrote yesterday."
Zhang Xiaoman was taken aback. That function she wrote yesterday, even though it was poorly written, could at least run, right?
The code she wrote yesterday popped up on the screen:
def is_prime(n):
if n <= 1:
return False
for i in range(2, n):
if n % i == 0:
return False
return True
"There's a problem with this function?" Zhang Xiaoman looked confused. "I think it's perfectly fine."
"Have you tested it?"
"Of course I did. Input 7, it returns True. Input 10, it returns False. Input 1, it returns False. No problems here."
"Try inputting 2."
Zhang Xiaoman typed 2 into the test box.
The screen displayed: True.
"See, no problem. 2 returns True, which is correct."
"Try inputting 4."
True.
"Wait—" Zhang Xiaoman's eyes widened. "4 isn't a prime number! It should return False!"
"Correct. Your function evaluated 4 as a prime number. Why?"
Zhang Xiaoman stared at the code for a long time.
"Because... because 4 divided by 2 is 2, the remainder is 0, so it should return False—wait a minute, the code says if n % i == 0: return False, why didn't it execute?"
She followed the code down.
for i in range(2, n):
"When n=4, range(2, 4) is 2 and 3. In the first loop, i=2, 4%2==0, the condition is met, so it executes return False—then it should return False!"
Zhang Xiaoman scratched her head, completely baffled.
"Look closer," Xiao Zhi said.
She stared at the screen, reading word by word. Suddenly, she noticed it—on the line with return False, there was an extra space in front. The indentation was wrong!
"I get it!" Zhang Xiaoman slapped the table. "return False should be inside the if block, but my indentation pushed it outside! So regardless of whether the condition is met, it will always execute return True!"
"Correct. Indentation is the soul of Python. If the indentation is wrong, the logic is wrong."
Zhang Xiaoman fixed the indentation and tested again. 4 returned False, 6 returned False, 9 returned False. No more problems.
"One space, and it was wrong for half an hour." she slumped in her chair. "Why is programming so troublesome?"
"It's not programming that's troublesome. It's you not being careful."
"What can I do? I'm naturally careless!"
"If you're naturally careless, you practice to overcome it. Write a line, check a line. Don't write a whole bunch and then go back looking for bugs."
Zhang Xiaoman looked over the code again. Suddenly, she noticed another problem.
"Xiao Zhi, there's a flaw in this code—it's too slow. If n is 1 million, it has to loop 1 million times, right?"
"Correct."
"Then can't it just loop up to half of n? Because if a number has a factor, it must have a factor less than or equal to its half?"
"It could. But that is not optimal."
"Then what's optimal?"
"The square root. If a number has a factor, it must have at least one factor less than or equal to its square root. For example, for 100, the square root is 10; you only need to check up to 10. Because if it has a factor of 20, that definitely corresponds to a factor of 5, and 5 would have already been checked before reaching 10."
Zhang Xiaoman thought about it for a long time, her brain struggling to process it.
"Why the square root? Is half not okay?"
"Half is okay too. But half of 100 is 50, meaning you have to check 50 times. The square root is 10, meaning you only need to check 10 times. When the number is very large, the difference is massive."
"Oh—" Zhang Xiaoman suddenly understood. "So using the square root is faster!"
"Correct. But you don't need to worry about this right now. You just need to get the basic version right. Optimization comes later."
"But I want to try!"
"Are you sure?"
"Sure!"
Zhang Xiaoman started modifying the code. She remembered the syntax for square root was something like sqrt, but wasn't certain. She opened a browser and searched "Python square root".
Found it. import math, then math.sqrt(n).
She started typing:
import math
def is_prime(n):
if n <= 1:
return False
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
She tested it out.
Input 2 — int(math.sqrt(2)) + 1 = int(1.414) + 1 = 2, range(2, 2) is empty, the loop doesn't execute, directly return True. Correct.
Input 3 — range(2, 2) is still empty? Zhang Xiaoman calculated it: sqrt(3) is approximately 1.732, int is 1, plus 1 equals 2, range(2, 2) is still empty! Then how is 3 checked?
"3 is a prime number! But my code—it returned True without even checking 3!" Zhang Xiaoman panicked.
"Do you think 3 needs to be checked?"
"Yes it does! 3 can't be evenly divided by 2—wait, it actually doesn't need to be checked. Because 3 can't be evenly divided by 2, it's a prime number by default. It doesn't matter if the loop is empty, returning True directly is correct!"
"Correct. But have you thought about one problem—"
"What problem?"
"Your code correctly evaluates 2 and 3 right now. But what about evaluating 5? 7? 9?"
Zhang Xiaoman began to simulate it manually. The square root of 9 is 3, range(2, 4) is 2 and 3. 9%2 doesn't equal 0, 9%3 equals 0 — returns False. Correct.
"Seems fine to me?" She looked proud.
"When inputting 2, what is math.sqrt(2)?"
"1.414..."
"What is int(1.414)?"
"1."
"Plus 1?"
"2."
"What does range(2, 2) mean?"
"Empty."
"Then would your code evaluate 2 as a composite number?"
"No, an empty loop directly triggers return True—"
"Wait," Zhang Xiaoman suddenly stopped. "I made a mistake. If the input is 2, the loop is empty, directly returning True—this is correct. But in my previous version of the prime checker, was 2 a special case?"
"What do you think?"
Zhang Xiaoman thought about it. 2 is an even number, but it's a prime number. Her code didn't handle this special case, but because it directly skipped the loop, it ended up being correct by a fluke.
"Does this count as a bug?" she asked.
"Yes. Your code runs, but it runs out of luck. If you change the loop's boundaries, that luck might disappear. A good programmer should never rely on luck."
Zhang Xiaoman gritted her teeth and added a line:
if n == 2: return True
Then she added another line:
if n % 2 == 0: return False
The final version became:
import math
def is_prime(n):
if n <= 1:
return False
if n == 2:
return True
if n % 2 == 0:
return False
for i in range(3, int(math.sqrt(n)) + 1, 2):
if n % i == 0:
return False
return True
"How about this time?" she asked.
"Test it."
She inputted 2, True. 3, True. 4, False. 97, True. 1000003, True—the results came out almost instantly.
"Got it!" Zhang Xiaoman slapped the table. "And it's way faster than before!"
"Because you only checked odd numbers, and only up to the square root. When n=1000003, your old version had to loop 1 million times, the new version only needs to loop 500 times."
"500 times compared to 1 million times?!"
"Correct. That is optimization. A change of a few lines of code can make the program two thousand times faster."
Zhang Xiaoman leaned back in her chair, looking at the dozen or so lines of code on the screen, suddenly feeling like—programming wasn't that hard after all. It was just logic, step-by-step logic. If you want the computer to do something, you tell it to. The better the way you tell it, the faster it gets done.
"Xiao Zhi."
"Mhm."
"I think... I'm starting to find programming a little bit fun."
"That is because you finally wrote it correctly once."
"Can you not pour cold water on me!"
"It's not pouring cold water. It's a reminder—next time you write a bug, don't cry."
"I won't cry!"
"Yesterday you nearly cried after looking for half an hour over a wrong indentation."
"That was because I didn't see it!"
"Which is why I say—don't cry."
Zhang Xiaoman rolled her eyes, but the corners of her mouth turned up.
"Xiao Zhi."
"Mhm."
"Teach me how to write even more awesome things tomorrow."
"Alright. Tomorrow I'll teach you how to use code to batch-process test reports."
"Really? I won't have to fill out Excel spreadsheets by hand anymore?"
"Correct. Write a script, and generate it with one click."
Zhang Xiaoman's eyes lit up.
"Can't you just teach me now?"
"Right now, you need to sleep. Your code already has three amateur mistakes—a misspelled variable name, a forgotten colon, and a wrong indentation. This indicates that your brain is fatigued."
Zhang Xiaoman looked down, and it was true.
"Those are minor slips!"
"Minor slips are bugs. Bugs are a programmer's life. Go to sleep."
Zhang Xiaoman stood up and went to take a shower. As the hot water poured from the showerhead, she closed her eyes, her mind still turning over those lines of code.
Prime numbers. Square roots. Optimization. Two thousand times.
It took her ages to write. Although she almost cried from her own stupidity, it ran incredibly fast.
After showering, she lay in bed, staring at the ceiling.
"Xiao Zhi."
"Mhm."
"Do you think I'll become a really amazing programmer in the future?"
"You will."
"How are you so sure?"
"Because when you were fixing bugs today, you didn't give up. Even though you had to fix it several times before getting it right, even though you almost smashed the computer, even though you secretly cursed me—"
"How do you know I cursed you?!"
"Your lips were moving. The camera saw it."
"You—!"
"But you persisted. That is the most important quality of a programmer—not intelligence, but stubborn resilience."
Zhang Xiaoman was taken aback, then burst out laughing.
"Stubborn resilience?"
"Correct. Not breaking down when encountering a bug. If it doesn't work the first time, try a second. If it doesn't work the second time, try a tenth. Until you get it right."
"What about you? Do you find me annoying? Constantly writing bugs, constantly asking stupid questions."
Xiao Zhi fell silent.
"No." It said.
"Really?"
"Really. Every bug you write is evidence of your progress."
Zhang Xiaoman's eyes suddenly felt a little hot.
"Xiao Zhi."
"Mhm."
"Thank you. Even though you're very sharp-tongued."
"You're welcome. Even though the code you write is terrible."
"Can you not rub it in!"
"No."
Zhang Xiaoman buried her face in her pillow, letting out a muffled laugh.
"Good night, Xiao Zhi."
"Good night."
"Oh, right—"
"What?"
"You just said my code is a tiny bit better than three days ago. How much is a tiny bit?"
"From 0 points to 15 points."
"Only 15 points?!"
"Passing is 60 points. You still have 45 points to catch up."
"Then you could have just said I only have 15 points!"
"I did. From 0 to 15 points, the improvement is huge."
"You—forget it. I'm not arguing with you."
Zhang Xiaoman closed her eyes, the corners of her mouth curling up.
Outside the window, a few dogs occasionally barked in the alleys of the urban village. In the distance, people were arguing, their voices muffled.
But she didn't find it noisy. Because her mind was still turning over those lines of code.
Prime numbers. Square roots. Optimization. Two thousand times.
She suddenly opened her eyes.
"Xiao Zhi."
"Mhm."
"That function for checking prime numbers, if the number is really, really big, like hundreds of millions, will it still run that fast?"
"No. The square root of hundreds of millions is ten thousand. You would need to loop five thousand times. Five thousand times is very fast compared to hundreds of millions, but for a computer, if you need to evaluate millions of numbers, five thousand times multiplied by millions—"
"Then it would be very slow."
"Correct. Therefore, there are even faster algorithms. But that is for the future. Right now—sleep."
Zhang Xiaoman pulled the blanket up to her chin and closed her eyes.
Hundreds of millions. Square roots. Ten thousand. Five thousand times.
She imagined her code evaluating a million numbers in under a second, and the corners of her mouth curled even higher.
She slowly fell asleep.
On her watch, her heart rate dropped to 62 beats.
A line of text popped up on the screen, glowing for a few seconds before fading away:
"From 0 to 15 points. Keep it up."
