When do you use if then else or elif in python - python-2.7

When im using python on codecademy the tutorials on there use if(): statement then else(): statement. But sometimes it uses if(): then elif(): statement. I dont understand when your suppose to switch them out or which to use first.
def fruit_color(fruit):
if fruit == "apple":
return "red"
elif fruit == "banana":
return "yellow"
elif fruit == "pear":
return "green"

We could survive in a world in which there was no elif statement. We could do this:
def fruit_color(fruit):
if fruit == "apple":
color = "red"
else:
if fruit == "banana":
color = "yellow"
else:
if fruit == "pear":
color = "green"
# ...
# ....
# ...
# ...
# ...
# ... --->
return color
but it's rather inconvenient that the nesting keeps increasing and increasing---limited only by the number of types of fruit you want to check, which may be large. It makes code hard to follow, and in Python it also means the indentation must keep increasing: soon you won't be able to see all your code within the same screen-width.
The elif statement solves this inconvenience by allowing you to collapse an else followed immediately by an if into a single statement that doesn't require an increase in nesting.

Related

How to avoid repeating the same 'else' statement in multiple nested if/else?

In the code below, 'else' is same for all 'if' statements? Is there a way to have just one 'else' statement, rather than repeating the same code in all 'if' statement blocks for 'else' statement?
Here's example:
if condition A == "Yes":
print("A")
if condition B == "Yes":
print("B")
else:
print("D")
if condition C =="Yes":
print("C")
else:
print("D")
else:
print("D")
Flowchart
In the case of nested if else, you can use a guard type statement. guard is popular in case of nested if-else and provides a clean code.
Guard statement tries to element the else cases first. You know we write else cases to perform deviated paths. So what if we remove the
deviated paths first.
For example, if you have
if condition A == "Yes":
print("A")
if condition B == "Yes":
print("B")
else:
print("D")
if condition C =="Yes":
print("C")
else:
print("D")
else:
print("D")
Now I can formatting the following
// 1
if condiation A == "No" {
print("D")
return
}
// 2
if condition B == "Yes" {
print("B")
return
}
if condition C == "No" {
print("D")
return
}
print("C")
For more follow the link: - Youtube
You look like in a nested testing sequence
You test A
if A ok, you test B
if B ok you test C
if any test fail you print D
so ...
you eitheir leave the testing sequence test everything print all Yes result
or print D if any test fail (wich look like a big ERROR message)
or
you keep the ugly if else sequence
If you go for testing everything
you can create a function
def TestThis(Value, id):
if value == "Yes":
print(id)
return 1
else:
return 0
and call it like this:
if TestThis(A, "A") == 0:
integrity = 1
elif TestThis(B, "B") == 0:
integrity = 1
elif TestThis(C, "C") == 0:
integrity = 1
if integrity == 1:
print("D")
And I'm pretty sure you can find a way to finally get your sequence testing.
Edited to create that sequential testing that was the aim from the start

Faster "switch-case" implementation in python

I made the script below to read a string buffer and distribute the numbers in 6 different variables. I found an example doing the same in C# using switch-case method, and when I tried a similar method in python (as shown below) I got the desired result but it takes too much time to read the buffer (more than a second). This script is just a way to test the method, and it will be a part of a bigger open-loop control code, so the loop time is really important. Is there any faster way to do in in python? I use python 2.7. Thank you in advance.
Julio = '123.5,407.4,21.6,9.7,489.2,45.9/\n'
letter = ''
x_c = ''
y_c = ''
z_c = ''
theta_c = ''
ux_c = ''
uy_c = ''
variable_number = 1
def one():
global x_c
x_c += letter
def two():
global y_c
y_c += letter
def three():
global z_c
z_c += letter
def four():
global theta_c
theta_c += letter
def five():
global ux_c
ux_c += letter
def six():
global uy_c
uy_c += letter
def string_reader(variable_number):
switcher = {
1: one,
2: two,
3: three,
4: four,
5: five,
6: six
}
# Get the function from switcher dictionary
func = switcher.get(variable_number, lambda: 'Invalid variable number')
# Execute the function
print func()
for letter in Julio:
if (letter != '/') and (letter != ',') and (letter != '\n'):
string_reader(variable_number)
elif (letter == '/'):
break
elif (letter == '\n'):
break
else:
variable_number = variable_number + 1
print x_c, y_c, z_c, theta_c, ux_c, uy_c
Err... Aren't you overcomplicating things ?
>>> Julio = '123.5,407.4,21.6,9.7,489.2,45.9/\n'
>>> x_c, y_c, z_c, theta_c, ux_c, uy_c = Julio.strip().rstrip("/").split(",")[:6]

