Python Forum

Full Version: Replacing all letters in a string apart from the first letter in each word
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hey,
I am coding a song guessing game and at the moment i have succeeded. But i have a problem. When the code starts and allows the user to guess the song, it shows the user what the full name of the song is.
For example:
def main():
    playerScore=0
    guessCounter = 0
    # This is where you can change the max turns and guesses
    maxTurns=999999999
    maxGuesses = 2
    while True:
        randNum = int(random.randint(0, 19))
        f=open('Songs.txt')
        linesa=f.read().splitlines()
        g=open('Artists.txt')
        linesb=g.read().splitlines()

        for turnCounter in range(maxTurns):
            randNum = int(random.randint(0, 19))
            f=open('Songs.txt')
            linesa=f.read().splitlines()
            g=open('Artists.txt')
            linesb=g.read().splitlines()

            # Pick a random song:
            print('==============================================')
            randsong =(linesa[randNum])
            randart =(linesb[randNum])
            print(randsong)
            print(randart)
            print('==============================================')
            # Prompt for a guess:
            songGuess = input("What is the song called?\n==============================================\n>> ")
This code would output a random song from a text file but it would out put it like this:

==============================================
Ruin My Life
by Zara Larsson
==============================================
What is the song called?
==============================================
but i would like it to look like this:

==============================================
R___ M_ L___
by Zara Larsson
==============================================
What is the song called?
==============================================

How do i do this exactly? Wall Wall Wall


(If you need the full code then here is the pastebin link: https://pastebin.com/6mzLnfaK)
I observe that you open files many times and never close them. Beside that, why don't you read file content into data structure and work with that?

Regarding question how to get first letter and underscores from string, one way of doing it:

>>> def obscure(song_name):
...     return ' '.join([f'{word[0]}{(len(word) - 1) * " _ "}' for word in song_name.split()])
...
>>> song = 'Ruin My Life'
>>> print(obscure(song))
R _  _  _  M _  L _  _  _
I added empty spaces around underscores for better visibility.

If list comprehension seems complicated then in plain English: give me a string which consists first letter of word and number of underscores corresponding to length of word minus one for every word in song name (this code uses f-strings, but it can be easily done with .format method)
perfringo,
I am not sure how to do that as i am sorta new to python, how would i implement that into my code?
And also how would i "Read file content into data structure"?
I know how to close files but i just didn't see the need of doing it at the time as i will be constantly reading from them.

perfingo,
The code
def obscure(song_name):
    return ' '.join([f'{word[0]}{(len(word) - 1) * " _ "}' for word in song_name.split()])
didnt work...
Invalid syntax
(Jan-14-2019, 09:44 AM)Carbonix Wrote: [ -> ]I am not sure how to do that as i am sorta new to python, how would i implement that into my code?
And also how would i "Read file content into data structure"?
I know how to close files but i just didn't see the need of doing it at the time as i will be constantly reading from them.

You should define the function before you use it (before calling main()). Then on row 25 of your initial code modify print(randsong) to print(obscure(randsong))

There in no point of opening file several times. Especially when you don't close it (quote from unknown source: "not closing a file is a sin and you deserve all bad things which will happen to you as result of that"). Some things what can happen are described in answers to question in Quora and StackOverflow. Usually you open file, grab needed data in suitable format/structure and work with that data (not repeatedly open files without closing them). Good practice is to open files something like this: with open('spam.csv', 'r', encoding='UTF-8') as f:. In this case Python automatically closes file for you.

NB! In order to use f-strings you should have Python version 3.6 or later.
Okay i got that part but im on about the actual code that you gave me
    return ' '.join([f'{word[0]}{(len(word) - 1) * " _ "}' for word in song_name.split()])
does not work, it has an invalid syntax.
and also when i run the code with this
    return ' '.join([f(word[0])((len(word) - 1) * " _ ") for word in song_name.split()])
(which hasn't got the curly brackets and is missing some speech marks)
i get:

Traceback (most recent call last):
File "N:\Yee\A\Py\SongGame - Copy.py", line 146, in <module>
unimportant()
File "N:\Yee\A\Py\SongGame - Copy.py", line 17, in unimportant
mainMenu()
File "N:\Yee\A\Py\SongGame - Copy.py", line 40, in mainMenu
main()
File "N:\Yee\A\Py\SongGame - Copy.py", line 74, in main
print(obscure(randsong))
File "N:\Yee\A\Py\SongGame - Copy.py", line 50, in obscure
return ' '.join([f(word[0])((len(word) - 1) * " _ ") for word in song_name.split()])
File "N:\Yee\A\Py\SongGame - Copy.py", line 50, in <listcomp>
return ' '.join([f(word[0])((len(word) - 1) * " _ ") for word in song_name.split()])
TypeError: '_io.TextIOWrapper' object is not callable


Any chance you could put it into example in my full code? full code is here https://pastebin.com/6mzLnfaK
(I am running python ver 3.4.1)
(Jan-17-2019, 08:50 AM)Carbonix Wrote: [ -> ]Okay i got that part but im on about the actual code that you gave me
Python Code: (Double-click to select all)

return ' '.join([f'{word[0]}{(len(word) - 1) * " _ "}' for word in song_name.split()])
does not work, it has an invalid syntax.

Nope, it works. If you get error then you have something different

def test(song_name):
    return ' '.join([f'{word[0]}{(len(word) - 1) * " _ "}' for word in song_name.split()])

print(test("Nothing Else Matters"))
Output:
N _ _ _ _ _ _ E _ _ _ M _ _ _ _ _ _ >>>
Post your actual code and full traceback you get.


As to the other line you tried - it's really incorrect syntax.
Do i have to be on a specific version of python for this to work because i literally pasted the code you put in into a new python doc and im still getting the error, do i need to import anything?
def test(song_name):
    return ' '.join([f--------->'{word[0]}{(len(word) - 1) * " _ "}'<--------- for word in song_name.split()])
 
print(test("Nothing Else Matters"))
Where i have put the arrows is where the error is happening
Because of using f-strings it will work for 3.6+
in a version before 3.6 you need to replace f-string with format

def test(song_name):
    return ' '.join(['{}{}'.format(word[0], (len(word) - 1) * " _ ") for word in song_name.split()])
 
print(test("Nothing Else Matters"))
this will work also for 3.6+, but f-strings faster and more readble
Well there we have it then, im on version 3.4.1
Thank you
It works now
Aha, I thought you have seen this note in the perfingo's post:

(Jan-14-2019, 11:19 AM)perfringo Wrote: [ -> ]NB! In order to use f-strings you should have Python version 3.6 or later.