Getting a value from a Class Object in Python based on User Input - python-3.x

so I'm in the process of learning Python, so forgive any naivety.
I'm doing some practice on Classes - and I'm making it so that when a user input their car - it looks for instantiated objects and then returns the price.
I get it to work okay for "BMW" - but when I try Ferrari - it only return the price for the BMW (20k). I'm thinking it is something not right with the price_check function part of the code.
Please could you provide some guidance here? Code below:
class Car:
car_list = []
def __init__(self, make, model, price):
self.make = make
self.model = model
self.price = price
self.car_list.append(self)
#this is the part of the code that i'm stuck with
def price_check(self):
for i in Car.car_list:
if New_Car.make == self.make:
return i.price
else:
print("Not available")
BMW = Car('BMW', '1 Series', "£20,000")
Ferrari = Car('Ferrari', 'Italia', "£90,000")
New_Car = Car(
input("What is make of your car? "), input("What is the model? "), "")
print("The cost of this car is: ", New_Car.price_check())
So essentially, I want it to return the price of the Ferrari if that's what the user typed.
Thanks in advance. And, sorry for any incorrect formatting, etc...

Okay, I agree with the comments made by #Jarvis regarding errors in your code, I would also add that in Cars init the price is a required variable and should cause an error on instantiation. In addition, in price_check, since the new_car instance has already been added to the list, price_check will also examine that entry and either find None or 0 price, so will never get to the "No Price Available" return. Here's how I would implement the Class
class Car:
car_list = []
def __init__(self, make, model, price=None): #makes providing price optional
self._make = make
self._model = model
self._price = price
Car.car_list.append(self)
#property
def make(self):
return self._make
#property
def model(self):
return self._model
#property
def price(self):
return self._price
#price.setter
def price(self, val):
self._price = val
def price_check(self):
for i in Car.car_list:
if i != self and self.make == i.make and self.model == i.model:
return i.price
return "Not available"

Two issues, first you need to append to the list not bound to your instance but the one bound to your class as a class-attribute:
def __init__(self, make, model, price):
self.make = make
self.model = model
self.price = price
# use the 'class' rather than the 'instance', you need to modify a class-attribute
Car.car_list.append(self)
Second, your issue in price check
def price_check(self):
for i in Car.car_list:
# you need to compare self's make with 'i.make' (elements in list)
if self.make == i.make:
return i.price
else:
print("Not available")

Related

Function not Defined in Class

I am having trouble with a coding project in which I am trying to use classes in python to make a card game (cheat). However, when creating the player class, one of the functions that was previously defined within the class is shown as undefined. I cannot figure out the reason, and any suggestion is appreciated. Below is the definition of the classes
class card(object):
def __init__(self,rank,suit):
self.rank = rank
self.suit = suit
class player(object):
def __init__ (self):
self.number = number
self.hand = list()
#Here, hand is a list of the card class that was distributed with a suit and a rank
def check_card(self,player_rank,player_suit):
for card in self.hand:
if card.rank == player_rank and card.suit == player_suit:
return True
break
return False
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if check_card(self,rank,suit):
print(True)
else:
print(False)
Here is the actual code that will run it
player = player()
player.play_card()
The following error was received:
NameError: name 'check_card' is not defined
I have been troubleshooting and looking at different solutions, including moving the functions outside the class, but it continues to display the same error. Can anyone point out the mistake? Thanks!
You have the following two issues in your code
The way you passed self to the check_card function is wrong. You must call it in this way
self.check_card(rank,suit)
The second issue is that the number is not defined. Thus I passed it as an argument while initializing the player. Feel free to make changes for that.
This is the corrected code :
class card(object):
def __init__(self,rank,suit):
self.rank = rank
self.suit = suit
class player(object):
def __init__ (self, number):
self.number = number
self.hand = list()
#Here, hand is a list of the card class that was distributed with a suit and a rank
def check_card(self,player_rank,player_suit):
for card in self.hand:
if card.rank == player_rank and card.suit == player_suit:
return True
break
return False
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if self.check_card(rank,suit):
print(True)
else:
print(False)
player = player(3)
player.play_card()
Output :
what is the suit?spade
what is the rank?3
False
Based on this document the function call in python class is self.xxxx(args) (xxxx is denoted function name)
therefore the correct version of play_card function is shown as following.
enter code here
def play_card(self):
suit = input('what is the suit?')
rank = input('what is the rank?')
if self.check_card(rank,suit):
print(True)
else:
print(False)

AttributeError: 'ElectricCar' object has no attribute 'battery_size'

