Python does not have a construct like switch/case
-
instead, the preferred and simplest way to replace this command, which exists in languages that derived the C syntax, such as Java, Javascript, C ++, C #, among others is to use if
of Python, which in addition of else
also has the expression elif
. The def
keyword you use here is how to declare functions and methods in Python - whose main feature is to precisely isolate the internal variables of the environment from which they were invoked.
After showing the simplest (and recommended) form, I'll comment on what's happening in your code:
print ("ESCOLHA A CERVEJA PELO NUMERO")
print ("1-ANTARTICA R$6.00;2-SKOL R$6.50;3-BRAHMA R$8.20;4-SOL R$8.25;")
cerveja = raw_input ("5-NORTENHA R$16.80;6-PROIBIDA R$4.80;7-DEVASSA R$5.90;8-HEINEKEN R$9.00")
q = float(raw_input("Quantas ???"))
if cerveja=="1":
valor_cerveja = 6 * q
nome = "Antartida"
elif cerveja=="2":
valor_cerveja = 6.5 * q
nome = "Skol"
elif cerveja == "3":
...
else:
nome = None
print "Valor invalido"
if nome:
print (nome,"custa",valor_cerveja,"Reais, por",q,"cerveja(s)")
(I put the code for Python 2.x - if using Python 3.x,
switch "raw_input" back to input)
Then, in "Python," if is used with "elif" for the equivalent switch / case construct: "elif" is an "else if" contraction - which is used in similar situations when swicth case does not work in other languages - because of the nature of Python that defines which code is inside which block by indentation, it was necessary to create that extra keyword.
One advantage of "elif" over the "case" is that you can put any condition on it - whereas the "case" only allows comparisons with constants. (You also do not need a "break" command.)
Now what happened in your code:
you probably looked at some recipe on the internet how to make a switch/case
in Python but copied the incomplete recipe - you wrote several functions that would be the body of each case
independently above - what you can do - just as you can be done in C, Java. etc ... - but did not put any command for any of these functions to be actually called.
If you want to pass the original recipe link where you looked, I can make a more specific comment - but I suspect that after declaring the various functions of the code body the original recipe defined a dictionary, where the comparison constants of the " case "would be the keys, and the functions would be put as values - for your code it would look something like:
escolhas = {"1": case_1, "2": case_2, "3": case_3, "4": case_4 ...}
escolhas.get(cerveja, default) (q)
Notice that it gets pretty complicated and the "if / elif" is preferable. The assembly with the dictionary first retrieves an object from the dictionary, based on its switch variable - for example escolhas["1"]
-
this object is a function, and you can call it - so the call would be escolhas[ cerveja] (q)
- the extra pair of parentheses indicates the call to the function itself. In this example, instead of retrieving the dictionary function with the brackets ("[" and "]") I used the "get" method because in this way you can specify a default value if the key does not exist (what you want to do in "default").
Another detail is that while functions in this way can "see" the contents of q
as a global variable, it is highly recommended that it be passed as a parameter.
Now, besides its construction, because it does not have this part of the code, it does not call any of the functions, there is a problem in your code with the functions themselves: when using def
you define the two variables each in an integer function, and never returns its value - the case_1
function would, for example, be called, would assign the variables, discard those values, and execution would continue, with undefined variables at the point where you called the function. To get around this, you would have to return values of your functions:
def case_1(q):
valor_cerveja = 6 * q
nome = "Antartida"
return valor_cerveja, nome
# ou simplesmente:
def case_2(q):
return 6.5 * q, "Skol"
escolhas = {...}
nome, valor_cerveja = escolhas.get(cerveja, default)(q)
(See more about returning multiple values of a function here )
And last but not least - for what you want in this program, you do not even need to use "if / elif" (ie different code to run for each value, as in "switch / case" ):
the code you want to run is always the same, it just changes the value of beer - this allows you to use a Python dictionary with the data you want - and even more, the data in that dictionary can even be used to print your menu - we use Python's string formatting to include data for each beer on a printed line-
dados = {
1: ("Antártica", 6),
2: ("Skol", 8.5),
3: ("Brahma", 8.20),
...
}
print "Escolha a cerveja: "
for opcao in sorted(dados):
print ("{} - {} (R$ {:.02f})".format(opcao, dados[opcao][0], dados[opcao][1]))
cerveja = raw_input("Opção: ")
if not cerveja.isdigit() or not int(cerveja) in dados:
print("Valor inválido")
else:
qtd = float(raw_input("Quantidade: "))
nome = dados[opcao][0]
valor = dados[opcao][1]
total = qtd * dados[opcao][1]
print ("{nome} custa {valor} reais por {qtd} cerveja{plural}".format(
nome=nome, valor=valor, qtd=qtd, plural=("" if qtd == 1 else "s"))