Python - displaying data when using classes - python

I am looking to work out how to get the name of the budget to appear in the output - the code creates a list (name of budget and budget amount) and appends these as list items to a main list. I realise importing the Budget class to the app file is the way of accessing functionality but I am wondering how to extract the data created within the app file so the repr
def __repr__(self):
return f"The budget is {self.balance}."
can return the name of the budget in the list
I have two files: budget_app.py and another budget_class.py
The app file uses the exec function to append new items to a list
from budget_class import Budget
list = []
def createBudget():
list2 = []
addbudgetname = input("Name the budget:")
exec1 = f"{addbudgetname} = Budget({int(input('How much to add to budget:'))})"
exec(exec1)
exec2 = f"list2.append({addbudgetname})"
exec(exec2)
return(list2)
list.append(createBudget())
list.append(createBudget())
for item in list:
print(item)
The class file initializes the Budget
class Budget():
class Budget():
def __init__(self, balance):
self.balance = balance
def __repr__(self):
return f"The budget is {self.balance}."
I am trying to work out a way of getting the name of the budget to appear in the output, which is currently
How much to add to budget:60
Name the budget:apples
How much to add to budget:800
[The budget is 60.]
[The budget is 800.]

The class structure is suboptimal, I would suggest to make a complete refactor, something as the following:
class Budget():
def __init__(self, balance=0, name=None, list2=[] ):
self.balance = balance
self.name = name
self.list2 = list2
def createBudget(self):
self.name = input("Name the budget:")
self.list2.append(input("How much to add to budget:"))
def add_to_balance(self, to_add):
self.balance += to_add
def __repr__(self):
return f"The budget is {self.balance}. and the name {self.name}"
budget1 = Budget(0,'name1',[1,2])
budget2 = Budget(4,'name2',[1,5])
budged_list = [budget1,budget2]
Now you can instantiate the class directly with the arguments or add them with your input support, you can also print the name etc.

Related

Python. How to define an Items object within my inventoryRead method and then Call the inventoryRead method

