string.replace('the','') is leaving white space - python

I have a string that is the name of an artist that I get from the MP3 ID3 tag
sArtist = "The Beatles"
What I want is to change it to
sArtist = "Beatles, the"
I have running into 2 different problems. My first problem is that I seem to be trading 'The' for ''.
if sArtist.lower().find('the') == 0:
sArtist = sArtist.lower().replace('the','')
sArtist = sArtist + ", the"
My second problem is that since I have to check for both 'The' and 'the' I use sArtist.lower(). However this changes my result from " Beatles, the" to " beatles, the". To solve that problem I just removed the .lower and added a second line of code to explicitly look for both cases.
if sArtist.lower().find('the') == 0:
sArtist = sArtist.replace('the','')
sArtist = sArtist.replace('The','')
sArtist = sArtist + ", the"
So the problem I really need to solve is why am I replacing 'the' with <SPACE> instead of <NULL>. But if somebody has a better way to do this I would be glad for the education :)

Using
sArtist.replace('The','')
is dangerous. What happens if the artist's name is Theodore?
Perhaps use regex instead:
In [11]: import re
In [13]: re.sub(r'^(?i)(a|an|the) (.*)',r'\2, \1','The Beatles')
Out[13]: 'Beatles, The'

One way:
>>> def reformat(artist,beg):
... if artist.startswith(beg):
... artist = artist[len(beg):] + ', ' + beg.strip()
... return artist
...
>>> reformat('The Beatles','The ')
'Beatles, The'
>>> reformat('An Officer and a Gentleman','An ')
'Officer and a Gentleman, An'
>>>

Related

Manipulating list order

I am an artist taking a class on how to manipulate code to make poetry. Python was not supposed to be a prerequisite, but I am not getting it! Please help- we are supposed to make a snowball poem.
Here's the code I have so far:
my_string = "you're going home in a Chelsea ambulance"
counter = 0
new_list = my_string.split()
def make_a_snowball (text):
poem = ' '
for i in text:
poem = poem + "\n" + i
print (poem)
make_a_snowball (new_list)
The result is:
you're
going
home
etc..
I'd like it to look like:
you're
you're going
you're going home
etc...
Any suggestions? Help would be appreciated.
You just need to move the print method inside the loop:
my_string = "you're going home in a Chelsea ambulance"
counter = 0
new_list = my_string.split()
print(new_list)
def make_a_snowball(text):
poem = ' '
for word in text:
poem = poem + ' ' + word
print(poem)
make_a_snowball(new_list)
for i in range(len(new_list)):
print(poem.join(new_list[:i]))
If you want to have your whole poem be stored in one long string, here's how you'd do it:
def make_a_snowball(text):
poem_line = ''
full_poem = ''
for word in text:
poem_line += word + ' '
full_poem += poem_line + '\n'
print(full_poem)
return full_poem
This prints exactly what you want, except all at once rather than line-by-line.
The reason the code is printing each item on a new line is because we are inadvertantly adding a newline character between the terms, when we should be adding a space character.
In the following code, if we replace the \n with a " " and shift the print() function inwards so that it prints every time we loop through the items of the list, then this should work just fine.
my_string = "you're going home in a Chelsea ambulance"
counter = 0
new_list = my_string.split()
def make_a_snowball (text):
poem = ' '
for i in text:
poem = poem + " " + i
print (poem)
make_a_snowball (new_list)
This results in:
you're
you're going
you're going home
you're going home in
you're going home in a
you're going home in a Chelsea
you're going home in a Chelsea ambulance
A couple of additional thoughts.
In your code above, a counter is not necessary.
I like my code to be somewhat self descriptive, so I might replace this:
for i in text:
poem = poem + " " + i
print (poem)
with
for word in text:
poem = poem + " " + word
print (poem)

Beginner question about making a program change based on user input

I'm trying to learn to code and decided to give myself a simple task. It's a madlib game (roses are..., ... is blue, etc..). I want to make the program change '... is blue' to '... are blue' based on use input. So if the use inputs 'my head' the program says 'my head is blue' instead of 'my head are blue.'
I've tried to implement this:
if thing in ['my','your']:
print(thing + " is blue")
else:
print (thing + " are blue")
However the programme only reads 'are' when 'my' or 'your' are written on their own. Is there a way to print something based on whether or not a word is present, not if a certain phrase or word is written?
colour = input ("roses are... ")
thing = input(" ... are blue")
love = input("I love ... ")
print("roses are " + colour)
if thing in ['my','your']:
print(thing + " is blue")
else:
print (thing + " are blue")
print("I love " + love)
You can check if a sub-string is in your list by doing:
if any(word in thing for word in ['my', 'your'])
pretty self explanatory:
it's a for loop that just returns true or false. it basically looks at your variable thing which is storing a string, checks if it's also within your list
So full code:
colour = input ("roses are... ")
thing = input(" ... are blue ")
love = input("I love ... ")
print("roses are " + colour)
if any(word in thing for word in ['my', 'your']):
print(thing + " is blue")
else:
print (thing + " are blue")
print("I love " + love)

