0

The code was too long to past here, so it's on PasteBin: http://pastebin.com/UDPFYsLJ

What I want to happen is to be able to put in something like "555-GET-FOOD" and get "555-438-3663".

I have the code changing the letters to numbers...just on completely different lines. Here's a small excerpt:

Number:  555-GET-FOO3
Number:  555-4ET-FOOD
Number:  555-GET-3OOD

It's changing the letters correctly and leaving the numbers alone, but it's all on different lines. I know I have it running in a for loop, but I want the changes made to the previous loop to stay with the current loop.

For example, if the first loop returns 555-GET-FOO3, I want the next loop to pick that up so that it could return 555-4ET-FOO3.

I'm just not sure how to do that.

Any tips would be great. I've also been looking over this thread: Removing a list of characters in string

However, I haven't done much (or, well, anything) with the translate function and am having a hard time finding a good walkthrough outside of the Python Docs.

This is for school and we can't use Python 3, we have to use Python 2.7, so I don't think maketranslate will work.

Community
  • 1
  • 1
Chelsea
  • 335
  • 2
  • 13
  • maketrans should work just fine on python2.x ... – mgilson Nov 23 '12 at 20:47
  • @mgilson: though I agree with you, I think OP is a beginner, trying to "learn the ropes". So while references to [`maketrans`](http://www.tutorialspoint.com/python/string_maketrans.htm) and [`str.translate`](http://docs.python.org/2/library/string.html#string.translate) are good references for further reading, I think a good answer should help her see what went wrong with her algorithm. Dis/Agree? – inspectorG4dget Nov 23 '12 at 20:55
  • @inspectorG4dget -- It's always a struggle to find the balance between helping newcomers along vs. creating something that is really useful for others to use in production code in the spirit of SO vs. the spirit of a homework help site. In this case, I believe `maketrans` is an (the?) appropriate tool for the job so I don't want it advertised that "`maketrans` doesn't work in py2.x". I also have a hard time with codes which force me to look at a pastebin because it's too long. Usually boiling down to a minimal example for posting could help OP find her own problem... :.agree and dissagree – mgilson Nov 23 '12 at 20:59
  • @mgilson: do you have 10 minutes? I would like to open a chat with you for an idea I have – inspectorG4dget Nov 23 '12 at 21:05
  • @inspectorG4dget -- I replied to your comment then left my computer. Sorry about that. – mgilson Nov 24 '12 at 01:13

3 Answers3

4

All you have to do is change this

for i, j in dict.iteritems():
    newNumber = phoneNum.replace(i, j)
    print "Number: ",newNumber

to this:

for i, j in dict.iteritems():
    phoneNum = phoneNum.replace(i, j)
    print "Number: ",newNumber

Explanation:

In your method, you replace some characters in the original phone number and assign the result to a new variable called newNumber. But then, you do nothing with newNumber, so it gets thrown away.

Instead, if you overwrite the input (phoneNum) with the result of the translation, then any new translations that you make will be made with the newly overwritten value of phoneNum, thereby making all changes cumulative

inspectorG4dget
  • 110,290
  • 27
  • 149
  • 241
  • Ha, +1 in the context of your comment on the post - I think your answer is better :) – RocketDonkey Nov 23 '12 at 20:56
  • *facepalm* That's what I get for not reading the question properly. Definitely the best answer in context, so +1. – Keith Gaughan Nov 23 '12 at 21:07
  • Ah! Perfect, thank you very much. (: That makes complete sense. I think I was just too close to it to see clearly. (: I'm sure the other answers have a better way of doing it, but they're a bit over my head. As you suspected earlier, I am a beginner; this is my very first semester of Python. – Chelsea Nov 24 '12 at 02:35
1

Assuming you have a mapping of letter to numbers, you could try this:

In [1]: s = '555-GET-FOOD'

In [2]: num_map = {'D': 3, 'F': 3, 'O': 6}

In [3]: reduce(lambda x, y: x.replace(y, str(num_map[y])), num_map, s)
Out[3]: '555-GET-3663'

This works by taking the mapping of letters to numbers (num_map), and then using reduce to iterate through each key (letter) of the mapping, replacing the letter with the corresponding number.

However as this is for school, this approach is probably a bit obscure (in a bad way :) ), and @inspectorG4dget's answer is the one I'd go with.

RocketDonkey
  • 36,383
  • 7
  • 80
  • 84
  • Uh-oh...I've created a reduce monster ;-) – mgilson Nov 23 '12 at 21:00
  • @inspectorG4dget Ha, came up in the context of an answer the other day at the suggestion of mgilson – RocketDonkey Nov 23 '12 at 21:00
  • @mgilson Haha, indeed you have! – RocketDonkey Nov 23 '12 at 21:01
  • In this case (a 1 character substitution), I think I would prefer a simple `join`: `''.join(num_map.get(k,k) for k in s)` – mgilson Nov 24 '12 at 00:11
  • @mgilson Ha, trumped again! Definitely a nicer way to go. I did a quick `timeit` test - I imagine the `join` version is a bit slower due to the overhead of the `get` calls? Or because it is iterating over each character in the string? – RocketDonkey Nov 24 '12 at 00:21
  • @RocketDonkey -- there's a decent amount of overhead with creating a generator expression. You might do better if you used a list-comp instead with timeit. For large enough strings though, I would expect it to do better as the `reduce` solution is essentially `O(N*M)` where N is the size of the string and M is the size of the dict vs `O(M)` for the `join` solution, although I still hold that `maketrans` is probably the fastest :) (though I haven't timed it) – mgilson Nov 24 '12 at 01:17
  • @mgilson Ha, yeah I guess this is more of a second-place test - `maketrans` is definitely the fastest (2x so in a quick test). Yeah, your point on the string length makes sense - good call as usual :) – RocketDonkey Nov 24 '12 at 01:29
0

Try a different tack: rather than replacing the characters, instead create a new string from your input string with the letters translated. You can iterate over the characters of a string like this:

for ch in a_string:
    print ch

Once you can do that it's just a matter of creating a mapping of letters to digits where you can look up a character and find its corresponding digit. If you get a match in the mapping, you use that, if not, you use your original character:

# Map of letters to digits: you'd pad this out.
letter_map = {'G': 4, 'E': 3, 'T': 7, 'D': 3}
def remap_phone_number(original):
    result = []
    for ch in original:
        result.append(letter_map[ch] if ch in letter_map else ch)
    return ''.join(result)
Keith Gaughan
  • 21,367
  • 3
  • 32
  • 30