Python code formatting - python

In response to another question of mine, someone suggested that I avoid long lines in the code and to use PEP-8 rules when writing Python code. One of the PEP-8 rules suggested avoiding lines which are longer than 80 characters. I changed a lot of my code to comply with this requirement without any problems. However, changing the following line in the manner shown below breaks the code. Any ideas why? Does it have to do with the fact that what follows return command has to be in a single line?
The line longer that 80 characters:
def __str__(self):
return "Car Type \n"+"mpg: %.1f \n" % self.mpg + "hp: %.2f \n" %(self.hp) + "pc: %i \n" %self.pc + "unit cost: $%.2f \n" %(self.cost) + "price: $%.2f "%(self.price)
The line changed by using Enter key and Spaces as necessary:
def __str__(self):
return "Car Type \n"+"mpg: %.1f \n" % self.mpg +
"hp: %.2f \n" %(self.hp) + "pc: %i \n" %self.pc +
"unit cost: $%.2f \n" %(self.cost) + "price: $%.2f "%(self.price)

A multiline string would be more readable:
def __str__(self):
return '''\
Car Type
mpg: %.1f
hp: %.2f
pc: %i
unit cost: $%.2f
price: $%.2f'''% (self.mpg,self.hp,self.pc,self.cost,self.price)
To maintain visually meaningful indentation levels, use textwrap.dedent:
import textwrap
def __str__(self):
return textwrap.dedent('''\
Car Type
mpg: %.1f
hp: %.2f
pc: %i
unit cost: $%.2f
price: $%.2f'''% (self.mpg,self.hp,self.pc,self.cost,self.price))

You can solve the problem by putting the expression in parenthesis:
def __str__(self):
return ("Car Type \n"+"mpg: %.1f \n" % self.mpg +
"hp: %.2f \n" %(self.hp) + "pc: %i \n" %self.pc +
"unit cost: $%.2f \n" %(self.cost) + "price: $%.2f "%(self.price))
However, I'd consider writing it more like this: (code untested)
def __str__(self):
return """\
Car Type
mpg: %(mpg).1f
hp: %(hp).2f
pc: %(pc)i
unit cost: $%(cost).2f
price: $%(price).2f """ % self.__dict__

Python doesn't let you end a line inside an expression like that; the simplest workaround is to end the line with a backslash.
def __str__(self):
return "Car Type \n"+"mpg: %.1f \n" % self.mpg + \
"hp: %.2f \n" %(self.hp) + "pc: %i \n" %self.pc + \
"unit cost: $%.2f \n" %(self.cost) + "price: $%.2f "%(self.price)
In this case, the backslash must be the last character on the line. Essentially, it means "ignore the fact that there's a newline here". Or in other words, you're escaping the newline, since it would normally be a significant break.
You can escape an otherwise significant newline at any time with a backslash. It would be silly, but you could even do
def foo():
return \
1
so that foo() would return 1. If you didn't have the backslash there, the 1 by itself would cause a syntax error.

It require a little extra setup, but a data-driven approach (with a good dose of vertical alignment) is easy to grok and modify as a project evolves. And it indirectly eliminates the problem of long lines of code.
def __str__(self):
dd = (
("Car Type %s", ''),
(" mpg: %.1f", self.mpg),
(" hp: %.2f", self.hp),
(" pc: %i", self.pc),
(" unit cost: $%.2f", self.cost),
(" price: $%.2f", self.price),
)
fmt = ''.join("%s\n" % t[0] for t in dd)
return fmt % tuple(t[1] for t in dd)

Related

python: function with parameters and gather input then print return value

I'm currently going through beginner Python course in EDX and need help on one of its Required Coding Activity.
Program:
fishstore()
create and test fishstore()
fishstore() takes 2 string arguments: fish & price
fishstore returns a string in sentence form
gather input for fish_entry and price_entry to use in calling fishstore()
print the return value of fishstore()
example of output: Fish Type: Guppy costs $1
def fishstore():
fish_entry = input("Input fish ")
price_entry = input("Input price ")
return "Fish Type: " +str(fish_entry) + " costs " + str(price_entry)
a = fishstore()
print (a)
This is the whole code... What part did you not understand?
def fishstore(fish,price):
return ("Fish Type: "+ fish.capitalize() + " costs $" + price)
fish_entry=input('Enter fish type: ')
price_entry=input('Enter fish type price: ')
print (fishstore(fish_entry,price_entry))
This one works.

Syntax Error in function

I'm trying to call my function overwatch. It should print out bastion and lucio.
My code looks right to me. However I'm getting a couple errors and I don't know why I'm getting an error.
def overwatch(hero1, hero2):
print("hello " + hero1 "and " hero2)
overwatch(bastion, lucio)
You missed two + signs and quotes around your string literals.
def overwatch(hero1, hero2):
print("hello " + hero1 + " and " + hero2)
overwatch('bastion', 'lucio')
First of all you want bastion and lucio as a string variable, so you need to use overwatch('bastion','lucio'). Furthermore in your print statement you need to add a plus-sign:
print("hello " + hero1 "and "+ hero2)
The Error, you are seeing is:
print("hello " + hero1 "and " hero2)
^
SyntaxError: invalid syntax
and the solution is easy:
you should edit your code:
1) print("hello " + hero1 + "and " + hero2)
2) overwatch("bastion", "lucio")

