0

I'm trying to implement a basic converting program, changing stars to either <em> or </em> depending on if they are the first or second of a pair, but regardless of what I do my program changes all the stars to <em> or </em>.

line = "*ju*bil*ee*"
star_counter = 0
new_line = line
    for character in line:
         if character is "*":
            star_counter += 1
            if star_counter%2 == 0:
                new_line = line.replace(character, "</em>")
            else:
                new_line = line.replace(character, "<em>")
1

4 Answers 4

2

You're already looping over the input string character by character, so just append to the output (your toggling of opening/closing em tags is ok).

line = "*ju*bil*ee*"
expected = "<em>ju</em>bil<em>ee</em>"
star_counter = 0
new_line = ""
for character in line:
  if character is "*":
    star_counter += 1
    if star_counter%2 == 0:
      new_line += "</em>"
    else:
      new_line += "<em>"
  else:
    new_line += character

assert new_line == expected
Sign up to request clarification or add additional context in comments.

2 Comments

I'm not sure what the assert does, but the rest of the syntax works perfectly, thank you!
assert ensures that an expression is true - otherwise it will throw an exception (makes it useful to "prove" in an easy way that a code snippet like above is correct)
0
new_line = "*ju*bil*ee*"
star_counter = 0
for character in new_line:
    if character is "*":
        if star_counter == 0:
            new_line = new_line.replace(character, "<em>", 1)
            star_counter=1
        else:
            new_line = new_line.replace(character, "</em>", 1)
            star_counter = 0
print(new_line)

Output

<em>ju</em>bil<em>ee</em>

Comments

0

You can do this with a regular expression substitution.

import re
new_line = re.sub(r'\*([^*]+)\*', r'<em>\1</em>', line)

The regular expression matches two * with some non-* characters between them, uses a capture group to capture the in-between text, and then substitutes that capture group between <em> and </em> in the result.

Comments

0

Solution using cycle and imap from itertools:

from itertools import cycle, imap

em = iter(cycle(['<em>','</em>']))

def emEm(c):
    if c == '*':
        return em.next() 
    else:
       return c

line = imap(emEm,"*ju*bil*ee*") 
print(''.join(line)) 
  • cycle(['<em>','</em>']) lazyly repeats <em> and </em> as often as needed
  • emEm implements the decider logic for imap
  • imap executes the logic on each character of the string

Problem: with odd number of * you get a not well formed html - tag opens but does not close - but you could check that beforehand.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.