Skip to content

S3Q2 · Ubbi Dubbi - Add "ub"/"dub" Alternately Before Vowels

⚡ Quick Reference

Type: File-in, stdout-out

Core idea: read the file, iterate character by character, insert "ub" before odd-numbered vowels and "dub" before even-numbered vowels. Counter continues across lines.

import tempfile, sys

_, filename = tempfile.mkstemp(prefix="case")
with open(filename, 'w') as f:
    f.write(sys.stdin.read())

vowels = set("aeiou")
count = 0

with open(filename, 'r') as f:
    for line in f:
        result = []
        for ch in line:
            if ch in vowels:
                count += 1
                prefix = "ub" if count % 2 == 1 else "dub"
                result.append(prefix + ch)
            else:
                result.append(ch)
        print("".join(result), end="")

Key rules: - Odd vowel count → prefix "ub" | Even vowel count → prefix "dub" - Counter is global - continues across lines - Preserve spaces, newlines, and all non-vowel characters exactly - Use end="" in print since newlines are already part of the line


Problem Statement

Problem (File I/O → stdout)

Read a file of lowercase text. Before each vowel, insert "ub" (odd-numbered vowel) or "dub" (even-numbered vowel). Print the result preserving all formatting.

Example:

Input file
hello world
pyhton is good
Output
hubelldubo wuborld
pythdubon ubis gduboubod

Tracing the example

Vowel counter is global across both lines:

Line 1: "hello world"

Char Vowel? Count Prefix Output
h - - h
e 1 (odd) ub ube
l - - l
l - - l
o 2 (even) dub dubo
- -
w - - w
o 3 (odd) ub ubo
r - - r
l - - l
d - - d
\n - - \n

Line 1 output: hubelldubo wuborld

Line 2: "pyhton is good" (counter continues at 3)

Char Vowel? Count Prefix Output
p,y,h,t - - pyht
o 4 (even) dub dubo
n - - n
- -
i 5 (odd) ub ubi
s - - s
g - - g
o 6 (even) dub dubo
o 7 (odd) ub ubo
d - - d

Line 2 output: pythdubon ubis gduboubod


Solution approaches

import tempfile
import sys

_, filename = tempfile.mkstemp(prefix="case")
with open(filename, 'w') as f:
    f.write(sys.stdin.read())

vowels = set("aeiou")
count  = 0

with open(filename, 'r') as f:
    for line in f:
        result = []
        for ch in line:
            if ch in vowels:
                count += 1
                result.append(("ub" if count % 2 == 1 else "dub") + ch)
            else:
                result.append(ch)
        print("".join(result), end="")
import tempfile
import sys

_, filename = tempfile.mkstemp(prefix="case")
with open(filename, 'w') as f:
    f.write(sys.stdin.read())

vowels = set("aeiou")
count  = 0
output = []

with open(filename, 'r') as f:
    text = f.read()

for ch in text:
    if ch in vowels:
        count += 1
        if count % 2 == 1:       # odd → "ub"
            output.append("ub" + ch)
        else:                     # even → "dub"
            output.append("dub" + ch)
    else:
        output.append(ch)

print("".join(output), end="")

Read the entire file at once and process as a single string - newlines are preserved as \n characters.

import tempfile, sys

_, filename = tempfile.mkstemp(prefix="case")
with open(filename, 'w') as f:
    f.write(sys.stdin.read())

vowels = "aeiou"
count  = [0]   # mutable for closure

def replace_vowel(ch):
    count[0] += 1
    return ("ub" if count[0] % 2 == 1 else "dub") + ch

with open(filename) as f:
    text = f.read()

result = "".join(replace_vowel(ch) if ch in vowels else ch for ch in text)
print(result, end="")

Key takeaways

01

Global counter across lines

The vowel counter must persist across all lines - don't reset it at the start of each line. A counter initialised before the file loop and incremented per vowel handles this correctly.

02

print(line, end="") preserves newlines

When iterating for line in f, each line already ends with \n. Using print(..., end="") prevents print from adding a second newline, keeping the output formatting intact.

03

set("aeiou") for O(1) vowel lookup

Storing vowels as a set makes the membership check ch in vowels O(1) instead of O(5). For a string scan, this is a minor but good habit.