S3Q2 · Uppercase Every k-th Vowel in a File¶
⚡ Quick Reference
Type: File-in, stdout-out
Core idea: scan character by character across all lines; maintain a global vowel counter; uppercase every k-th vowel, lowercase all others.
import tempfile, sys
_, filename = tempfile.mkstemp(prefix="case")
with open(filename, 'w') as f:
f.write(sys.stdin.read())
VOWELS = set("aeiou")
with open(filename) as f:
k = int(f.readline().strip())
count = 0
for line in f:
result = []
for ch in line:
if ch.lower() in VOWELS:
count += 1
result.append(ch.upper() if count % k == 0 else ch.lower())
else:
result.append(ch)
print("".join(result), end="")
Key rules:
- Global vowel counter across all lines
- count % k == 0 → uppercase | otherwise → lowercase
- Consonants keep their original case unchanged
- print(..., end="") preserves newlines already in each line
Problem Statement¶
Problem (File I/O → stdout)
Read k from the first line. Process the rest of the file: uppercase every k-th vowel (globally), lowercase all other vowels, leave consonants unchanged.
Example (k=3):
3
This is a sample text.
it has many vowels.
every third one becomes uppercase.
This is A sample tExt.
it has mAny vowels.
Every third One becOmes uppErcase.
Tracing the example (k=3)¶
Line 1: "This is a sample text."
| Char | Vowel? | Count | Count%3 | Output |
|---|---|---|---|---|
| T | ❌ | - | - | T |
| h | ❌ | - | - | h |
| i | ✅ | 1 | 1 | i (lower) |
| s | ❌ | - | - | s |
| i | ✅ | 2 | 2 | i (lower) |
| s | ❌ | - | - | s |
| a | ✅ | 3 | 0 | A (UPPER) |
| ... | ||||
| a | ✅ | 4 | 1 | a |
| e | ✅ | 5 | 2 | e |
| e | ✅ | 6 | 0 | E (UPPER) |
→ This is A sample tExt. ✓ (count continues to line 2)
Line 2 starts at count=6, line 3 at count=9 after "vowels"...
Solution approaches¶
import tempfile, sys
_, filename = tempfile.mkstemp(prefix="case")
with open(filename, 'w') as f:
f.write(sys.stdin.read())
VOWELS = set("aeiou")
with open(filename) as f:
k = int(f.readline().strip())
count = 0
for line in f:
result = []
for ch in line:
if ch.lower() in VOWELS:
count += 1
result.append(ch.upper() if count % k == 0 else ch.lower())
else:
result.append(ch)
print("".join(result), end="")
import tempfile, sys
_, filename = tempfile.mkstemp(prefix="case")
with open(filename, 'w') as f:
f.write(sys.stdin.read())
VOWELS = set("aeiou")
with open(filename) as f:
lines = f.readlines()
k = int(lines[0].strip())
count = 0
result = []
for line in lines[1:]:
for ch in line:
if ch.lower() in VOWELS:
count += 1
result.append(ch.upper() if count % k == 0 else ch.lower())
else:
result.append(ch)
print("".join(result), end="")
import tempfile, sys
_, filename = tempfile.mkstemp(prefix="case")
with open(filename, 'w') as f:
f.write(sys.stdin.read())
VOWELS = set("aeiou")
with open(filename) as f:
k = int(f.readline().strip())
text = f.read()
count = [0]
transform = lambda ch: (
[count.__setitem__(0, count[0]+1), ch.upper() if count[0]%k==0 else ch.lower()][1]
if ch.lower() in VOWELS else ch
)
print("".join(map(transform, text)), end="")
Key takeaways¶
Global counter across lines
The vowel counter must persist across all lines - don't reset between lines. Initialise count = 0 once before the line loop; it increments with each vowel found anywhere in the file.
ch.lower() in VOWELS - case-insensitive vowel check
Lowercasing the character before checking membership handles both 'A' and 'a' with one set. The VOWELS set only needs lowercase letters.
Non-vowels keep original case - don't touch them
Only vowels are transformed. Consonants, spaces, punctuation, and newlines are appended to result unchanged. The else: result.append(ch) handles this correctly for all non-vowel characters including \n.