i am learning from the book' "Python crash course a handbook". i have written the code exactly as it is in book but still i m getting error. can you please tell me what is the problem with below code:
i m getting 'AttributeError: 'ElectricCar' object has no attribute 'battery_size''.
class Car:
def __init__(self, make, model, year):
self.make=make
self.model=model
self.year=year
self.odometer_reading = 0
def get_discriptive_name(self):
long_name= f"{self.year} {self.make} {self.model}"
return long_name.title()
def read_odometer(self):
"""Print a statement showing the car's mileage."""
print(f"This car has {self.odometer_reading} miles on it.")
def update_odometer(self, mileage):
"""
Set the Odometer reading to the given value.
Reject the change if it attempts to roll the odometer back.
"""
if mileage >= self.odometer_reading:
self.odometer_reading = mileage
else:
print("You can't roll back an odometer!")
def increment_odometer(self,miles):
"""Add the given amount to the odometer reading."""
self.odometer_reading += miles
"""Inheritance from parent/superclass to child/subclass."""
class ElectricCar(Car):
"""Represent aspects of a car, specific to electric vehicles."""
def __intit__(self,make,model,year):
super().__init__(make,model,year)
self.battery_size = 75
def describe_battery(self):
"""Print a statement describing the battery size."""
print(f"This car has a {self.battery_size}-kWh battery.")
my_tesla = ElectricCar('tesla','model s', 2009)
print(my_tesla.get_discriptive_name())
my_tesla.describe_battery()
class ElectricCar(Car):
def __intit__(self,make,model,year):
super().__init__(make,model,year)
self.battery_size = 75
def describe_battery(self):
"""Print a statement describing the battery size."""
print(f"This car has a {self.battery_size}-kWh battery.")
if you take a look you misspelled the init function

how to access to data from a class which is stored in another class in python?

This is my code. I got a problem when i want to print the information inside the class 'pokemon'
class trainer(object):
def __init__(self, name, pokemons = [], money = 0):
self.name = name
self.pokemons = pokemons
self.money = money
this is my first class which has every pokemon per trainer
class pokemon(object):
def __init__(self, name, attribute, attacks = {}, health = '==========='):
self.name = name
self.attribute = attribute
self.health = health
self.attacks = attacks
The other class where I take the pokemon to import to the other class
class fight():
def __init__(self, fighter1, fighter2):
self.fighter1 = fighter1
self.fighter2 = fighter2
def fighting(self):
if len(Trainer1.pokemons) >= 1 and len(Trainer2.pokemons) >= 1:
print('{} wanna fight against {}'.format(Trainer1.name, Trainer2.name))
keepgoing = True
print('{} got this Pokemons: '.format(Trainer1.name))
i = 0
for i in Trainer1.pokemons:
print(i)
#while (keepgoing):
else:
print('You gotta have pokemons to fight')
return False
I thought that creating a class named fight for getting in battle would be the most wise idea but I'd like to know another method to do it
Pokemon1 = pokemon('Charizard', 'Fire', attacks={'1':'ball fire', '2':'cut', '3':'fire blast', '4':'mega kick'})
Pokemon2 = pokemon('Charmander', 'fire', attacks={'1':'blast', '2':'scratch', '3':'heat', '4':'tear'})
Trainer1 = trainer('Santiago', pokemons=[Pokemon1, Pokemon2])
Pokemon3 = pokemon('Charizard', 'Fire', attacks={'1':'ball fire', '2':'cut', '3':'fire blast', '4':'mega kick'})
Pokemon4 = pokemon('Charmander', 'fire', attacks={'1':'blast', '2':'scratch', '3':'heat', '4':'tear'})
Trainer2 = trainer('Alejandra', pokemons=[Pokemon3, Pokemon4])
Okay my problem is in the class fight. when i want to print the names of the pokemons i get the following message:
Santiago got this Pokemons:
<__main__.pokemon object at 0x000002AAD9B64D00>
<__main__.pokemon object at 0x000002AAD9B92DF0>
i know that the pokemon class has various instances, but how can i access to them?
To make your life easier, I recommend that you implement the __str__ dunder method on pokemon. This will resolve the issue that you are seeing right now, and make future prints of pokemon much easier.
That would look something like this:
class pokemon(object):
def __init__(self, name, attribute, attacks = {}, health = '==========='):
self.name = name
self.attribute = attribute
self.health = health
self.attacks = attacks
def __str__(self):
return "Pokemon: %s (Health: %11s)" % (self.name, self.health)
When you print the 'Charmander' pokemon, it'll look something like this:
Pokemon: Charmander (Health: ===========)
Of course, you can change the return of the __str__ to return whatever you want out of the pokemon.

PyQt 5 update list model

