2

With this code, all I am trying to do is insert a dash between odd numbers and an asterisk between even ones. It does not work correctly with every input. It works with, e.g. 46879, but returns None with 468799, or does not insert * between 4 and 6 with 4546793. Why is it doing that? Thanks

def DashInsertII(num): 

 num_str = str(num)

 flag_even=False
 flag_odd=False

 new_str = ''
 for i in num_str:
  n = int(i)
  if n % 2 == 0:
   flag_even = True
  else:
   flag_even = False
  if n % 2 != 0:
   flag_odd = True
  else:
   flag_odd = False
  new_str = new_str + i
  ind = num_str.index(i)

  if ind < len(num_str) - 1:
   m = int(num_str[ind+1])
   if flag_even:
    if m % 2 == 0:
      new_str = new_str + '*'
   else:                 
    if m % 2 != 0:
      new_str = new_str + '-'                     
 else:
  return new_str  
 print DashInsertII(raw_input()) 
5
  • 3
    Use 4 spaces or a tab to indent your code. This is barely readable. Also you did not add a return at the end of the function. Commented Jul 7, 2014 at 20:20
  • num_str.index(i) will always return the first occurrence. You can't expect ind+1 to point to the next number if index returned the first occurrence, instead of the succeeding occurrence. Commented Jul 7, 2014 at 20:23
  • This code could be simplified and cleaned. Commented Jul 7, 2014 at 20:25
  • @alvits he could get the index by just using enumerate(num_str) in the loop signature. Commented Jul 7, 2014 at 20:28
  • @RafaelBarros - Although your suggestion will solve his problem, it doesn't give him insight where he went wrong. I think the fastest way to learning is to understand where they went wrong. You should post your suggestion as one of the alternative answers and I'll upvote it too. Commented Jul 7, 2014 at 20:50

3 Answers 3

5

Your function definition is one of the most overbuilt functions I've seen in a while; the following should do what yours was trying to do, sans the complexity.

def DashInsertII(num):
  num_str = str(num)

  new_str = ''
  for i in num_str:
    n = int(i)
    if n % 2 == 0:
      new_str += i + '*'
    else:
      new_str += i + '-'
  return new_str
print DashInsertII(raw_input()) 

EDIT: I just re-read the question and saw that I misinterpreted what you want, which is to insert a - between two odd numbers and a * between two even numbers. For that, the best solution I can come up with uses regular expressions.

Second Edit: As per alvits's request, I'm including an explanation of the regex in this.

import re

def DashInsertII(num):
  num_str = str(num)

  # r'([02468])([02468])' performs capturing matches on two even numbers
  #    that are next to each other
  # r'\1*\2' is a string consisting of the first match ([02468]) followed
  #    by an asterisk ('*') and the second match ([02468])
  # example input: 48 [A representation of what happens inside re.sub()]
  #    r'([02468])([02468])' <- 48 = r'( \1 : 4 )( \2 : 8 )'
  #    r'\1*\2' <- {\1 : 4, \2 : 8} = r'4*8'
  num_str = re.sub(r'([02468])([02468])',r'\1*\2',num_str)
  # This statement is much like the previous, but it matches on odd pairs
  #    of numbers
  num_str = re.sub(r'([13579])([13579])',r'\1-\2',num_str)

  return num_str

print DashInsertII(raw_input())

If this is still not what you actually want, please comment on this to let me know.

Sign up to request clarification or add additional context in comments.

2 Comments

+1 You could add some explanation to your regular expressions for the benefit of the OP and others who might stumble into this thread.
@alvits Good suggestion, I've edited the post to include that.
1

RevanProdigalKnight's answer is almost right but fails when 3 or more even/odd numbers come together.

The right way to do this with regex would be to use positive lookahead (use ?=).

def insert_right_way(num):
    #your code here
    num_str = str(num)
    num_str = re.sub(r'([13579])(?=[13579])', r'\1-', num_str)
    num_str = re.sub(r'([02468])(?=[02468])', r'\1*', num_str)
    return num_str

def DashInsertII(num):
    num_str = str(num)
    num_str = re.sub(r'([02468])([02468])',r'\1*\2',num_str)
    num_str = re.sub(r'([13579])([13579])',r'\1-\2',num_str)

    return num_str


print insert_right_way(234467776667888)

print DashInsertII(234467776667888)

This would output:

234*4*67-7-76*6*678*8*8 ( what is desired)
234*467-776*6678*88   ( not what we wanted)

Comments

0

If I understand your problem - for 11223344 you need 1-12*23-34*4

def DashInsertII(num): 

    prev_even = ( int(num[0])%2 == 0 )

    result = num[0]

    for i in num[1:]:

        curr_even = (int(i)%2 == 0)

        if prev_even and curr_even:
            result += '*'                
        elif not prev_even and not curr_even:
            result += '-'

        result += i

        prev_even = curr_even

    return result

print DashInsertII(raw_input())

2 Comments

After casting number to string, it worked beautifully. Very neat, thanks!
raw_input() gives always string so I removed str() from version in question.

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.