In my inventoryRead how can I properly define an Items object. Also, how do I run this method
Traceback (most recent call last):
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 7, in <module>
class Items:
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 34, in Items
inventoryRead('self')
File "C:/Users/jburk/OneDrive/Desktop/Deft Project/quickMart.py", line 24, in inventoryRead
item1 = Items()
NameError: name 'Items' is not defined
code
class Items:
# Constructor to initilize an item object
# An item has name, quantity, price, member price, and taxing status
def __init__(self, name, quantity, price, memPrice, taxStatus):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
def inventoryRead(self):
txt = ""
count = 0
f = open("inventory.txt", "r")
inList = []
item1 = Items()
print(item1)
for line in f.readlines():
item1.name = line[0:line.find(":")]
print(item1)
print(item1.name)
inList[count] = Items()
txt = line.next()
print(txt)
inventoryRead('self')
#arr = f.readlines()
#print(arr[0])
I think it would be smarter if you had an Item and a separate ItemMangager or Items class. I'm going to call it Items from now on.
Items would contain some store every Item in (for example) a list and Items loads them from the file, but also saves them to same.
You try to create an instance of the class you are currently in, the main way you would edit this file is through the self prefix you used before to modify this instances attributes.
The example I provide is done using a .txt file for storage to keep to your way of doing it, although it would probably be smarter to use an actual database module like sqlite, you should have a look into that.
#!/usr/bin/env python3
#Item holds one record of sth
class Item():
def __init__(self,name, quantity, price, memPrice, taxStatus):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
class Item_Manager:
def __init__(self):
self.items=[]
self.data_file_path="records.txt"
def load_data(self):
with open(self.data_file_path,"r") as f:
contents= f.read()
for i in contents.split("\n"): #splits every line into a new string
data=i.split(" ") #asuming every line has the attributes space-separated
item=Item(data[0],data[1],data[2],data[3],data[4])
self.items.append(item) #saving the new created Item instance in the mangagers items list
def save_data(self): #overwriting
with open(self.data_file_path,"w") as f:
for i in self.items: #i = item instance
f.write("{} {} {} {} {}".format(i.name,i.quantity,i.price,i.memPrice,i.taxStatus))
def create_item(self):
name=input("Name: ")
quantity= input("Quantity: ")
price=input("Price: ")
memPrice= input("MemPrice: ")
taxStat = input("Tax Status: ")
item=Item(name, quantity, price, memPrice, taxStat)
self.items.append(item)
def display_data(self):
for i in self.items:
print(i.name,i.quantity,i.price,i.memPrice,i.taxStatus)
Hope this helps, if you have any further questions, just comment under this.
There are two main issues here:
Your code is obviously faulty, see below, and
You have made some strange design choices.
Code Error:
Your error comes from line: inventoryRead('self')
This is wrong because:
you do not write self into a class method call. It is passed by itself.
Your method call is outside of context. It is not part of another method in the class, while it obiously isn't an attribute.
Sort off "working" version of your code would be:
class Items:
''' Constructor to initilize an item object
An item has name, quantity, price, member price, and taxing status'''
def __init__(self, name=None, quantity=0, price=0, memPrice=0, taxStatus=None): # fill the default values or you will have an error in inventory function
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
def inventoryRead(self):
txt = ""
count = 0
f = open("inventory.txt", "r")
inList = []
item1 = Items() # <-- works like this only if you have defaults in your __init__ definition
print(item1)
for line in f.readlines():
item1.name = line[0:line.find(":")]
print(item1)
print(item1.name)
inList[count] = Items()
txt = line.next()
print(txt)
items = Items()
items.inventoryRead()
This would work now but it surelly isn't what you want...
Design choice
You have an Item --> make it a class
You have an inventory? --> make it a class!
Manipulate your code from within Inventory
You should really read some examples and tutorials on python OOP, since it would seem you don't really feel comfortable with how it works.
Now for a quick working example:
#!/usr/bin/env python3
class Item:
def __init__(self,name, quantity=0, price=0, memPrice=0, taxStatus=0):
self.name = name
self.quantity = quantity
self.price = price
self.memPrice = memPrice
self.taxStatus = taxStatus
class Inventory:
def __init__(self):
self.items = []
def inventoryRead(self):
# your function to collect items from file
if __name__ == '__main__':
inventory = Inventory()
inventory.inventoryRead()

Searching for an ID in a list of books

