2
\$\begingroup\$

so as a beginner in Python, I've been utilizing CodeWars to practice everyday alongside my courses, been happy by the results so far, however, what I really am focusing on is the logical thinking side of things and "Thinking like a programmer". I got a question today on codewars that brought me here to ask. Although the end result of the code I wrote was a "PASS" and it worked out, I know for a fact there is a way to write shorter code using ITERATION for the same result.

The Question was to write a function that takes in a string and returns the string with numbers associated with the alphabetical position. My code is below. Again, it worked, but what would you have done differently? And how do I get into the habit of thinking differently to achieve cleaner code?

def alphabet_position(text):

    alphabet = {'a':'1','b':'2','c':'3','d':'4','e':'5','f':'6','g':'7','h':'8','i':'9','j':'10','k':'11','l':'12','m':'13','n':'14','o':'15','p':'16','q':'17','r':'18','s':'19','t':'20','u':'21','v':'22','w':'23','x':'24','y':'25','z':'26'}
    text = text.lower()
    mylist = []

for letter in text:
    if letter in alphabet:
        mylist.append(alphabet[letter])
    else:
        pass

return ' '.join(mylist)
\$\endgroup\$
2
  • 3
    \$\begingroup\$ Why can't you give us the link? \$\endgroup\$ Commented Oct 5, 2020 at 22:28
  • 3
    \$\begingroup\$ The current question title of your question is too generic to be helpful. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How do I ask a good question?. \$\endgroup\$
    – BCdotWEB
    Commented Oct 6, 2020 at 15:41

2 Answers 2

3
\$\begingroup\$

You are already using iteration, by using a for-loop to iterate over the characters in text.

However, programming is about automating tasks. So thinking like a programmer means finding ways to let the computer do things for you, so you don't have to. For example, instead of creating the dict alphabet by hand, which means typing out all 26 characters and their index, you can let the program do this for you, by making use of the chr() and ord() functions, which convert characters to ASCII values and back, respectively:

alphabet = {}
for i in range(26):
    alphabet[chr(ord('a') + i)] = i + 1

But you can write that more compactly using dict comprehension:

alphabet = {chr(ord('a') + i): i + 1 for i in range(26)}

And now you should realize that you actually don't need alphabet, but can convert the characters in text immediately into indices:

mylist = [ord(letter) - ord('a') + 1 for letter in text]

And if you want you can just replace the whole function with:

def alphabet_position(text):
    return ' '.join([ord(letter) - ord('a') + 1 for letter in text])

However, if you feel more comfortable using for-loops, then by all means keep using those. It also helps if you create a function that converts a single letter to an index; this breaks up your code into simpler chunks that are more easy to reason about:

def alphabet_position_of_letter(letter):
    return ord(character) - ord('a') + 1

def alphabet_position(text):
    positions = [alphabet_position_of_letter(letter) for letter in text]
    return ' '.join(positions)

The above is a bit more verbose, but now the function and variable names help describe what everything means.

\$\endgroup\$
2
  • \$\begingroup\$ thank you for the feedback. I haven't gotten to the chapter where we use the chr() and ord() functions. That's probably why I don't understand it \$\endgroup\$
    – hell0jack
    Commented Oct 5, 2020 at 21:01
  • 1
    \$\begingroup\$ ord('a') can be take out as a constant value too. \$\endgroup\$
    – hjpotter92
    Commented Oct 6, 2020 at 7:18
1
\$\begingroup\$

For string operations Python has a neat library called string. You could go like this:

import string

text = "Your text here"
text_in_numbers = list(string.ascii_lowercase.index(letter) + 1 for letter in text.lowercase() if letter in string.ascii_lowercase)

and if you need it as a function, you can abstract it with lambda:

text_to_numbers = lambda(text: list(string.ascii_lowercase.index(letter) + 1 for letter in text.lowercase() if letter in string.ascii_lowercase))

or wrap it it in a def

def text_to_numbers(text: str) -> list[int]:
    return list(string.ascii_lowercase.index(letter) + 1 for letter in text.lowercase() if letter in string.ascii_lowercase)
\$\endgroup\$

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.