1

When I enter a last name, like mcstuff, it prints Welcome Joe Mcstuff!. Instead, I want it to say Welcome Joe McStuff!.

I don't know why the 3rd letter won't capitalize, and I feel like I am doing something obvious wrong.

Here's my code:

#Just defining strings needed for later
Mc = "Mc"
O = "O'"

#What is your name?
name = raw_input('What is your first name? ')
name2 = raw_input('What is your last name? ')

#Setting up the grammar for all of these weirdly typed names
#Lowering all the letters of the names
game = name.lower()
game2 = name2.lower()

#Separating out the rest of the name from the first letter
lame = game[1:len(game)]
lame2 = game2[1:len(game2)]

#The names with the first letter being uppercase
Name = game[0].upper() + lame
Name2 = game2[0].upper() + lame2

#For the names with a Mc in it
#If the first 2 letters of the last name have "MC" or "Mc", they will get edited by this conditional
#The last name is now transformed by adding an Mc to an uppercase 3rd letter (assuming the first to letters are some variation of Mc), and adding in the rest of the letters from the fourth letter
if Name2[0:1] == "mc" or Name2[0:1] == "MC" or Name2[0:1] == "Mc":
    Last_Name = Mc + Name2[2].upper() + Name2[3:len(Name2)]

#For the names with an O'name in it
#If the first letter has an O, it will get edited by this conditional
#Same as the process with the names with an Mc in it, except if they have an O'(name)
elif Name2[0:1] == "O'" or Name2[0:1] == "o'":
    Last_Name = O + Name2[2].upper() + Name2[3:len(Name2)]

#For the regular names, or names not caught by the conditionals
else:
    Last_Name = Name2

#For the liars with fake names, or the people unfortunate enought to have this long of a name
if len(Name) + len(Name2) > 45:
    print "STOP LYING!"

#Lets finally print this beast
else:
    print "Welcome " + Name + " " + Last_Name + "!"
moooeeeep
  • 31,622
  • 22
  • 98
  • 187

3 Answers3

2

You need to check Name2[0:2] instead of Name2[0:1] in order to get the first two characters.

(Here you can find a detailed explanation of Python's slice notation.)

Community
  • 1
  • 1
Falko
  • 17,076
  • 13
  • 60
  • 105
1

You've became a victim of off-by-one error.

Slice notation in Python creates slice in [low, high) range, so closed on lower limit and open on higher limit. Therefore s[0:1] is equal to s[0] and evaluates to single character - m.

Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
1

First, know how to debug your code. Just print all the variables, and see if they contain what you think.

Second, the variable names are very counterintuitive, and you don't need so many of them.

Third, the check for 45 is completely useless. You cannot always expect all possible usecases for your code. Somebody may use it for 10,000-character DNA strings, because you just never know. You have even mentioned in the comments that people might conceivably have longer names. Why make your program fail on long names for no reason other than because you wanted it to do so? Support 1-billion character names; why not? This is not to mention that you shouldn't insult the user with accusations.

Fourth, yes, the issue is an off-by-one error in the indexing. But a deeper issue is that you don't know how to debug your code.

Fifth, your program raises an exception on e.g. empty names because you are not checking if game is not empty before using game[0].

Sixth, don't ever use variables called lame. It gets into your subconscious mind and creates - or shows - a certain attitude towards programming.

Seventh, if at all possible, follow a certain variable name convention. Either use all lowercase (recommended), or if you absolutely must disagree with the rest of the python world, start all of them from a capital letter, but don't keep changing it all the time. And it's a good idea to avoid variable names ending with 2, such as Name2. There are usecases for that, but often it just means that the programmer was too lazy to invent a meaningful name.

Solution:

#What is your name?
first_name = raw_input('What is your first name? ').lower()
last_name = raw_input('What is your last name? ').lower()

def upper_kth_letter(s, k):
    if len(s) > k: # if s[k] exists, i.e. the string is not too short
        return s[:k] + s[k].upper() + s[k+1:]
    else:
        return s

if last_name[:2] in ['mc', 'o\'']:
    last_name = upper_kth_letter(last_name, 2)

first_name = upper_kth_letter(first_name, 0)
last_name = upper_kth_letter(last_name, 0)

print 'Welcome, %s %s!' % (first_name, last_name)
Sergey Orshanskiy
  • 6,794
  • 1
  • 46
  • 50