I've made a simple library system which stores books with an ID, name and cost. My question is rather simple but my limited knowledge of python has let me down.
I've created a class that stores books in the library, they are created like this;
if __name__ == '__main__':
lib = Library()
book1 = Book(1, 'Bookname1', "$30")
book2 = Book(2, 'Bookname2', "$10")
book3 = Book(3, 'Bookname3', "$40")
I have to make a function that searches for a book by its ID, by making a function in my library class. I tried to make it like in the code below, but it didn't work. basically, I want to give my function an ID, and it should return the name and cost of that particular book, but only if the ID is present in the list.
class Book:
def __init__(self, ID, name, price):
self.ID = ID
self.name = name
self.price = price
def show(self):
print(self.ID, self.name, self.price)
def get_attribute_string(self):
print(str(self.ID) + '_' + str(self.name) + '_' + str(self.price))
def get_id(self):
print(self.ID)
def get_name(self):
print(self.name)
def get_price(self):
print(self.price)
class Library:
def __init__(self):
self.books = []
def add_book(self, Book):
self.books.append(Book)
def remove_book(self, Book):
self.books.remove(Book)
#def show_id(self, ID):
# if ID in lib:
# return self.books
def show_all(self):
for Book in self.books:
Book.show()
if __name__ == '__main__':
lib = Library()
book1 = Book(1, 'Bookname1', "$30")
book2 = Book(2, 'Bookname2', "$10")
book3 = Book(3, 'Bookname3', "$40")
#1.show_id
lib.add_book(book1)
lib.add_book(book2)
lib.add_book(book3)
lib.remove_book(book2)
lib.show_all()
I think the simplest idea if you need ID indexing is to use a dictionary:
class Library:
def __init__(self):
self.books = dict()
def add_book(self, Book):
self.books[Book.ID] = Book
def remove_book(self, Book):
del self.books[Book.ID]
def get_book(self, ID):
return self.books[ID]
def show_id(self, ID):
self.get_book(ID).show()
def show_all(self):
for Book in self.books.values():
Book.show()
You could even rename get_book to __getitem__, this second name is special in python, it's called a dunder method (or magic method). Implementing it will allow you to write lib[id] instead of lib.show_id(id) (I'm not saying that you should, but that's an option). There are many other dunder methods that you can try using for fun, you can find some of them in the python data model.
I think that you should post your code on codereview as you may use broader advices on your code.
As noted above, there might be better implementations, but using your current code, you can do the below where I have adapted your show_id function according to requirements. It relies on a list comprehension to identify the correct IDs.
Hope this helps!
class Book:
def __init__(self, ID, name, price):
self.ID = ID
self.name = name
self.price = price
def show(self):
print(self.ID, self.name, self.price)
def get_attribute_string(self):
print(str(self.ID) + '_' + str(self.name) + '_' + str(self.price))
def get_id(self):
print(self.ID)
def get_name(self):
print(self.name)
def get_price(self):
print(self.price)
class Library:
def __init__(self):
self.books = []
def add_book(self, Book):
self.books.append(Book)
def remove_book(self, Book):
self.books.remove(Book)
def show_id(self, ID):
# simple list comprehension to filter; note that you might need to make sure that e.g. all IDs are int, or str
matching_ids = [book for book in self.books if book.ID == ID]
# return name, price tuple for all matching books as requested -- note that this will return a list of all matches
# if the IDs are truly unique, you can return e.g. a single tuple or Book object here
# if nothing found, will return empty list
return [(book.name, book.price) for book in matching_ids]
def show_all(self):
for Book in self.books:
Book.show()
if __name__ == '__main__':
lib = Library()
book1 = Book(1, 'Bookname1', "$30")
book2 = Book(2, 'Bookname2', "$10")
book3 = Book(3, 'Bookname3', "$40")
#1.show_id
lib.add_book(book1)
lib.add_book(book2)
lib.add_book(book3)
lib.remove_book(book2)
lib.show_all()
print(lib.show_id(1))
Even if this method is not really optimized, you can go through them with a for loop.
for book in lib.books:
if book.id == searched_id:
searched_book = book
break

How to make a function that calls aand prints each students name and courses

