Print initial letter of an entered name Just started learning python and I'm solving some beginner problems. I wrote a solution for a question without any edge cases like user not entering anything, entering numbers etc.:


  Question: Write a program to print initial letter of an entered name?
  
  Expected output: If the user inputs,
  
  
  Ram Chandra Giri -&gt; R.C.Giri
  Ram chandra Giri -&gt; R.C.Giri
  


My solution works as expected but I would like insight on whether I am following best practice or not and if there is better and easier way to do it. Question is from Class 10 book for students to learn Q-BASIC.

My solution:

def initial_of_name(c):
    word_list = c.split(" ")
    i = (len(word_list) - 1)
    new_list = []
    for w in range(0, i):  # this loop leaves last name and creates a new list.
        word = word_list[w]
        word = word[0:1].upper()  # sliced word into initial letter
        new_list.append(word)
    new_list.append(word_list[-1])  # added last name to the list before joining.
    initial = '.'.join(new_list)
    print("The initial of your name is {0}.".format(initial))
    return


name = input("Please enter your name?\n&gt;")
initial_of_name(name)
In general, I think that's a great start - it's consistently formatted and sensibly structured.



def initial_of_name(c):


c isn't a great name for a parameter, it tells the reader nothing about what the function is expecting to get. It might also be helpful to add a docstring to provide a bit more information.



word_list = c.split(" ")


If you're splitting on spaces, note that you can just use .split(), which will also have the effect of counting consecutive whitespace as a single space. This is helpful if someone accidentally types My  Name instead of My Name; with the current formulation you'd get ['My', '', 'Name'].



i = (len(word_list) - 1)
...
for w in range(0, i):
    word = word_list[w]


Iterating over a list by index in Python is a bit of an anti-pattern, there are lots of better tools for dealing with iteration. In this case, you could iterate over a slice of all but the last item in the list:

for word in word_list[:-1]:




Talking of slicing:

word = word[0:1].upper()


You don't need the 0, that's the default start to a slice, so it could be word[:1]. But what you want is the first character, which is perhaps more clearly expressed as word[0].



new_list = []
for ...:
    ...
    new_list.append(...)


Creating an empty list, iterating and appending is often not the most efficient way to build a new list. Instead, consider a list comprehension (if this is unfamiliar to you, see e.g. Python for-in loop preceded by a variable).



print("The initial of your name is {0}.".format(initial))


In general, I wouldn't use print in a function like this. This is part of separation of concerns; building the appropriate string and displaying the result to the user are two completely different tasks, so they shouldn't be in the same function. Additionally, printing rather than returning the result makes it harder to test the function.



With all of that considered, here's how I would implement the same requirements.

def initial_of_name(name):
    """Converts a name to initials and surname.

    Ensures all initials are capitalised, even if the
    first names aren't.

    Examples:

      &gt;&gt;&gt; initial_of_name('Ram Chandra Giri')
      'R.C.Giri'
      &gt;&gt;&gt; initial_of_name('Ram chandra Giri')
      'R.C.Giri'

    """
    parts = name.split()
    initials = [part[0].upper() for part in parts[:-1]]
    return '.'.join(initials + [parts[-1]])


if __name__ == '__main__':
    name = input("Please enter your name?\n&gt;")
    initial = initial_of_name(name)
    print("The initial of your name is {0}.".format(initial))


If the last part is unfamiliar, see What does if __name__ == "__main__": do?



Note that including examples in the docstring in the form of an interactive Python session not only gives the reader a good idea of exactly how to use the function, but also allows doctest to validate the code and examples for you. If you save the above into a file initial.py:

$ python -m doctest initial.py --verbose
Trying:
    initial_of_name('Ram Chandra Giri')
Expecting:
    'R.C.Giri'
ok
Trying:
    initial_of_name('Ram chandra Giri')
Expecting:
    'R.C.Giri'
ok
1 items had no tests:
    initial
1 items passed all tests:
   2 tests in initial.initial_of_name
2 tests in 2 items.
2 passed and 0 failed.
Test passed.