I am trying to create a Python program which has the details of power grids and the houses connected to each of those power grids.
I have mainly two tasks to handle, one to add houses to the connection list of each power grid and remove them.
Following is the class for my house:
class House:
def __init__(self, number, power):
self.house_no = number
self.power_required = power
self.assigned_propagator_no = -1
def assign_propagtor(self, number):
self.assigned_propagator_no = number
def __str__(self):
return f"house_no: {self.house_no} power_required: {self.power_required}"
I have a propagator class which is basically used to store all the details and connect between the houses and the power grids:
class Propagator:
def __init__(self, number, max_power):
self.propagator_no = number
self.maximum_power = max_power
self.power_remaining = max_power
self.houses_connected = list()
def __str__(self):
return f"no : {self.propagator_no} max_power: {self.maximum_power} power_remaining: {self.power_remaining}"
def connected_houses_info(self):
for house,_ in self.houses_connected:
print(house)
# check if the house is connected part of the list or not.
def is_house_present(self, house_no):
if house_no in self.houses_connected:
return self.houses_connected.index(house_no)
else:
return -1
# Add the house in the list.
# Before adding check if the house is already connected
def add_house(self, house:House):
if house.assigned_propagator_no != -1:
print('Already exists!')
else:
self.houses_connected.append(house.house_no)
# Remove the house from the list, before removing need to check
# if the house is in the assigned propoagtor list.
def remove_house(self, house_no:int):
pass
Similarly I have created the class for my power grid:
class PowerGrid:
def __init__(self):
self.propagators = dict()
# Adding the propagtor into in the dictionary.
# Check if the propagator is not part of the dictioary already
# It will not posess any value in the beginning.
def add_propagator(self, propagator:Propagator):
pass
# Removing the propagtor into in the dictionary.
# Check if the propagator is part of the dictioary or not
def remove_propagator(self, propagator_no):
pass
def add_house(self, house:House, propagator_no:int):
if propagator_no in self.propagators:
return self.propagators[propagator_no].add_house(house)
else:
return False
def remove_house(self, house_no:int, propagator_no:int):
if propagator_no in self.propagators:
return self.propagators[propagator_no].remove_house(house_no)
else:
return False
class Propagator:
def __init__(self, number, max_power):
self.propagator_no = number
self.maximum_power = max_power
self.power_remaining = max_power
self.houses_connected = list()
def __str__(self):
return f"no : {self.propagator_no} max_power: {self.maximum_power} power_remaining: {self.power_remaining}"
def connected_houses_info(self):
for house,_ in self.houses_connected:
print(house)
# check if the house is connected part of the list or not.
def is_house_present(self, house_no):
if house_no in self.houses_connected:
return self.houses_connected.index(house_no)
else:
return -1
# Add the house in the list.
# Before adding check if the house is already connected
def add_house(self, house:House):
pass
# Remove the house from the list, before removing need to check
# if the house is in the assigned propoagtor list.
def remove_house(self, house_no:int):
pass
The main function to create the power grid is as follows:
def create_power_grid():
power_grid = PowerGrid()
with open('app.csv', newline='') as csvfile: # app.csv image provided later
reader = csv.DictReader(csvfile)
for row in reader:
entity_type = row['Type']
if entity_type == "propagator":
propagator = Propagator(int(row['Entity_Number']), int(row['Power']))
power_grid.add_propagator(propagator)
elif entity_type == "house":
house = House(int(row['Entity_Number']), int(row['Power']))
house.assigned_propagator_no = int(row['Assigned_Propagator'])
power_grid.add_house(house, int(row['Assigned_Propagator']))
return power_grid
if __name__ == "__main__":
power_grid = create_power_grid()
for _, propagator in power_grid.propagators.items():
#Printing the propagator information
print(f"Propagator No : {propagator.propagator_no}")
print("------------Propagator Information-----------------")
print(propagator)
print("------------Connected Houses Information-----------------")
propagator.connected_houses_info()
print("\n")
print("----Removing House 1014 from Propagator 1002----")
if power_grid.remove_house(1014, 1002):
print("House 1014 is successfully removed from Propagator 1002")
else:
print("House 1014 is not connected with Propagator 1002")
print("\n----Removing House 1024 from Propagator 1003----")
if power_grid.remove_house(1024, 1003):
print("House 1024 is successfully removed from Propagator 1003")
else:
print("House 1024 is not connected with Propagator 1003")
I have made certain changes to the add_propagator function inside class PowerGrid as follows:
def add_propagator(self, propagator:Propagator):
if (propagator.propagator_no not in self.propagators.keys()):
self.propagators[propagator.propagator_no] = {}
self.propagators[propagator.propagator_no]['max_power'] = propagator.maximum_power
self.propagators[propagator.propagator_no]['houses'] = []
But I am getting an error:
AttributeError: 'dict' object has no attribute 'add_house'
for the following part:
def add_house(self, house:House, propagator_no:int):
if propagator_no in self.propagators:
return self.propagators[propagator_no].add_house(house)
else:
return False
I have a CSV file from which the values are fed in. The format of the CSV file looks like the following:
I am unable to understand how to define the addition of a house and removal of a house from this, any kind of help with explanation is appreciated.
To have a key correspond to a list in a dictionary in python, note that d[item] is a list::
d = dict()
for item in items_to_add:
if item not in d:
d[item] = []
d[item].append(the_other_item)
# in your case:
if propagator_no not in self.propagators:
self.propagators[propagator_no] = []
self.propagators[propagator_no].append(house)
Your problem is that self.propogators is a dictionary, and therefore has these functions, not add_house.
Related
I am creating a Lottery simulator, and am trying to initialize a Child class (called Checker) with a variable called win_ticket. To obtain this winning ticket, I attempt to call a method which itself belongs to a Root class of Checker.
On the creation of Checker() object: like
c = Checker(),
it appears to successfully initialize c.win_ticket and assign it a winning_ticket, but then it immediately "forgets" it. I have gone step by step through debugging and there is a moment where self.win_ticket does have the correct assignment, but then it forgets it!
It is then of Nonetype, but I can then invoke, c.draw_lottery() myself and only then does it successfully "remember" the variable c.win_ticket.
Could someone explain or point to the idea of why an object on creation appears to assign itself a variable on an init() and then forgets it? Thank you in advance.
class Checker(Ticket):
"""
Will check purchased tickets against the winning ticket drawn from root Class MegaMillion
TODO I can't seem to have self.winticket automatically draw and initialize!
"""
def __init__(self, cost=2) -> None:
super(Checker, self).__init__(cost)
# list of tuples (3,1), (0,1) to match with prize_dict
self.ticket_match_list = []
self.winnings = 0
self.win_ticket = self.draw_lottery()
It is trying to obtain the method from its Parent(or is it called grandparent?) class
class MegaMillions():
""""""
def __init__(self, cost=2) -> None:
self.win_ticket = None
self.cost = cost
def draw_numbers(self, times=1):
"""Return a list of numbers [(a, b, c, d, e), f ] """
number_list = []
for i in range(times):
numbers = (sorted(random.sample(list(range(1, 71)), k=5))
), (random.randint(1, 25))
number_list.append(numbers)
return number_list
def draw_lottery(self) -> list:
"""Draws and sets the lottery winning ticket"""
self.win_ticket = self.draw_numbers()
print(f"\n Tonight's winning ticket is ...: {self.win_ticket}")
logger.info(f"win_ticket is: {self.win_ticket}")
class Ticket(MegaMillions):
"""
Models purchasing tickets.
It can buy_tickets()
Can ask_number_tickets requested and buy them.
"""
def __init__(self, cost=2) -> None:
super().__init__(cost)
self.ticket_list = None
self.ticket_req = None
self.total_tickets_purchased = 0
...extra code...
class Checker(Ticket):
"""
Will check purchased tickets against the winning ticket drawn
from root Class MegaMillion
TODO initialize self.net
TODO I can't seem to have self.win_ticket automatically draw and initialize!
"""
def __init__(self, cost=2) -> None:
super(Checker, self).__init__(cost)
# list of tuples (3,1), (0,1) to match with prize_dict
self.ticket_match_list = []
self.winnings = 0
self.win_ticket = self.draw_lottery()
I have a class I've imported into a Python file. But my code is printing the location of the object not the data stored in the object. It is giving me this output, '<Chapter_10_Program_Exercise_5.RetailItem object at 0x10e281520>' which I think is the location but how can I change that? Here's the code and a picture of the python terminal output.
class RetailItem:
# __init__ method initializes the attributes.
def __init__(self, description, units, price):
self.__item_description = description
self.__units_in_inventory = units
self.__price = price
# The set_item_description method gets the item type.
def set_item_description(self, description):
self.__item_description = description
# The set_units_in_inventory method gets number of items available.
def set_units_in_inventory(self, units):
self.__units_in_inventory = units
# The set_price method gets the cost of item.
def set_price(self, price):
self.__price = price
# The get_item_description method returns the item type.
def get_item_description(self):
return self.__item_description
# The get_units_in_inventory returns the number of items available.
def get_units_in_inventory(self):
return self.__units_in_inventory
# The get_price method returns the cost of item.
def get_price(self):
return self.__price
from Chapter_10_Program_Exercise_5 import RetailItem
class CashRegister:
# The __init__ method initializes the attributes.
def __init__(self):
self.__items = []
def clear(self):
self.__items = []
def purchase_item(self, retail_item):
self.__items.append(retail_item)
print('The item was added to the cash register.')
def get_total(self):
total_cost = 0.0
# for loop
for item in self.__items:
total_cost = total_cost +item.get_price()
return total_cost
def display_items(self):
print('The items in the cash register are:')
for item in self.__items:
print(item)
PANTS = 1
SHIRT = 2
DRESS = 3
SOCKS = 4
SWEATER = 5
def main():
pants = RetailItem('Pants', 10, 19.99)
shirt = RetailItem('Shirt', 15, 12.50)
dress = RetailItem('Dress', 3, 79.00)
socks = RetailItem('Socks', 50, 1.00)
sweater = RetailItem('Sweater', 5, 49.99)
sale_items = {PANTS:pants, SHIRT:shirt, DRESS:dress, SOCKS:socks, SWEATER:sweater}
register = CashRegister()
checkout = 'N'
while checkout =='N':
# Call the get_user_option and it is assigned to the user_option
user_option = get_user_option()
# Sale_items of argument user_option is assigned to the item
item= sale_items[user_option]
# If condition to check the items in the items_in_inventory
if item.get_units_in_inventory()== 0:
print('The item is out of stock.')
else:
register.purchase_item(item)
# New item is updated and it is assigned to the new_item
new_item = RetailItem(item.get_item_description(),
item.get_units_in_inventory()-1,
item.get_price())
# Item is updated according to the user selected option
sale_items[user_option] = new_item
# The user input is assigned to the attribute checkout
checkout = input('Are you ready to check out (Y/N)? ')
print()
print('Your purchase total is:',\
format(register.get_total(),'.2f'))
print()
register.display_items()
register.clear()
# Define the get_user_option() method to print the menu items
def get_user_option():
print('Menu')
print('-------------------')
print('1. Pants')
print('2. Shirt')
print('3. Dress')
print('4. Socks')
print('5. Sweater')
print()
option = int(input('Enter the menu number of the item you would like to purchase: '))
print()
while option > SWEATER or option < PANTS:
option = int(input('Please enter a valid item number: '))
return option
main()
Python Terminal Output
This is how python manages the printing of objects. If you want to print attributes you need to tell python which representation you want for your object.
You can do that by implementing these methods in the object class:
class RetailItem:
.
.
.
def __repr__(self):
return "RetailItem()"
def __str__(self):
return "" + self.__item_description + str(self.__units_in_inventory) + str(self.__price)
Note that the two methods will be automatically called in different situations:
>>> ri = RetailItem()
>>> ri
RetailItem()
>>> print(ri)
description 2.0 13.99
Since all variables within RetailItem are private, you'd
need to use the getter method (get_*()) to grab the info.
So to apply that to your display_items() method:
def display_items(self):
print('The items in the cash register are:')
for item in self.__items:
print("Description: %s, Units in Inventory: %d, Price: %0.2f" %
(item.get_item_description(),
item.get_units_in_inventory(),
item.get_price())
I have a python problem that creates a box and puts items in the box and with the help of the list command I can see what's in my box. One example of the execution may go as:
next command> newbox bedroom-box-05
next command> add bedroom-box-05 pillow 3
next command> list bedroom-box-05
Box "bedroom-box-05" contains 3 items.
3 pillow
There are some issues with class MovingBox() as I cannot change the main functions.
class MovingBox():
"""A class for keeping track of the contents ofa moving box. """
def __init__(self,*args):
self = dict()
def add_item(self,key,value =[]):
setattr(self,key,value)
self.add_item=value
def list_content(self,key,value =[]):
setattr(self, key, value)
self.list_content = value
key1 = Keys() # parens
key1.list_content(value)
DON'T CHANGE ANYTHING AFTER THIS LINE
def convert_str_to_int(word):
"""
Converts the parameter string *word* in to an integer value.
"""
try:
result = int(word)
except ValueError:
return None
return result
def newbox(all_boxes, list_of_additional_info):
if len(list_of_additional_info) != 1:
print("Error: wrong number of initial data: can't create a new box.")
return
box_name = list_of_additional_info[0]
all_boxes[box_name] = MovingBox(box_name)
def add_to_box(all_boxes, list_of_additional_info):
if len(list_of_additional_info) != 3:
print("Error: wrong number of elements: can't add into a box.")
return
box_name, item_name, item_count = list_of_additional_info
item_count = convert_str_to_int(item_count)
if item_count is None:
print("Error: not a number: can't add to a box.")
return
if box_name not in all_boxes:
print("Error: box does not exist: can't add to a box.")
return
all_boxes[box_name].add_item(item_name, item_count)
def list_box_content(all_boxes, list_of_additional_info):
"""Displays the contents of a single box in *all_boxes* """
if len(list_of_additional_info) != 1:
print("Error: wrong number of elements: can't list contents.")
return
box_name = list_of_additional_info[0]
if box_name not in all_boxes:
print("Error: box does not exist: can't list content.")
return
all_boxes[box_name].list_content()
def main():
boxes = {}
while True:
command_line = input("next command> ").strip()
if command_line == "":
break
command_words = command_line.split()
first_word = command_words[0]
list_of_other_words = command_words[1:]
if first_word == "quit":
break
elif first_word == "newbox":
newbox(boxes, list_of_other_words)
elif first_word == "add":
add_to_box(boxes, list_of_other_words)
elif first_word == "list":
list_box_content(boxes, list_of_other_words)
if __name__ == "__main__":
main()
Based on the way this class is being used in the code that you're not supposed to change, I don't think you've understood what the MovingBox is supposed to contain/model. Here are examples of how MovingBox is being used:
MovingBox(box_name)
# creates a box named box_name
all_boxes[box_name].add_item(item_name, item_count)
# increments the count of item_name by item_count
all_boxes[box_name].list_content()
# lists the content of the box
The immediate error you're hitting is that list_content isn't supposed to take a parameter, but the larger problem is that what you've tried to implement doesn't match up at all with what the rest of the code is trying to do -- e.g. your implementation of add_item seems to be trying to add a unique item with an arbitrary value (that defaults to [], which has its own problems), when the calling code is actually providing a count of a type of item.
Since MovingBox is seemingly supposed to just be a counter with a custom interface, I'd implement it as a wrapper around collections.Counter:
from collections import Counter
class MovingBox():
"""A class for keeping track of the contents of a moving box. """
def __init__(self, name: str):
self.name = name
self.contents = Counter()
def add_item(self, name: str, count: int) -> None:
self.contents[name] += count
def list_content(self) -> None:
total = sum(self.contents.values())
print(f'Box "{self.name}" contains {total} items.')
for name, count in self.contents.items():
print(f'{count} {name}')
>>> box = MovingBox("a box")
>>> box.add_item("pillow", 3)
>>> box.list_content()
Box "a box" contains 3 items.
3 pillow
I come from C background currently learning Python. My task is to create a general tree. The input to the program is in two passes. In the first pass I must collect the identity, name, role and dept of a person. In the second pass I get to know the parent of a node, the manager. So I must store the values transiently. In C I would typically use an array of structs or a linked list depending on the availability of the size information. But I am lost here in Python, not even sure if what I am doing is okay let alone efficient.
Thanks in advance,
Preeti.
if __name__ == "__main__":
# Have successfully created the tree and added nodes by hardcoding values as shown below in commented code
# create_tree = Tree()
# Tree.add_node(42, "Stephen", "Time Cone Radiation", "Black Hole")
# But unable to figure out how to store transient info and use it later to create the tree.
num = 8
list = []
backup_num = num
while num:
id, name, role, dept = raw_input().split()
num -= 1
list.append((id, name, role, dept))
while backup_num:
id, parent = raw_input().split()
backup_num -= 1
#For an id in the list above locate it, and call add_node.
# But not sure how and what is an efficient way.
This will give you a fare idea. Hope this helps.
class Tree():
def __init__(self):
self.length = 0
self.data = {}
def add_node(self, nodeid, name, role, dept):
obj = {}
obj["child"] = {"left": None, "right": None}
obj["parent_id"] = None
obj["name"] = name
obj["role"] = role
obj["dept"] = dept
self.data[nodeid] = obj
self.length += 1
return True
# which_one : Left or Right
def update_child_id(self, which_one, nodeid_parent, nodeid_child):
self.data[nodeid_parent]["child"][which_one] = nodeid_child
return True
def update_parent(self, nodeid, parent_id):
self.data[nodeid]["parent_id"] = parent_id
return True
def display_node(self, nodeid):
obj = self.data[nodeid]
print("Node:", nodeid)
print("Parent:", obj["parent_id"], ", Name:", obj["name"], ", Role: ", obj["role"], ", Dept: ", obj["dept"])
def display_child(self, nodeid):
print(self.data[nodeid]["child"].items())
# Main
test = Tree()
# Get the identity and then add here
node_id, name, role, dept = [42, "Stephen", "Time Cone Radiation", "Black Hole"]
test.add_node(node_id, name, role, dept)
# Get the parent id and add here
parent_id, parent = [6, "James"]
test.update_parent(node_id, parent_id)
test.display_node(42)
test.display_child(42)
need a help with Dijkstra. I found a lot of codes on the internet, but I can't use any of them, because I'm not given a graph, but just lists of Vertexes & Edges into createGraph function. It's a homework and I gotta have some attributes in classes.
This is what I have:
class Vertex:
def __init__(self, id, name):
self.id = id
self.name = name
self.minDistance = float('inf')
self.previousVertex = None
self.edges = []
self.visited = False
class Edge:
def __init__(self, source, target, weight):
self.source = source
self.target = target
self.weight = weight
class Dijkstra:
def __init__(self):
self.vertexes = []
self.result = 0
def createGraph(self, vertexes, edgesToVertexes):
for i in range(len(vertexes)):
self.vertexes.append(vertexes[i])
for j in range(len(edgesToVertexes)):
if edgesToVertexes[j].source == vertexes[i].id:
vertexes[i].edges.append(edgesToVertexes[j])
def getVertexes(self):
return self.vertexes
def findMinID(self):
maxDistance = 1000000
curVertex = None
result = None
for i in range(len(self.vertexes)):
self.vertexes[i] = curVertex
if curVertex.visited is False and curVertex.minDistance < maxDistance:
curVertex = result
curVertex.minDistance = maxDistance
else:
pass
self.result = result
return
def computePath(self, sourceId):
start = None
end = None
road = None
while start is None:
if Vertex.id == sourceId:
start = Vertex
start.minDistance = 0
start.visited = True
for i in range(len(start.edges)):
start.edges[i].target = end
start.edges[i].weight = road
if road < end.minDistance:
end.minDistance = start.minDistance + road
end.previousVertex = start.id
else:
pass
self.findMinID()
self.computePath(self.result.id)
I'm still beginner so I tried to keep it simple, but it's not working as it raises error:
'type' object is not subscriptable
or:
AttributeError: type object 'Vertex' has no attribute 'id'
which makes absolutely no sense to me why.
I can use any help, thanks in advance!
When you put the line:
self.vertexes = Vertex
you are assigning the variable to the actual class. Probably what you wanted to do was make an empty list, as you append to it later:
self.vertexes = []
I would assume this is where the error comes from, as if you ever try to iterate over self.vertexes, you are iterating over the Vertex class, which is impossible and throws that error.
You also have later:
start = Vertex
Try initializing the start, like:
start = Vertex(sourceId, "vertex")
Also, the line before that you have
if Vertex.id == sourceId:
meaning that you might want to make the id variable in Vertex static:
class Vertex:
id = 0
def __init__(self, id, name):
self.id = id
id += 1
Some suggestions: class tutorial in python
Edit:
To find the vertex that has the id you want, use a filter:
start = None
for v in self.vertexes:
if v.id == sourceId:
start = Vertex(sourceId, v.name)
start.minDistance = 0
break