I am trying to update listview model in QML quick controls with python. Every item in this model contains address and status property. Right now my code is this:
ListModel:
class ServersModel(QAbstractListModel):
def __init__(self, parent=None):
super(ServersModel, self).__init__(parent)
self.list = []
for address, status in (
("server 1", "green"),
("server 2", "green"),
("server 3", "red")):
self.list.append(server(address, status))
def rowCount(self, parent=QModelIndex()):
return len(self.list)
def data(self, index, role=None):
if role == Qt.DisplayRole: #show just the name
person = self.list[index.row()]
return QVariant(person.name)
elif role == Qt.UserRole: #return the whole python object
person = self.list[index.row()]
return person
return QVariant()
def removeRow(self, position):
self.list = self.list[:position] + self.list[position+1:]
self.reset()
ServerObject:
class server(object):
'''
a custom data structure, for example purposes
'''
def __init__(self, address, status):
self.address = address
self.status = status
def __repr__(self):
return "%s\n%s"% (self.address, self.status)
Python connection handler:
class ServersListViewHandler(QObject):
def __init__(self):
QObject.__init__(self)
listLoaded = pyqtSignal(QAbstractListModel, arguments=['model'])
data_changed = pyqtSignal(QModelIndex, QModelIndex)
# Slot for detecting clicks in listView
#pyqtSlot(str)
def listViewItemClicked(self, name):
self.listLoaded.emit(ServersModel())
And this is my connectin at qml:
Connections {
target: serversListViewHandler
onListLoaded: {
serversListView.model = model
}
}
Address property should go to text as value and status is color of circle. This works fine if I implement model directly to QML but I want to update it dynamically and load it form python. Any ideas on how to accomplish this? I am probably doing it totally wrong but there are almost none tutorial or references about pyqt 5
I'm working on a similar experiment at the moment. I succeeded doing this by using dedicated role names for columns (in my case in the list view).
For your example this would kinda look like this:
class ServersModel(QAbstractListModel):
AddressRole = Qt.UserRole + 1
StatusRole = Qt.UserRole + 2
_roles = {AddressRole: b"address", StatusRole: b"status"}
...
def roleNames(self):
return self._roles
def data(self, index, role=None):
if role == AddressRole: #show just the name
person = self.list[index.row()]
return QVariant(person.name)
elif role == StatusRole: #return the whole python object
person = self.list[index.row()]
return person
return QVariant()
Though this may only target the displaying part, not the complete update procedure. Would be interesting to see the QML where you access the model.
Also I'm not really sure if there is some kind of best practice for this kind of thing.

Sorting a dictionary that contains a class holding 5 variable by one of the class variables

I have a dictionary that contains keys that are made from a class containing 5 variables. I want to sort this dictionary by one of the class vars.
here is what i currently have
class Player:
def __init__(self,name,wins,losses,ties,winpercent):
self.__name = name
self.__wins = wins
self.__losses = losses
self.__ties = ties
self.__winpercent = winpercent
# mutators
def setname(self,name):
self.__name = name
def setwins(self,wins):
self.__wins = wins
def setlosses(self,losses):
self.__losses = losses
def setties(self,ties):
self.__ties = ties
def setwinpercent(self,winpercent):
self.__winpercent = winpercent
# accessors
def getname(self):
return self.__name
def getwins(self):
return self.__wins
def getlosses(self):
return self.__losses
def getties(self):
return self.__ties
def getwinpercent(self):
return self.__winpercent
def displayHighScores(self):
print("\n"," "*2,self.__name," "*(24-len(self.__name)),self.__wins)
def displayplayers(self):
print(self.__name)
I store Players like this:
def addplayer(players):
newName = input("\nEnter new Player name or 9 to quit: ")
wins = "0"
losses = "0"
ties = "0"
winpercent = "0"
if not newName:
print("\nNo name detected try again")
addplayer(players)
elif newName == '9':
print("\nReturning to Options menu")
else:
players[newName] = Player(newName,wins,losses,ties,winpercent)
saveData(players)
return players
Finally i am working on a sorted hi scores list. right now i can print my dictionary unsorted like this:
def printhiscores(players):
print("\n"," "*13,"HiScores")
print(" "*3,"Name"," "*20,"Wins")
if len(players) == 0:
print("\nNo current Players in memory.")
else:
for x in players.keys():
players[x].displayHighScores()
DisplayHighScores () being a part of the class object.
I have been reading on dictionary sorting using
OrderedDict(sorted(players.items(), key=itemgetter(1)))
but this returns edit:TypeError: '<' not supported between instances of 'Player' and 'Player'
Again I am looking to sort my dictionary of players by their win attribute and then print this new order to a high score screen. Any help would be greatly appreciated. I will post if i make any more progress on my own on this.
Your Player instances are not orderable however, as they don't implement comparison methods:
TypeError: '<' not supported between instances of 'Player' and 'Player'
If you wanted to sort them by the value returned, say, wins, then just access that information instead of just returning the value:
OrderedDict(sorted(players.items(), key=lambda kv: kv[1].getwins()))
Otherwise, give your Player class rich comparison methods; methods by which to determine when one instance should be sorted before or after another. You'll also need an equality test. It's easier to just implement support for < (lower then) and equality, then use the #functools.total_ordering decorator to provide the rest:
from functools import total_ordering
#total_ordering
class Player:
def __lt__(self, other):
if not isinstance(other, Player):
return NotImplemented
return self.__wins < other.__wins
def __eq__(self, other):
if not isinstance(other, Player):
return NotImplemented
return self.__wins == other.__wins
The above makes two Player instances equal when their wins are equal, and orders them by that attribute. You'll need to adjust this for your application as needed.

Resources