Repeat a function every 5 times a loop runs

Is there a way to repeat a single function in a while loop one in every 5 times the loop runs? I am trying to create a bot to help me with my Latin revision but I don't want the option to close the program to crop up every time I answer a question, it would be better if it only happened 1 out of 10 times.
import random
exit = "no"
print "welcome to latin learner v1"
wordtype = raw_input("what would you like to learn (nouns verbs everything)")
if wordtype == "nouns":
declension = raw_input("declension 1-5")
if declension == "1":
while "no" in exit:
wordno = random.randint(1,30)
noun1L = ["ancilla","aqua","cena","copiae","cura","dea","domina","epistula","femina","filia","hora","ianua","insula","ira","nauta","patria","pecunia","poena","porta","puella","regina","Roma","silva","taberna","terra","turba","via","victoria","villa","vita"]
answer = raw_input(noun1L[wordno])
noun1E = ["slave-girl" or"slave-woman","water","dinner" or "meal","forces" or "troops","care" or "worry","goddess","mistress","letter","woman","daughter","hour","door","island" or "block of flats","anger","sailor","country" or "homeland","money","punishment","gate","girl","queen","Rome","wood","shop" or "inn","ground" or "land" or "country","crowd","street" or "road" or "way","victory","house" or "country villa","life"]
if noun1E[wordno] == answer:
print "correct"
else:
print "incorrect"
print noun1E[wordno]
for i in range[1,5]:
exit = raw_input("would you like to quit (yes/no)")
To solve your issue, we can add a question counter and use the modulus operator (%) to trigger the exit option on every fifth question.
However, there are some other problems to address. For example, this:
,"dinner" or "meal",
is just wishful thinking -- it doesn't work that way. We can turn this into a list of possible answers. Next, whenever we have parallel arrays like noun1L and noun1E, it usually means we're missing a data structure. Finally, don't store the data in the code, separate them.
Here's my rework of your code addressing the above issues:
import random
noun1 = {
"ancilla": ["slave-girl", "slave-woman"],
"aqua": ["water"],
"cena": ["dinner", "meal"],
"copiae": ["forces", "troops"],
"cura": ["care", "worry"],
"dea": ["goddess"],
"domina": ["mistress"],
"epistula": ["letter"],
"femina": ["woman"],
"filia": ["daughter"],
"hora": ["hour"],
"ianua": ["door"],
"insula": ["island", "block of flats"],
"ira": ["anger"],
"nauta": ["sailor"],
"patria": ["country", "homeland"],
"pecunia": ["money"],
"poena": ["punishment"],
"porta": ["gate"],
"puella": ["girl"],
"regina": ["queen"],
"Roma": ["Rome"],
"silva": ["wood"],
"taberna": ["shop", "inn"],
"terra": ["ground", "land", "country"],
"turba": ["crowd"],
"via": ["street", "road", "way"],
"victoria": ["victory"],
"villa": ["house", "country villa"],
"vita": ["life"],
}
print("Welcome to Latin Learner v1")
wordtype = raw_input("What would you like to learn (nouns verbs everything): ")
if wordtype == "nouns" or wordtype == "everything":
declension = raw_input("Declension 1-5: ")
if declension == "1":
count = 1
while True:
word = random.choice(list(noun1))
answer = raw_input(word +": ")
if answer.lower() in noun1[word]:
print("Correct.")
else:
print("Incorrect: " + ", ".join(noun1[word]))
if count % 5 == 0:
answer = raw_input("would you like to quit (yes/no): ")
if "y" in answer.lower():
break
count += 1

