PCAP-31-03: Section 3: Strings

Try 10 focused PCAP-31-03 questions on Section 3: Strings, with explanations, then continue with IT Mastery.

On this page

Open the matching IT Mastery practice page for timed mocks, topic drills, progress tracking, explanations, and full practice.

Try PCAP-31-03 on Web View full PCAP-31-03 practice page

Topic snapshot

FieldDetail
Exam routePCAP-31-03
Topic areaSection 3: Strings
Blueprint weight18%
Page purposeFocused sample questions before returning to mixed practice

How to use this topic drill

Use this page to isolate Section 3: Strings for PCAP-31-03. Work through the 10 questions first, then review the explanations and return to mixed practice in IT Mastery.

PassWhat to doWhat to record
First attemptAnswer without checking the explanation first.The fact, rule, calculation, or judgment point that controlled your answer.
ReviewRead the explanation even when you were correct.Why the best answer is stronger than the closest distractor.
RepairRepeat only missed or uncertain items after a short break.The pattern behind misses, not the answer letter.
TransferReturn to mixed practice once the topic feels stable.Whether the same skill holds up when the topic is no longer obvious.

Blueprint context: 18% of the practice outline. A focused topic score can overstate readiness if you recognize the pattern too quickly, so use it as repair work before timed mixed sets.

Sample questions

These questions are original IT Mastery practice items aligned to this topic area. They are designed for self-assessment and are not official exam questions.

Question 1

Topic: Section 3: Strings

A developer is troubleshooting a failed file open on Windows. This code prints a strange path and then raises FileNotFoundError:

path = "C:\new\test.txt"
print(path)
with open(path, "r") as f:
    print(f.readline())

What is the best explanation for the failure?

Options:

  • A. Text mode cannot open file paths that contain backslashes.

  • B. \n and \t were interpreted as newline and tab in the string literal.

  • C. print() modifies the path value before open() uses it.

  • D. open() requires forward slashes instead of backslashes on Windows.

Best answer: B

Explanation: In a normal Python string literal, some backslash combinations are escape sequences. Here, \n becomes a newline and \t becomes a tab, so the path passed to open() is different from the intended Windows path.

The core concept is that backslashes inside a normal string literal can introduce escape sequences. In "C:\new\test.txt", Python does not keep every backslash as a literal character: \n is parsed as a newline and \t as a tab. That means the resulting string no longer matches the real file path, so open() looks for the wrong location and raises FileNotFoundError.

To keep backslashes literal in this kind of path, use doubled backslashes like "C:\\new\\test.txt" or a raw string such as r"C:\new\test.txt".

The key takeaway is that the problem comes from string-literal parsing, not from open() or print().

  • Text mode confusion fails because text mode affects file contents, not how the path literal itself is parsed.
  • Forward slash myth fails because Windows paths can be used without requiring forward slashes.
  • print() side effect fails because print() only displays the current string; it does not change it.

Question 2

Topic: Section 3: Strings

A support script should extract a file’s final extension, but it gives the wrong result for names with multiple dots.

name = "report.final.csv"
pos = name.find(".")
print(name[pos + 1:])

The script prints final.csv, but the requirement is to get only csv. Some filenames may also contain no dot, and that case should not raise an exception. Which change is the best fix?

Options:

  • A. Use name.index(".") and rely on -1 when the dot is missing.

  • B. Use name.rfind(".") and treat -1 as no extension.

  • C. Use name.find(".") after checking "." in name.

  • D. Use sorted(name) before searching for ".".

Best answer: B

Explanation: The requirement is to search from the right and avoid an exception when no dot exists. rfind() returns the last matching position, and if the substring is absent it returns -1, which can be handled before slicing.

This is a string-search method selection problem. find() searches from left to right, so it returns the first dot in report.final.csv, which makes the slice start at final.csv instead of the final extension. index() also searches from the left, but unlike find(), it raises ValueError if the substring is missing.

