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'}
Related
Filename=open('StudentBio.txt','w')
Name=1
fathername=1
Nationality=1
religion=1
if Name==1 and fathername==0 and Nationality==1 and religion==1:
print('You are Eligible for Admission\nCongratualation')
else:
print('Tick All The Above boxes That You Have To fill')
def StudentBiography(Name,fathername,Nationality,religion):
Name=input('Enter Name Of student : ')
fathername=input('Enter Name Of father : ')
Nationality=input('Enter Nationality :')
religion=input('Enter Religion : ')
all_info=[Name,fathername,Nationality,religion]
return all_info
def Grading(Maths,Islamiat,English):
A=Maths+Islamiat+English
B=(A/300)*100
C=[Maths,Islamiat,English]
return (B,C)
for i in range(2):
a=StudentBiography(Name,fathername,Nationality,religion)
f=str(a)
Filename.write(f)
for j in range(2):
Maths = eval(input('Enter no : '))
Islamiat = eval(input('Enter no : '))
English = eval(input('Enter no : '))
b=Grading(Maths,Islamiat,English)
g=str(b)
Filename.write(g)
Filename.close()
please Help me I need Serious Help
From what I can understand you would like to write student information to a text file. First of all, I think you should read more about Python syntax and work on your scripting. For example in Python variables and functions should start with lowercase letters and you need spaces around = sign and things like that. I will try my best to help you out.
def get_student_bio():
name = input('Enter Name Of student : ')
father_name = input('Enter Name Of father : ')
nationality = input('Enter Nationality :')
religion = input('Enter Religion : ')
return ' '.join([name, father_name, nationality, religion])
def get_student_grade():
math = input('Enter no : ')
islamiat = input('Enter no : ')
english = input('Enter no : ')
avg = str(sum(float(math) + float(islamiat) + float(english)) / 3)
return ' '.join([avg, math, islamiat, english])
fileobj = open('StudentBio.txt','w')
for i in range(2):
bio = get_student_bio()
grades = get_student_grades()
fileobj.write(bio + ' ' + grades + '\n')
fileobj.close()
I assume you are trying to enter student bio and grades one by one and write them in a text file. Here is one way you can achieve this. I tried to keep it similar to the way you were doing it so maybe it's easier to understand. I got rid of the initial if statement though because I wasn't sure what you were trying to achieve with that. Anyways, hope this is useful.
I am a beginner and recently started python development.
The code i was working on:
import random
import textwrap
def show_message(dotted_line,width):
print(dotted_line)
print("\033[1m"+ "Attack of clones:" + "\033[0m")
message = (
"The war between humans and their arch enemies , Clones was in the offing. Obi-Wan, one of the brave Jedi on his way ,"
"he spotted a small isolted settlement .Tired and hoping to replenish his food stock , he decided to take a detour."
"As he approached the village, he saw five residence , there was no one to be seen around.He decided to enter" )
print(textwrap.fill(message, width = width))
def show_mission(dotted_line):
print("\033[1m"+ "Mission:" + "\033[0m")
print('\t Choose the hit where Obi wan can rest...')
print("\033[1m"+ "TIP:" + "\033[0m")
print("Be careful as there are Stormtroopers lurking around!")
print(dotted_line)
def occupy_huts():
global huts
huts = []
while len(huts) < 5:
random_choice = random.choice(occupants)
huts.append(random_choice)
def process_user_choice():
message = "\033[1m"+ "Choose the hut to enter (1-5) " + "\033[0m"
uc = input("\n" + message)
index = int(uc)
print("Revealing the occupants...")
message = ""
def reveal_occcupants(index,huts,dotted_line):
for i in range (len(huts)):
occupant_info = "<%d:%s>"%(i+1,huts[i])
if i + 1 == index:
occipant_info = "\033[1m"+ "" + "\033[0m"
message += occupant_info + " "
print("\t" + message)
print(dotted_line)
def enter_huts(index,huts,dotted_line):
print("\033[1m"+ "Entering Hut %d ..." %index + "\033[0m")
if huts[index - 1] == 'clones':
print("\033[1m"+ "There's Stormtrooper Here!!" + "\033[0m")
else:
print("\033[1m"+ "It's Safe here!" + "\033[0m")
print(dotted_line)
def run():
keep_playing = 'y'
global occupants
occupants = ['clones','friend','Jedi Hideout']
width = 70
dotted_line = '-' * width
show_message(dotted_line, width)
show_mission(dotted_line)
while keep_playing == 'y':
huts = occupy_huts()
index = process_user_choice()
reveal_occcupants(index,huts,dotted_line)
enter_huts(index,huts,dotted_line)
keep_playing = raw_input("Play Again?(y/n)")
if __name__ == '__main__':
run()
and the error is in body of
def reveal_occupants.
"TypeError: object of type 'NoneType' has no len()"
how this error can be overcome and please suggest an alternative approach too
Here :
while keep_playing == 'y':
huts = occupy_huts()
Your occupy_huts() function doesn't return anything (it populates a global variable huts but doesn't return it), so the after the huts = occupy_huts() statement huts is now None (the default function return value if you don't explicitely return something). Then you pass this (now None) huts variable to reveal_occupants() :
reveal_occcupants(index,huts,dotted_line)
The solution is simple: modify occupy_huts so instead of working on a global (which is almost always a very bad idea) and returning None, it works on a local variable and returns it:
def occupy_huts():
huts = []
while len(huts) < 5:
random_choice = random.choice(occupants)
huts.append(random_choice)
return huts
While we're at it, you are using a global for occupants too, which is brittle (occupy_huts() will break if called before this variable has been created), while you could just pass it as argument:
def occupy_huts(occupants):
huts = []
while len(huts) < 5:
random_choice = random.choice(occupants)
huts.append(random_choice)
return huts
and then in run():
def run():
keep_playing = 'y'
occupants = ['clones','friend','Jedi Hideout']
# ...
while keep_playing == 'y':
huts = occupy_huts(occupants)
The funny thing here is that you pass arguments for mundane stuffs that are mostly constants and have no impact on the program's logic (ie dotted_lines), but use globals for the important things - should really be the other way round (declare dotted_lines as a pseudo_constant at the start of your module and don't bother passing it to functions) ;)
Also, note that you have a similar issue with process_user_choice() here :
while keep_playing == 'y':
huts = occupy_huts()
index = process_user_choice()
since your process_user_choice() function doesn't return anything either. You should modify it so it returns its local variable index.
len() method accepts an object as parameter.
in your case, at line 43, huts may be None, so you can get an error.
you should insert if condition like below after line 42
if huts is None:
return
My guess is that "huts" is None-type, because occupy_huts() was never called. Or there is an issue with the scope of the "huts" variable -- this might be cleared up by declaring it as an empty set outside of the occupy_huts() function.
Also, you could take advantage of Python's syntax and change line 43 to "for hut in huts:". If you also need the index of the hut, try "for hut, i-hut in enumerate(huts):".
You method "reveal_occupants" receive empty value as huts. That means, that type of huts is None. That why you can't get len of this value.
I have a program that maintains a flat file database of cd information. I am trying to write a function that updates the database. In this function I am checking to see if the artist exists and if so, appending the album name to this artist, but for some reason it will not see that the artist I type in already exists. I made sure that I type it in exactly like it is in the dictionary but for some reason python will not see that it is there. Why would this be happening? I have included sample input as well as the python program. Any help would be greatly appreciated.
import sys
def add(data, block):
artist = block[0]
album = block[1]
songs = block[2:]
if artist in data:
data[artist][album] = songs
else:
data[artist] = {album: songs}
return data
def parseData():
global data
file='testdata.txt'
data = {}
with open(file) as f:
block = []
for line in f:
line = line.strip()
if line == '':
data = add(data, block)
block = []
else:
block.append(line)
data = add(data, block)
return data
def artistQry():
global artists, usrChoiceArt, albums, usrChoiceAlb, usrArtist
artists=sorted(data.keys())
for i in range(0,len(artists)) :
print str(i+1) + " : " + artists[i]
usrChoiceArt = raw_input("Please choose an artist or enter q to quit:")
if usrChoiceArt=='q' :
print "Quitting Now"
exit()
else :
albumQry()
def albumQry():
global artists, usrChoiceArt, albums, usrChoiceAlb, usrArtist
usrArtist=artists[int(usrChoiceArt)-1]
albums=sorted(data[usrArtist].keys())
for i in range(0,len(albums)) :
print str(i+1) + " : " + albums[i]
usrChoiceAlb=raw_input("Please choose an album or enter a to go back:")
if usrChoiceAlb=="a":
artistQry()
else:
trackQry()
def trackQry():
global artists, usrChoiceArt, albums, usrChoiceAlb, usrArtist
usrAlbum=albums[int(usrChoiceAlb)-1]
tracks=data[usrArtist][usrAlbum]
for i in range(0,len(tracks)) :
print tracks[i]
usrChoiceTrack=raw_input("Enter \"a\" to go back or \"q\" to quit:")
if usrChoiceAlb=="q":
print "Quitting Now"
exit()
elif usrChoiceTrack=="a":
albumQry()
else:
print "Invalid Choice"
trackQry()
def artistExist(Name):
for i in range(0,len(data.keys())):
if Name==data.keys()[i]:
return True
else:
return False
def updData():
artistName=raw_input("Please enter an artist name:")
albumName=raw_input("Please enter an album name:")
trackList=raw_input("Please enter the track list seperated by comma's:")
if artistExist(artistName):
data[artistName].append(albumName)
print data[artistName]
elif not artistExist(artistName):
print "Quitting"
exit()
if __name__ == '__main__':
data = parseData()
if sys.argv[1]=='-l':
artistQry()
elif sys.argv[1]=='-a':
updData()
Input data:
Bob Dylan
1966 Blonde on Blonde
-Rainy Day Women #12 & 35
-Pledging My Time
-Visions of Johanna
-One of Us Must Know (Sooner or Later)
-I Want You
-Stuck Inside of Mobile with the Memphis Blues Again
-Leopard-Skin Pill-Box Hat
-Just Like a Woman
-Most Likely You Go Your Way (And I'll Go Mine)
-Temporary Like Achilles
-Absolutely Sweet Marie
-4th Time Around
-Obviously 5 Believers
-Sad Eyed Lady of the Lowlands
In your function artistExist, you return False on the very first iteration! Instead, you must wait until all iterations are finished.
for i in range(0,len(data.keys())):
if Name==data.keys()[i]:
return True
return False
In addition to what Padraic Cunningham says below, the elif here is also redundant:
if artistExist(artistName):
...
elif not artistExist(artistName):
...
If something isn't True, then it can only be False. So really you should just have
if artistExist(artistName):
...
else:
...
And since the function is just a needless one-liner, an even better expression is
if artistName in data:
...
else:
...
Apart from returning too early by returning False in the loop you are doing way too much work, you simply need to use return Name in data:
def artistExist(Name):
return Name in data # will return True or False with O(1) lookup
Every time you call .keys you are creating a list in python2 so your lookup is actually quadratic in the worst case as opposed to 0(1) with the simple return Name in data. A big part of using a dict is efficient lookups which you lose calling .keys. If you actually wanted to iterate over the keys you would simply for key in data, no call to .keys and no need for range.
I don't really know how to explain this exactly.. But I'm making a text adventure for learning the basics. Now I want to make a gold and money system, I am using def... things for different levels and such. but in every prompt I have to put in if the user types gold, or inv it shows the inventory and then go back to the def where it was.. which I find irritating to do every time. And I forget it too at some periods. I want to do it as default in the prompt.
I have a def prompt(): that is this easy code:
def prompt():
x = input('Type a command: ')
return x
and if I put it there it just ends the code. I have to do this in every prompt:
def AlleenThuis():
command = prompt()
if command == '1':
print()
elif command == '2':
print()
elif command == '3':
print()
elif command == '4':
print()
elif command == 'geld': #Actions start here
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
return AlleenThuis()
elif command == 'inv':
if not inv:
print("\n\tYou don't have any items..\n")
return AlleenThuis()
else: #The else has to stay in this place because it's part of the 'if not inv:' guys.
print('\n\t' + str(inv) + '\n')
return AlleenThuis()
#Actions end here
So if there's any way to just implement it so that I don't have to put it in again every time that would be awesome!
Thanks.
EDIT: It looks like you guys aren't understanding what I'm saying, so I have 2 images.
So..
http://i.imgur.com/GLArsyu.png (I can't post pictures yet =[ )
As you can see in this picture, I have included gold and inv.
But in http://i.imgur.com/V3ZhJ36.png I have also done that, so I have coded that in the code again, that is what I Don't want!
I just want to have that in the code 1 time, and let the gold and inventory show all the time when the player enters the commands for them!
On a more fundamental level, the object-oriented paradigm elegantly solves the problem of repetitive code like this:
global gold = 0
def cave():
print "You are in a cave."
print "You have %i gold." % gold
direction = input()
if direction = 'N':
stream()
elif direction == 'S':
house()
elif direction == 'W':
mountain()
elif direction == 'directions':
print "You can go North, West, or South."
else:
print "You cannot go there."
def stream():
print "A small stream flows out of the building and down a gully."
print "You have %i gold." % gold
direction = input()
if direction == 'N':
tree()
elif direction == 'S':
cave()
elif direction == 'directions':
print "You can go North or South."
else:
print "You cannot go there."
def main():
cave()
by turning it into something like this:
class Location:
map = { 'cave': {
'description': 'You are in a cave.',
'directions': { 'N': 'stream', 'S': 'house', 'W': 'mountain' } },
'stream': {
'description':
'A small stream flows out the building and down a gully.',
'directions': { 'N': 'tree', 'S': 'cave' } } #...
}
def __init__ (self):
self.location = 'cave'
def enter (self, direction):
self.location = self.map[self.location]["directions"][direction]
print self.map[self.location]["description"]
def directions(self):
return self.map[self.location]["directions"].keys()
def readable(self, dirs):
readable = { 'S': 'South', 'N': 'North', 'W': 'West', 'E': 'East' }
return [readable[d] for d in dirs]
class Inventory:
def __init__ (self):
self.inventory = { 'gold': 0 }
def query (self):
print "You have %i gold." % self.inventory['gold']
def main:
loc = Location()
inv = Inventory()
while True:
directions = loc.directions()
action = raw_input()
if action in directions:
loc.enter(action)
inv.query()
elif action == 'directions':
where = loc.readable(directions)
print "You can go " + ", ".join(where[:-1])\
+ ", or " + where[-1]
else:
print "You cannot go there."
You will notice that the more modular code is also easier to extend. For example, the inventory can now hold more things than gold, and it's easy to add new commands to query for weapons, potions, etc. Furthermore, it somewhat separates the code from the data, making it less cumbersome and error-prone to add new locations and actions.
Next up, define class Object with subclasses for animate objects, objects you can pick up, immobile objects, etc; and populate the locations with instances of these. Different subclasses can have different interactions defined, and inherit from more basic superclasses which implement fundamentals like take, drop, kill, etc.
What to map into objects is a broad topic, but a few simple guidelines would be to isolate and encapsulate unrelated code into their own classes, and make them as decoupled as possible (code implementing "location" should not need to know pretty much anything about code in "inventory", and vice versa).
Your code for this has some serious structural problems. If I understand correctly, you're trying to accept repeated commands and execute some code to make them function the way you intend.
The problem is that your function to run the game is recursive, so every time you execute a command other than 1, 2, 3, or 4, you're calling your function again without returning from the first one. Eventually, if you enter enough commands, you'll get an error saying that you're recursing too deeply and the game will error out.
What you want is something more like this:
def prompt():
x = input('Type a command: ')
return x
def ProcessAction(command):
if command == '1':
print()
elif command == '2':
print()
elif command == '3':
print()
elif command == '4':
print()
elif command == 'geld': #Actions start here
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
elif command == 'inv':
if not inv:
print("\n\tYou don't have any items..\n")
else:
print('\n\t' + str(inv) + '\n')
#Actions end here
curr_command = None
while curr_command not in ("1", "2", "3", "4"):
curr_command = prompt()
ProcessAction(curr_command)
What this will do is keep asking for new commands and processing them until one of the commands that exits the game is entered.
Edit: From your comment below, it sounds like you're trying to figure out how to display gold and inventory every time a command is entered without requiring a special command to do it. If this is what you're after, you can add print statements to the while loop above to ensure that it's printed before every prompt. In that case, the while loop might look like:
while curr_command not in ("1", "2", "3", "4"):
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
if not inv:
print("\n\tYou don't have any items..\n")
else:
print('\n\t' + str(inv) + '\n')
curr_command = prompt()
ProcessAction(curr_command)
Hope that gets closer to what you're after.
Edit 2: Ok, after reading the full code for your game, I think you might want to consider reorganizing the entire thing. Think about what you want the game to be: the player enters a series of commands and each command does two things, it changes the game's state and it prints out a response based on both the current state and the new state.
So, you should think about processing your commands with a loop like I described. Then, fold all those different functions into ONE ProcessAction(command) function that figures out from the game's state (which you store in variables) what to print out and how to change the state.
If it's a game where you're going room to room, for example, you might keep a global variable room that defines where you are. Your ProcessAction function then follows logic that says "If I'm in room A and the character types this thing then print out B and change room to C, and sets gold to 0."
To make this work well, you'll have to step back and think about the overall "story" of your game, how to store the state in various variables, and how to make your ONE ProcessAction function handle all the possible states and commands that can be issued.
Doing this puts you on the path of developing what's called a "state machine," where you have a simple, general function that looks at a data structure (probably some nested dicts) that you fill up with what each command does when your game is in each state and where to go next, as well as what to print out.
This Wikipedia article describes the concept of a state machine. How you implement it in Python is up to you. I can tell you that if you're careful you should be able to do this without repeating any code. http://en.wikipedia.org/wiki/State_machine
Another edit: Answering a question you placed in the comments below, if you think you have to print out, for example, the value of a player's gold in multiple places, you can do something like this:
def print_gold(gold_value):
print('\n\tYou have ' + str(gold_value) + ' euro. RICH BOY BRO!.\n')
print()
then use print_gold(gold) in place of those print statements whenever you need to do that. However, I think you may want to take a step back and think about rewriting the whole thing with some of the thoughts I've offered before you tackle that problem.
My earlier answer is long and addresses a number of problems in the OP's code, but he's asking about one specific thing, so I thought I'd separate out that answer here.
If you have some code you'd like to repeat multiple times, you might be tempted to copy and paste it around in your code In your case, that would be something like:
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
Wrapping that in a function will allow you to execute that same code anytime you need to do that thing, without copying and pasting. You're already defining functions, so you seem to have the concept down, but this wrapped in a function might look like:
def print_gold(gold_value):
print('\n\tYou have ' + str(gold_value) + ' euro. RICH BOY BRO!.\n')
print()
With this function defined, anytime you place print_gold(gold) in your code, it'll pass the value of gold into that function as the variable gold_value and print it out as you've specified.
So, if for some reason you had code that looked like this:
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
you could turn this into:
def print_gold(gold_value):
print('\n\tYou have ' + str(gold_value) + ' euro. RICH BOY BRO!.\n')
print()
... somewhere else in your code ...
print_gold(gold)
print_gold(gold)
print_gold(gold)
Those three lines are function calls, which tell Python to execute the function you've defined with def.
I am assuming you are currently pasting something into this prompt everytime you want to run your Python program, and your question is about how to avoid that:
The answer to this problem is generally to save your program's code in a whatever.py file and run that file... either by doubleclick or through the terminal. The exact instructions depend on your operating system etc.
If I understood correctly the latest edit to your question, then you might want something like:
def get_gold_or_inv(command):
if command == 'geld': #Actions start here
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
elif command == 'inv':
if not inv:
print("\n\tYou don't have any items..\n")
else:
print('\n\t' + str(inv) + '\n')
while True:
command = prompt()
if command == '1':
print()
elif command == '2':
print()
elif command == '3':
print()
elif command == '4':
print()
get_gold_or_inv(command)
Are you trying to say that you want this to run in an infinite loop until quit?
You can do that either by encapsulating the entire function block with a while True: or just by calling AlleenThuis() after the ifs and elifs. I took the liberty to rewrite your implementation using the first option below.
def AlleenThuis():
while True:
command = prompt()
if command == '1':
print()
elif command == '2':
print()
elif command == '3':
print()
elif command == '4':
print()
elif command == 'geld': #Actions start here
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
elif command == 'inv':
if not inv:
print("\n\tYou don't have any items..\n")
else:
print('\n\t' + str(inv) + '\n')
else:
print("Invalid command")
Hope I didn't misunderstand you.
EDIT:
def action(cmd):
if cmd == 'geld':
print('\n\tYou have ' + str(gold) + ' euro. RICH BOY BRO!.\n')
print()
elif cmd == 'inv':
if not inv:
print("\n\tYou don't have any items..\n")
else:
print('\n\t' + str(inv) + '\n')
else:
# If the command was not found
return False
# If the command was found and the else statement was not run.
return True
Then just run this at the start of every scenario if action(command): return ScenarioName().
Hope that helps!
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'
>>>