Here is what i have so far
from CSE_324_course import Course
from CSE_324_skeleton_student import Student
math = Course("Algebra I")
language = Course("Spanish I")
science = Course("Earth Science")
history = Course("U.S. History I")
phys_ed = Course("Physical Education I")
speaking = Course("Speech I")
art = Course("Art I")
test_student = Student("Jill", "Sample")
test_student.add_course(math)
test_student.add_course(language)
test_student.add_course(science)
test_student.add_course(history)
test_student2 = Student("Bill", "Sample")
test_student2.add_course(math)
test_student2.add_course(phys_ed)
test_student2.add_course(science)
test_student2.add_course(history)
test_student3 = Student("Kim", "Sample")
test_student3.add_course(language)
test_student3.add_course(speaking)
test_student3.add_course(science)
test_student3.add_course(art)
student_list=[test_student,test_student2,test_student3]
for (test_student,test_student2,test_student3 : get_course)
if (test_student().equals(search))
System.out.println(teststudnetgetCourse());
#Each iteration should:
#get,concatenate, and print the first and last name of the student
#print all courses for that student
#print a blank line between students
'''for this part you may need to review the other skeleton code to:
- see how to get items from a list
- see if there is code (like a function) in that file you can call in this file
- verify that running this file gets you the correct output with information from that file
Also, review syntax of pulling items from a list f
2 page of code
Course import Course
class Student:
student_id = 0
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
self.courses = []
self.student_id = Student.student_id
Student.student_id += 1
def __str__(self):
# TODO You will need to use a variable in the loop, so you must intialize it here,
# that variable will need to be initalized to get items listed in the first def _init_ section
# TODO add a loop that will go through the course list
# TODO Add code here to create a string representation of a student,
# including first and last name and all courses that student is taking
return "complete this return statement based on your in loop variable"
def get_first_name(self):
return self.first_name
def get_last_name(self):
return self.last_name
def get_student_id(self):
return self.student_id
def add_course(self, new_course):
# TODO add code to append new_course to self.courses
print "Course not yet added, implementation needed."
3rd page
class Course:
def __init__(self, course_name):
self.course_name = course_name
def __str__(self):
return self.course_name
I think you are looking to change
for (test_student,test_student2,test_student3 : get_course)
if (test_student().equals(search))
System.out.println(teststudnetgetCourse());
(which you have improperly indented) to:
for student in student_list:
print("{} {}".format(student.first_name, student.last_name))
for course in student.courses:
print(course) # This won't work because "2 page of code Course import Course" needs to be finished
print("\n") # blank line between students

Appending variables to Lists/Call list from another function

So I fixed the issues previous that were based on not having the list defined properly. Is it possible to organize the items in the list? Or is it always going to display the way it was added? If there is a way to update the list after being created and added to, how?
This is the main class file:
def storing():
the_item = Ch10b_retailItemClass.RetailItem("","","")
for count in range(3):
desc = input('What item would you like to inventory?\n')
unit = input('How many of them are in stock?\n')
price = input('What\'s the price for this item?\n')
the_item.set__desc(desc)
the_item.set__unit(unit)
the_item.set__price(price)
# I want to print the list as a whole.
print(the_item.list_function())
And this is my class being imported:
class RetailItem:
global inv
inv = []
# init function, getting us started and initializing variables?
def __init__(self, desc, unit, price):
self.__desc = desc
self.__unit = unit
self.__price = price
# functions that create temp place holders
def set__desc(self, desc):
self.__desc = desc
inv.append(desc)
def set__unit(self, unit):
self.__unit = unit
inv.append(unit)
def set__price(self, price):
self.__price = price
inv.append(price)
def list_function(self):
return inv

how assign list attributes to a class python 3 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I need to create a class student and then assign him or her a subject (maths, science, etc.) and then the grade by subject.
Basically, I have created a class student with name, gender,etc. Then I need to add more than one subject.
But i dont understand how one student object can get more than one subject and probably a greade per subject.
class student:
def __init__(self,name,age,gender,subject):
self.name = name
self.age = age
self.gender = gender
self.subject = subject
def __str__(self):
return ('{},{},{},{}'.format(self.name,self.age,self.gender,self.subject))
new = student('Alan',17,'M','Science')
Please if someone can help me to clarify a little bit I appreciate.
thanks
From your question, I gather that you have already worked with entity relations (ERDs), which is why you are thinking in terms of associations -- which is good. I'm assuming this is homework, so I don't want to give away too much. However, the code below should get you started.
from typing import List, Dict
class CollegeClass:
def __init__(self, class_code: str, name: str):
self.class_code = class_code #type: str
self.name = name
def __str__(self):
return f"{self.class_code}, {self.name}"
def __repr__(self):
return str(self)
class Student:
def __init__(self):
self.current_classes = dict() # type: Dict[str, CollegeClass]
def enroll(self, college_class: CollegeClass):
if college_class.class_code in self.current_classes:
print("The student is already taking the class.")
return
self.current_classes[college_class.class_code] = college_class
if __name__ == '__main__':
math = CollegeClass("mth101", "Intro to Math")
english = CollegeClass("eng201", "Intro to Fiction")
eric_praline = Student()
eric_praline.enroll(math)
eric_praline.enroll(english)
for _, cls in eric_praline.current_classes.items():
print(cls)
There are many ways to accomplish this task. One solution is to not specify the subject when creating the student. Instead, you would create the student object and then add subjects to it.
For example:
student = Student(name="John Smith")
for subject_name in ("Math", "Science", "Literature"):
student.add_subject(subject_name)
That gives you a new student who has three subjects. The add_subject method might look something like this:
class Student(object):
def __init__(self, name, age, gender):
...
self.subjects = {}
...
def add_subject(self, name):
self.subjects[name] = Subject(name)
To assign grades you would do something like this, perhaps
student.add_grade("Math", "A")
student.add_grade("Science", "B")
student.add_grade("Literature", "C")
add_grade would then take the grade name, look up the subject object from self.subjects, and call a method on that subject object to add the grade.
For example:
def add_grade(self, subject_name, grade):
subject = self.subjects[subject_name]
subject.add_grade(grade)
Your class Subject could be something very simple:
class Subject(self):
def __init__(self, name):
self.name = name
self.grade = None
def add_grade(self, grade):
self.grade = grade
Note: the above assumes you want a single grade per subject. If you want multiple grades, you can change self.grade to be self.grades and have it be a list.
Class Student represents just a type of people
Object of class Student represents a particular student, e.g. John Smith
Class Subject represents something students can learn in general
Object of class Subject represents a particular class students can take, e.g. Math 2017
Grade does not belong in either of these, because it only makes sense with a combination of both. So I would suggest creating some data storage, e.g. a list of tuples to store a grade for each combination of student/subject objects you want to keep track of, e.g.
Grades = [
(john_smith, math_2017, 'A+'),
...
]
class Subject(object):
def __init__(self, name, grade=None):
self.name = name
self.grade = grade
class student:
def __init__(self,name,age,gender, subjects=[]):
self.name = name
self.age = age
self.gender = gender
self.subjects = {}
for sub in subjects:
self.subjects[sub] = Subject(sub)
# Create new student with 2 subjects (Art and Science)
new = student('Alan',17,'M', subjects=['Art', 'Science'])
# You can wrap the following processes in functions if so desired
# Add a new subject later on (Math)
new.subjects['Math'] = Subject('Math')
# Add grades
new.subjects['Art'].grade = 'C'
new.subjects['Science'].grade = 'A+'
new.subjects['Math'].grade = 'B-'
# Get a list of subjects and grades
print([(sub.name, sub.grade) for _, sub in new.subjects.items()])
>>>[('Art', 'C'), ('Science', 'A+'), ('Math', 'B-')]
But i [don't] understand how one student object can get more than one subject and probably a [grade] per subject.
Pass in a dictionary of {subject: grade} pairs.
Code
class Student:
def __init__(self, name, age, gender, subjects=None):
self.name = name
self.age = age
self.gender = gender
# Handle mutable keyword defaults
if subjects is None:
self.subjects = {}
else:
self.subjects = subjects
def __repr__(self):
return ("{0.name}, {0.age}, {0.gender}, {0.subjects}".format(self))
subjects = {"Math": "A", "Biology": "B-", "Chemistry": "A"}
s = Student("Joe", 20, "M", subjects=subjects)
s
# Joe, 20, M, {'Math': 'A', 'Chemistry': 'A', 'Biology': 'B-'}
s.subjects["Math"]
# 'A'
Assigning None to a keyword argument is a convention for avoiding a well-known gotcha when assigning mutable arguments, e.g. lists, dictionaries. The lines that handle subjects is equivalent to this one-liner:
self.subjects = {} if subjects is None else subjects
The __repr__() method was defined, which you may wish to include along with __str__().

Categories

Resources