rfind() is the best fit because it searches for the last occurrence of "." and returns -1 when there is no match. That directly matches both requirements: use the final dot, and do not raise an exception for filenames without one. The closest distractor is checking membership before find(), which avoids a missing-dot issue but still finds the wrong dot.

  • index() confusion fails because index() raises ValueError when "." is absent and still finds the first dot.
  • Membership check only avoids a missing-dot crash, but find() still returns the first dot rather than the last one.
  • Sorting first changes the character order instead of searching the original filename.

Question 3

Topic: Section 3: Strings

A developer wants this code to print B. The condition should compare the code point of c with the code point of D, but the if line is broken.

c = "A"
if ord(c) < "D":
    print(chr(ord(c) + 1))

Which replacement for the if line is the best fix?

Options:

  • A. if ord(c) < ord(“D”):

  • B. if c.ord() < ord(“D”):

  • C. if chr(ord(c)) < ord(“D”):

  • D. if ord(c, 1) < ord(“D”):

Best answer: A

Explanation: ord() returns an integer code point for a one-character string, while chr() turns an integer back into a character. The broken line compares an int with a str, so the fix is to apply ord() to "D" as well before using <.

This question tests matching types when using ord() and chr(). In the broken condition, ord(c) returns an integer, but "D" is still a string, and Python 3 cannot compare those with <. Replacing "D" with ord("D") makes both sides integers, so the condition can be evaluated correctly.

  • ord("A") is 65
  • ord("D") is 68
  • 65 < 68 is True
  • chr(65 + 1) is "B"

A close distractor rebuilds c with chr(ord(c)), but that returns a string again and leaves the type mismatch in the comparison.

  • The option using chr(ord(c)) still puts a string on the left side of <, so it does not fix the mixed-type comparison.
  • The option using c.ord() is invalid because ord() is a built-in function, not a string method.
  • The option using ord(c, 1) is invalid because ord() accepts exactly one argument.

Question 4

Topic: Section 3: Strings

A developer stores message text in an object and searches it from an instance method. Assume no extra exception handling.

class Note:
    def __init__(self, text):
        self.text = text

    def position(self, fragment):
        return self.text.index(fragment)

n = Note("spam ham eggs")
print(n.position("toast"))

Which statement is correct?

Options:

  • A. .index() raises AttributeError; self.text is an instance variable.

  • B. .index() raises ValueError; using .find() here would return -1.

  • C. .index() returns -1; using .find() here would raise ValueError.

  • D. .index() returns None; .find() would also return None.

Best answer: B

Explanation: str.index() and str.find() differ only in how they report a missing substring. Here, self.text is a normal string, so searching for "toast" with .index() raises ValueError; .find() would return -1 instead.

str.index() and str.find() both search for a substring inside a string, but they handle the “not found” case differently. In this example, the method position() calls .index() on self.text, which is just a str stored in an instance variable. Because "toast" does not appear in "spam ham eggs", .index() raises ValueError, so print() never receives a numeric result.

  • Use .index() when absence should be treated as an error.
  • Use .find() when you want a position if found, or -1 if not found.

The fact that the call happens inside a class method does not change the string method’s behavior.

  • Swapped behaviors fails because .find() is the method that returns -1 when the substring is missing.
  • Wrong exception type fails because this is not an attribute lookup problem; the missing value causes a search failure, not AttributeError.
  • Wrong return value fails because neither method returns None for an absent substring.

Question 5

Topic: Section 3: Strings

A support script should print match only when the substring 'disk' appears anywhere in a log message. The current code raises an error:

text = "Error: disk full"
if text.index("disk") in text:
    print("match")

Which replacement for the if line is the best fix?

Options:

  • A. if text.find["disk"] >= 0:

  • B. if "disk" in text:

  • C. if find(text, "disk") >= 0:

  • D. if "disk".find(text) >= 0:

Best answer: B

Explanation: The broken line mixes two different operations: index() returns an integer position, while in performs a membership test. Since the goal is only to check whether 'disk' occurs in the string, the direct membership form is the correct repair.

String membership and string search methods are related but not interchangeable. text.index("disk") returns the starting position of the substring, or raises ValueError if the substring is absent. The in operator expects a substring on the left and a string on the right.

In the broken code, Python first evaluates text.index("disk"), which produces an integer, and then tries to evaluate whether that integer is in the string. That is the wrong operand type for string membership.