Python 2.7, trouble printing docstrings (doc comments) "function has no attribute _doc_" error

I'm working on LPTHW ex 41, where we modify a bunch of print statements to use a docstring style and then use a runner to print them.
The code originally was like this:
Function()
Print "Several lines of printed material"
Revised, the functions begin:
Function()
"""doc comment"""
A runner connects all the functions ("rooms") like so, with the goal being to print doc comments instead of print commands.
ROOMS = {
'death': death,
'central_corridor': central_corridor,
'laser_weapon_armory': laser_weapon_armory,
'the_bridge': the_bridge,
'escape_pod': escape_pod
}
def runner(map, start):
next = start
while True:
room = map[next]
print "\n----------------"
print room._doc_
next = room()
runner(ROOMS, 'central_corridor')
But I keep getting the error
'function" object has no attribute '_doc_'
Example room:
def central_corridor():
"""You wanna blow thing up.
You running toward place for to get bomb.
Emeny approach!
1 = shoot at enemy
2 = avoid emenemeny
3 = use bad pick up line on emenie
4 = hint"""
#print(_doc_)
action = int(raw_input("> "))
if action == 1:
print "He shoot you first."
return 'death'
elif action == 2:
print "No he still gots you."
return 'death'
elif action == 3:
print "Oh yeah sexy boy."
print "You get past laughing enemy."
return 'laser_weapon_armory'
elif action == 4:
print "Emeny like good joke."
return 'central_corridor'
else:
print "You enter wrong input"
return 'central_corridor'
Can anyone tell me how to get the doc comments to print? Thanks!
Noticed doc needs two underscores. Fixed
_doc_
__doc__

Python 2.7: Variable defined in previous function, receiving undefined error

So my variable is clearly defined in inputnfo(), why am I getting an undefined error? The try & except perhaps? I've added removed... swapped it all around and cannot seem to find the solution, and answers online seem very situation based... Thanks in advance :)
Super New & improved edit: now getting UnboundLocalError
import random
alpha = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z']
strgen = []
retry = 0
### Defining
def inputnfo():
global much
much = input('how long do you want your random word/lucky number to be: ')
global which
which = raw_input('would you like letters or numbers?(let,num, or mix?):').lower
def generate():
while much > 0:
if which == 'let':
strgen.append(random.choice(alpha))
much -= 1
print '.'
elif which == 'num':
strgen.append(random.randint(1,9))
much -= 1
print '.'
elif which == 'mix':
mixer = random.choice([0,1])
if mixer == 0:
strgen.append(random.choice(alpha))
much -= 1
print '.'
elif mixer == 1:
strgen.append(random.randint(1,9))
much -= 1
print '.'
def finish():
finito = ''.join(strgen)
print 'Generation Completed!\n'
if which == 'let':
print 'Your randomly generated string is:' + finito
elif which == 'num':
print 'Your randomly generated number is:' + finito
elif which == 'mix':
print 'Your randomly generated Alpha-Numerical string is:' + finito
### Running
inputnfo()
while much != 0:
generate()
finish()
Its because the variable "much" in the function inputnfo() is local to that function alone. that is why you are getting an undefined error in the while loop. there is two solution
1. Make the variable "much" global by including the line
def inputnfo():
global much
try:
and then removing the argument of generate function
Or
2. Let the function inputnfo() return much and use this return value in the while loop and generate function
do the same for variable "which"
and put a line which = "" befor
which = ""
def inputnfo():
global much