Looping and saving multiple inputs

I'm trying to loop through a set of inputs where I ask for a user's course grade, course hours and course code. The loop keeps on repeating until the user enters "done". Once the user has entered done I want it to print out the entered courses with grade and hours.
For Example:
course_count = False
#LOOP through Inputs
while not course_count:
#GET course code
course_code = input( "Please Enter the Course Code (or done if finished): " )
#IF course code is not equal to done (convert to lowercase)
if course_code.lower() != "done":
#GET course hours
course_hours = int( input( "How many credit hours was " + course_code + "? " ) )
#GET grade earned
course_grade = float( input( "What grade did you earn in " + course_code + "? " ) )
#ELSE END LOOP
else:
course_count = True
print("Course: " + course_code + " Weight: " + str( course_hours ) + " hours " + "Grade: " + str( course_grade ) + "%")
The problem is it will always print out only one inputted course, hour and grade. How would I save more than one answer using only accumulative strings?
The output I'm looking to make is:
# Please Enter the Course Code (or done if finished): COMP 10001
# How many credit hours was COMP 10001? 5
# What grade did you earn in COMP 10001? 75
# Please Enter the Course Code (or done if finished): COMP 20002
# How many credit hours was COMP 10001? 8
# What grade did you earn in COMP 10001? 95
# Please Enter the Course Code (or done if finished): done
# Course: COMP 10001 Weight: 5 Grade: 75%
# Course: COMP 20002 Weight: 8 Grade: 95%
It's for a school practice problem and were not allowed to use lists, arrays or dictionaries if that makes sense
You may find it useful to keep your information in a dictionary structure where the key is stored as the course code. Then it is as simple as iterating over each course saved in your dictionary to get the details.
Example:
course_count = False
course_info = {}
#LOOP through Inputs
while not course_count:
#GET course code
course_code = input( "Please Enter the Course Code (or done if finished): " )
course_info[course_code] = {};
#IF course code is not equal to done (convert to lowercase)
if course_code.lower() != "done":
#GET course hours
course_hours = int( input( "How many credit hours was " + course_code + "? " ) )
course_info[course_code]['hours'] = course_hours;
#GET grade earned
course_grade = float( input( "What grade did you earn in " + course_code + "? " ) )
course_info[course_code]['grade'] = course_grade
#ELSE END LOOP
else:
course_count = True
For course_code in course_info :
course_hours = course_info[course_code]['hours']
course_grade = course_info[course_code]['grade']
print("Course: " + course_code + " Weight: " + str( course_hours ) + " hours " + "Grade: " + str( course_grade ) + "%")
See if you can relate this simplified example to your code. To get the output you describe, you need to store the output text somehow and access it later:
output_lines = []
for i in range(10):
input_string = input("Enter some input")
output_lines.append(input_string)
for output_line in output_lines:
print(output_line)
From the comments, using only string "accumulation" (warning: quadratically bad):
output_text
for i in range(10):
input_string = input("Enter some input")
output_text = output_text + '\n' + input_string
print(output_text)
Note that the preferred way to build up a long string is to append to a list and use 'separator'.join(list_of_strings) or print one-by-one as above.
Use an output string output_string
Add each new line to the output string
...
output_string += "Course: {} Weight: {} hours Grade: {}\n".format(course_code, course_hours, course_grade"
#ELSE END LOOP
...
This accumulates the information into a string, using standard string formatting to insert the data from each pass through the loop.
At the end of the program, print the output string.
As others have noted, this is a pretty silly way of storing data, since accessing it, except to print out, will be difficult. Lists/dictionaries would be a lot better.

Return value doesn't work in Python 3 [duplicate]

This question already has answers here:
How do I get a result (output) from a function? How can I use the result later?
(4 answers)
Alternatives for returning multiple values from a Python function [closed]
(14 answers)
Closed 3 years ago.
It seems like I can't pass a value from a function to another even though I have put a return statement in the 1st function.
This is my code:
price=0
TotalPrice=0
def SumPrice(price,TotalPrice):
if cup_cone=="cup":
price=(price+(mass/10)*0.59)*TotalSet
else:
if cone_size=="small":
price=(price+2)*TotalSet
else:
if cone_size=="medium":
price=(price+3)*TotalSet
else:
price=(price+4)*TotalSet
if Member_Ans=="yes":
TotalPrice=TotalPrice+price*0.90
print(price,TotalPrice)
return (price)
return (TotalPrice)
def PrintDetails(price,TotalPrice,Balance):
SumPrice(price,TotalPrice)
if Member_Ans=="yes":
print("Member ID: ", loginID, " (" , Username, ")")
for element in range (len(UserFlavor)):
print (UserFlavor[element], "--- ", UserFlavorPercentage[element], "%")
print ("Total set = ", TotalSet)
print ("Total price = RM %.2f" % (price))
if Member_Ans=="yes":
print ("Price after 10% discount = RM %.2f" % (TotalPrice))
while True:
Payment=int(input("Please enter your payment: "))
if Payment<TotalPrice:
print("Not enough payment.")
if Payment >= TotalPrice:
break
Balance=Balance+(Payment-TotalPrice)
print(Balance)
PrintDetails(price,TotalPrice,Balance)
When I try to print the price and TotalPrice, it prints 0, why?
You are trying to use return twice, which is not allowed (your function will end as soon as it reaches the 1st return statement, making the other one useless).
You can, however, return both values in one statement:
return (price, TotalPrice)
And then assign the value to a tuple or anything else you would like:
my_tuple = SumPrice(a, b)
or
var1, var2 = SumPrice(a, b)
Your second return statement of first function is not reachable! btw try to not use global variables in your code, instead access return values of your first function.
def SumPrice():
price = 0
TotalPrice = 0
if cup_cone=="cup":
price=(price+(mass/10)*0.59)*TotalSet
else:
if cone_size=="small":
price=(price+2)*TotalSet
else:
if cone_size=="medium":
price=(price+3)*TotalSet
else:
price=(price+4)*TotalSet
if Member_Ans=="yes":
TotalPrice=TotalPrice+price*0.90
return price, TotalPrice
def PrintDetails():
price, TotalPrice = SumPrice()
if Member_Ans=="yes":
print("Member ID: ", loginID, " (" , Username, ")")
for element in range (len(UserFlavor)):
print (UserFlavor[element], "--- ", UserFlavorPercentage[element], "%")
print ("Total set = ", TotalSet)
print ("Total price = RM %.2f" % (price))
if Member_Ans=="yes":
print ("Price after 10%% discount = RM %.2f" % (TotalPrice))
while True:
Payment=int(input("Please enter your payment: "))
if Payment<TotalPrice:
print("Not enough payment.")
if Payment >= TotalPrice:
break
Balance=Balance+(Payment-TotalPrice)
print(Balance)
PrintDetails()

Why does this script print an extraneous 'none' in the output

I've written a simple script to help me better understand using classes. It generates a random character for a game. I defined the object and then call a function on that object that prints out the generated character. At the end of the printed block, there is an extraneous "None" that I'm not sure where it's coming from nor why it's being printed. Here's the sample output:
ted
Strength : 20
Dexterity : 17
Hit Points: 100
Aura : 100
Weapon :
Spell :
Item :
Element :
--------------------
None
In my code, the last line of player.stats() is print "-" * 20 which is displayed right above "None". Here's the code that defines the object:
class Player(object):
def __init__(self, name):
self.name = name
self.strength = randint(15, 20)
self.dexterity = randint(15, 20)
self.hit_points = 100
self.aura = 100
self.weapon = " "
self.spell = " "
self.item = " "
self.element = " "
def stats(self):
print "\n"
print self.name
print "Strength : %d" % self.strength
print "Dexterity : %d" % self.dexterity
print "Hit Points: %d" % self.hit_points
print "Aura : %d" % self.aura
print "Weapon : %s" % self.weapon
print "Spell : %s" % self.spell
print "Item : %s" % self.item
print "Element : %s" % self.element
print "-" * 20
The object is then instanced using this:
name = raw_input("Name your character: ")
player = Player(name)
print player.stats()
The complete code can be read here at Pastebin if necessary.
print player.stats()
Is the culprit. player.stats() == None
You want just:
player.stats()
You'd do better to name your function player.printStats().
Another option would be to make it return a string:
def stats(self):
return '\n'.join([
self.name
"Strength : %d" % self.strength,
"Dexterity : %d" % self.dexterity,
"Hit Points: %d" % self.hit_points,
"Aura : %d" % self.aura,
"Weapon : %s" % self.weapon,
"Spell : %s" % self.spell,
"Item : %s" % self.item,
"Element : %s" % self.element,
"-" * 20
])
And then print player.stats() would behave as expected
The stats() method does not return anything. A function that doesn't return anything evaluates to None. Which is what you print.
So, don't print the return value of the function. Just call it. Now, you should rename the function as printStats() to make it clear what it does. And then just call it like this:
def printStats(self):
....
player = Player(name)
player.printStats()
Naming is a really important part of programming. A slightly poor choice of name often leads to confusion like this.
You print the return value of player.stats():
print player.stats()
but the .stats() method does not have a return statement. The default return value of any function or method in python is None, if no return statement has been given:
>>> def foo():
... pass
...
>>> print foo()
None
Either remove the print before the method call, or have stats() return a string to print instead of doing all the printing in the method.

Categories