If the task is only a yes/no test, use:

if "disk" in text:

Use find() or index() only when the actual position matters. A close distractor is using find, but here the simplest correct fix is the membership operator itself.

  • text.find["disk"] >= 0 fails because find is a method call, not something accessed with brackets.
  • "disk".find(text) >= 0 reverses the search target and looks for the whole message inside the shorter substring.
  • find(text, "disk") >= 0 fails because find is a string method, not a standalone built-in function.

Question 6

Topic: Section 3: Strings

A developer suspects a bad string index, but the bug may actually be in byte handling. What is printed by this code?

word = "naïve"
raw = word.encode("utf-8")

print(word[2], ord(word[2]), raw[2])

try:
    print(raw[2:3].decode("utf-8"))
except UnicodeDecodeError:
    print("decode error")

Options:

  • A. ```text ï 239 239 decode error

- B. ```text
ï 239 195
ï
  • C. ```text ï 239 b’\xc3' decode error

- D. ```text
ï 239 195
decode error

Best answer: D

Explanation: The string index is valid: word[2] returns ï. The problem is byte representation in UTF-8—ï uses more than one byte, so raw[2:3] contains an incomplete sequence and decoding it raises UnicodeDecodeError, which is caught.

word is a Unicode string, so indexing it works by characters, not by UTF-8 bytes. The third character is ï, and ord(word[2]) is its Unicode code point, 239. After encode("utf-8"), that same character is stored as two bytes, 195 and 175, so raw[2] is just the first byte of the encoded form.

  • print(word[2], ord(word[2]), raw[2]) prints ï 239 195
  • raw[2:3] is a one-byte slice, not a complete UTF-8 character
  • Decoding that incomplete byte sequence raises UnicodeDecodeError
  • The except block then prints decode error

The key point is that the failure comes from decoding incomplete bytes, not from string indexing.

  • Treating raw[2] as 239 confuses the character’s Unicode code point with its first UTF-8 byte.
  • Treating raw[2:3].decode("utf-8") as ï ignores that ï needs two bytes in UTF-8.
  • Treating raw[2] as b'\xc3' confuses byte indexing with byte slicing; indexing a bytes object returns an integer.

Question 7

Topic: Section 3: Strings

A developer initializes an object from a status line and relies on .split() to separate fields using its default behavior. What is printed?

class StatusLine:
    def __init__(self, raw):
        self.parts = raw.split()

s = StatusLine("  cpu   high\ttemp  ")
print(s.__dict__)

Options:

  • A. {'parts': ['cpu', 'high', 'temp']}

  • B. {'parts': ['cpu', 'high\ttemp']}

  • C. {'parts': ['', '', 'cpu', '', '', 'high\ttemp', '', '']}

  • D. {'parts': [' cpu high', 'temp ']}

Best answer: A

Explanation: str.split() with no separator uses default whitespace splitting. It removes leading and trailing whitespace, collapses consecutive whitespace, and treats tabs as separators, so the instance attribute becomes a three-item list.

The key concept is the default behavior of str.split() when no separator is provided. In that form, Python splits on any whitespace character, including spaces and tabs, and it does not keep empty strings caused by leading, trailing, or repeated whitespace. In the constructor, the result is stored in the instance attribute parts, so printing s.__dict__ shows that attribute and its list value.

For the given string, the tokens are:

  • cpu
  • high
  • temp

So the object’s dictionary contains one key, parts, mapped to ['cpu', 'high', 'temp']. The closest mistakes come from confusing split() with split(" ") or forgetting that \t is also whitespace.

  • Empty strings included matches split(" "), not split() with no argument.
  • Tab kept inside text fails because default split() treats \t as whitespace too.
  • Only two parts would fit splitting only on the tab, which the code does not do.

Question 8

Topic: Section 3: Strings

A text import routine receives records like Ann||QA. The program must turn each record into a list of fields using | as the separator, and an empty field between two separators must remain ''. Which string method best matches this requirement?

Options:

  • A. record.strip('|')

  • B. '|'.join(record)

  • C. record.find('|')

  • D. record.split('|')

Best answer: D