Putting quotation marks inside a string

def add_div(filename, caption):
test = str(filename)
return ('<div><img src=' + test + '><br><p>' + caption + '</p></div>')
def add_body(image_dict, s, order = None):
'''(dict of {str:list of str}, str, list) -> str
If the third parameter is passed, then the filenames
included in the body should only be those in the list and should be added
in the same order as they are listed in the list. '''
new = ''
s = '<html><head></head>'
while order is None:
for (key, value) in image_dict.items():
new += add_div(str(key), str(value[2]))
return (s + '<body><div id="slideshow">' + new + '</body>'+ '</html>')
The output of add_body function is:
how do I get quotation marks around the word images/skater.jpg ?
this is what the file looks like
You have two separate options:
1) Use double quotes
print("Hey that's pretty cool!")
2) Escape the single quotation mark
print('Hey that\'s pretty cool!')
You can include the quotation marks in the string that you are concatenating like this :
def add_div(filename, caption):
test = str(filename)
return ('<div><img src="' + test + '"><br><p>' + caption + '</p></div>')
Use one type of quotation for the string definition and the other for the included quotes:
>>> "bob said: 'hello'"
"bob said: 'hello'"
>>> "I said 'yo bob, how u doing?' in reply"
"I said 'yo bob, how u doing?' in reply"
So to fix your problem, just change the return statement in the first function to:
return ('<div><img src="' + test + '><br><p>'" + caption + '</p></div>')
Note that as a final thing, the parenthesis in the return statement aren't required as return is a not a function or method.
Good answers, but another method is to escape the single or double quotation mark with \
Example:
# this is the same as
# s = "'"
s = '\''
print(s)
#this is the same as
# s = '"'
s = "\""
print(s)

Returning contents of a text file and printing different value

I am making a Recipe book, at the moment I have the ability to create a recipe, but now I am starting to build the module of searching and displaying stored recipes.
At the moment I have a .txt document with the contents along the lines of:
Williams Special Recipe
Ingredients:
bread: 120 grams
butter: 1234 grams
Recipe Serves: 12
I then ask the user how many they are serving and based on how many the recipe serves, I need to multiply all the ingredients quantity by that number. I then need to print that off with the full recipe again.
I was wondering how I would go about achieving this result, not asking specifically for a coded response as an answer, but I would greatly appreciate how I would approach this task and any specific functions required.
I have also included my code so far, I appreciate the fact it is incredibly un-organised at the moment, and probably hard to understand, but I included it for any reference.
(I have also created a .txt file of all the created recipes which will be implemented later on as a way of displaying to the user all recipes, but at the moment it is just set up for searching.)
#Recipe Task
import os.path
def file_(n):
if n == "listR" :
list_f = open("list_recipes.txt", "a+")
list_f.write(new_name + "\n")
if n == "oar": #open append read
f=open(new_name + ".txt","a+")
elif n == "c": #closes file
f.close()
def print_line(x): #ease of printing multiple lines to break up text
for c in range(x):
print ""
def new_ingredients(): #adding new ingredients
f.write("Ingredients:" + "\n" + "\n")
fin_ingredient = False
while fin_ingredient != True :
input_ingredient = raw_input("New ingredient:" + "\n").lower()
split_ingred = input_ingredient.split()
if input_ingredient == "stop": #stops asking questions when user types 'stop'
fin_ingredient = True
else :
f.write(split_ingred[0] + ":" + " " + split_ingred[1] + " " + split_ingred[2] + "\n")
def search_recipe(n): #searching for recipes
n = n + ".txt"
if os.path.isfile('/Users/wjpreston/Desktop/' + n) == True :
print "Recipe Found..."
found_recipe = open(n)
print found_recipe.read()
append_serving = raw_input("Would you like to change the number of people you are serving?" + "\n").lower()
if append_serving == "yes" :
appended_serving = input("How many would you like to serve?" + "\n")
with open(n) as f: #here is my issue - not sure where to go with this!!
list_recipe = f.readlines()
found_recipe.close()
else :
print "fail"
else:
print "No existing recipes under that name have been found."
print "Welcome to your Recipe Book"
print_line(3)
recipe_phase = raw_input("Are you 'creating' a recipe or 'viewing' an existing one?" + "\n").lower()
if recipe_phase == "creating":
new_name = raw_input("Name of Recipe: " + "\n")
file_("listR")
file_("oar")
f.write("------------" + "\n" + new_name + "\n" + "\n")
print "Ingrediants required in the format 'ingredient quantity unit' - type 'stop' to end process"
new_ingredients()
new_num = input("Number serving: ")
f.write("\n" + "Recipe Serves: " + str(new_num) + "\n" "\n" + "\n")
file_("c")
elif recipe_phase == "viewing":
search = raw_input("Search for recipe: ")
search_recipe(search)
I'm not the specialist in processing strings, but I'd approach your problem following way:
Save each ingredient on a new line.
Split the loaded string by "\n".
Then process the list with some for-loops while creating two dicts, one for the actual data
e.g. {"bread": 4, "butter": 7}
and one for the types of each ingredient:
e.g. {"bread": grams, "butter": grams}
The you should also save how many serves the recipe is written for, and maybe the order of the ingredients (dicts get stored in a random order):
e.g. ["bread", "butter"]
After that, you can ask your costumer how many serves he has and then finally calculate and print the final results.
for ing in ing_order:
print ing+":", ing_amount[ing]*requested_serves/default_seves, ing_types[ing]
...hopyfully you still have enough challange, and hopefully I understood your question correctly.

Dictionary Writing and Hard-Coded Entries

TypeError: Can't convert 'NoneType' object to str implicitly. That is the error I get when I try to hard-code an entry into a dictionary by using a function. Having user input works, and puts it into the dictionary, but this won't work. I've searched for other errors such as this(meaning the TypeError.), but I have come up with nothing. The other two(This and this) entries that had this error were irrelevant to me.
So. I tried to make AweInspiring and BeingAwesome a print function thinking it would print properly into the Achievements dictionary because simply putting AweInspiring and BeingAwesome there would lead to it saying it needs to be defined. Then it turned up this error. I think it should work, but it doesn't and I don't know why. Can anybody help me?
achievements = {}
AweInspiring = print()
BeingAwesome = print()
def dovar():
global achievements
print('Type in either \'achievement get\' or \'view achievements.\'')
achieve = input()
if achieve == 'view achievements':
print('Achievements')
for x in achievements.keys():
print('Achievement Name: ' + x + '\tFor: ' + achievements[x])
elif achieve == 'achievement get':
achieveget()
elif achieve == 'achieve':
hardachieve()
def achieveget():
print('Add Achievement')
achievename = input('Name of achievement earned: ')
achievedesc = input('How was the achievement earned: ')
achievements[achievename] = achievedesc
dovarloop()
def hardachieve():
achievename = AweInspiring
achievedesc = BeingAwesome
achievements[achievename] = achievedesc
dovar()
def dovarloop():
dovar()
dovar()
print() does not return anything (by default, it returns None). So then when you do achievements[achievename] = achievedesc, python is actually making this:
{None:None}
Then you're doing:
print('Achievement Name: ' + x + '\tFor: ' + achievements[x])
Where x is the key None and achievements[x] is the value (which is also None)
But you can't concatenate a string and a NoneType (hence the error).
So pretty much, your code in simplest form (as an example), you're trying to do this:
print('Hello' + None)
To solve this, you can make AweInspiring and BeingAwesome empty strings:
AweInspiring = ''
BeingAwesome = ''
Edited it in my Idle, added an achievements, and ended up being proud of myself, because it works fine for me:
achievements = {}
def dovar():
global achievements
print('Type in either \'achievement get\' or \'view achievements.\'')
achieve = raw_input()
if achieve == 'view achievements':
print('Achievements')
for x in achievements.keys():
print('Achievement Name: ' + x + '\tFor: ' + achievements[x])
elif achieve == 'achievement get':
achieveget()
elif achieve == 'achieve':
hardachieve()
def achieveget():
print('Add Achievement')
achievename = raw_input('Name of achievement earned: ')
achievedesc = raw_input('How was the achievement earned: ')
achievements[achievename] = achievedesc
dovarloop()
def hardachieve():
global achievments
achievename = "got a cat"
achievedesc = "found one"
achievements[achievename] = achievedesc
#dovar()
def dovarloop():
dovar()
dovar()
My conversation:
================================ RESTART ================================
>>>
Type in either 'achievement get' or 'view achievements.'
achievement get
Add Achievement
Name of achievement earned: got a cat
How was the achievement earned: found one
Type in either 'achievement get' or 'view achievements.'
view achievements
Achievements
Achievement Name: got a cat For: found one
>>>
>>> ================================ RESTART ================================
>>> hardachieve()
>>> achievements
{'got a cat': 'found one'}

Categories

Resources