Explanation: split('|') is the right choice because it parses the string into a list wherever | appears. With an explicit separator, consecutive delimiters preserve empty fields, so Ann||QA becomes ['Ann', '', 'QA'] as required.

Use split() when you need to parse delimited text into separate fields. Passing '|' tells Python exactly where to cut the string, and adjacent separators create an empty string in the result. That directly matches the requirement to preserve a blank middle field.

  • Ann||QA.split('|') produces ['Ann', '', 'QA']
  • The result is a list of field values
  • Empty fields are preserved when a separator is explicitly provided

The key distinction is that split() parses a record, while methods like strip() only remove characters from the ends.

  • End trimming only the option using strip('|') removes | only from the start or end, not between fields.
  • Search, not parse the option using find('|') returns an index, not the list of fields.
  • Wrong direction the option using '|'.join(record) builds one string from an iterable and would place | between characters here.

Question 9

Topic: Section 3: Strings

A developer is checking how escape sequences in a string literal become characters at runtime. What is printed by this code?

msg = "A\\nB\nC"
print(msg)
print(len(msg))

Options:

  • A. ```text A\nB\nC 7

- B. ```text
A\\nB
C
6
  • C. ```text A\nB C 5

- D. ```text
A
B
C
5

Best answer: B

Explanation: Python interprets escape sequences while reading the string literal. In "A\\nB\nC", \\ produces a literal backslash, so \\n becomes the two characters \ and n, while the later \n becomes a real newline.

Escape sequences are part of the source-code representation of a string literal. Python converts them into characters when the program is parsed. In this example, \\ becomes one backslash character, so the first \\n does not become a newline; it becomes the two runtime characters \ and n. The second \n is a real newline character.

That means the runtime string contains 6 characters: A, \, n, B, newline, and C. So print(msg) displays A\nB on the first line and C on the second line, and print(len(msg)) then prints 6.

The closest mistake is to treat \\n as if it were another newline escape.

  • Both newlines fails because the first \\n is not a newline; \\ first becomes a literal backslash.
  • Wrong length gets the displayed lines right but counts \ and n as one character instead of two.
  • No escape processing fails because Python does interpret \n in string literals, so the second one cannot remain literal.

Question 10

Topic: Section 3: Strings

A developer wants to confirm Python’s default string ordering before sorting labels. What is printed by this code?

data = ["cat", "catalog", "Cat", "20", "3"]
print(sorted(data))

Options:

  • A. ['20', '3', 'cat', 'Cat', 'catalog']

  • B. ['20', '3', 'Cat', 'catalog', 'cat']

  • C. ['20', '3', 'Cat', 'cat', 'catalog']

  • D. ['3', '20', 'Cat', 'cat', 'catalog']

Best answer: C

Explanation: Python compares strings lexicographically, character by character, using Unicode code points. Here, digit-starting strings come first, Cat comes before cat, and cat comes before catalog because it is the shorter matching prefix.

The key concept is lexicographic string comparison in Python. sorted() uses the same ordering as other string comparisons: it checks characters from left to right by Unicode code point, and if one string ends while all compared characters still match, the shorter string is considered smaller.

  • "20" comes before "3" because '2' is less than '3'.
  • "Cat" comes before the lowercase words because 'C' has a smaller code point than 'c'.
  • "cat" comes before "catalog" because both start with cat, and the shorter equal-prefix string sorts first.

The usual mistakes are treating digit strings as numbers, assuming lowercase sorts before uppercase, or placing the longer prefix first.

  • The list starting with "3" treats the digit strings as numeric values instead of strings.
  • The list placing "cat" before "Cat" ignores Python’s case-sensitive character ordering.
  • The list placing "catalog" before "cat" reverses the prefix rule for string comparison.

Continue with full practice

Use the PCAP-31-03 Practice Test page for the full IT Mastery route, mixed-topic practice, timed mock exams, explanations, and web/mobile app access.

Try PCAP-31-03 on Web View PCAP-31-03 Practice Test

Free review resource

Read the PCAP-31-03 Cheat Sheet on Tech Exam Lexicon, then return to IT Mastery for timed practice.

Revised on Thursday, May 14, 2026