class Cart: """Cart class""" # default constructor def __init__(self): self.item_list = ItemList() self.subtotal_cost = 0.00 self.tax_cost = 0.00 self.shipping_cost = 0.00 self.total_cost = 0.00 self.shopper = Customer() def add_to_cart(self, listing): self.item_list.add(listing) self.subtotal_cost += listing.total def delete_from_cart(self, listing): for entry in self.item_list.listings: if listing.item.item_name == entry.listing.item.item_name: self.item_list.listings.remove( ) # remove that element from list return None def get_total_cost(self): return self.total_cost def get_subtotal_cost(self): return self.subtotal_cost def get_tax_cost(self): return self.tax_cost
def __init__(self, verbose=False): """Initialize library, optionally setting verbose mode.""" self._verbose = verbose self._log('Initializing {}'.format(self)) # Initialize internal lists. self._item_list = ItemList() self._user_list = UserList()
def __init__(self): self.item_list = ItemList() self.subtotal_cost = 0.00 self.tax_cost = 0.00 self.shipping_cost = 0.00 self.total_cost = 0.00 self.shopper = Customer()
def build(self): """ Builds the GUI using kivy and performs tasks on boot. Loads items as a list of lists, into items as lists """ self.items = ItemList() items_as_lists = load_items() self.items.add_items_from_list(items_as_lists) self.title = "Shopping List App" self.root = Builder.load_file('app.kv') self.list_required() return self.root
def __init__(self, **kwargs): # initializer function super().__init__(**kwargs) temp_item_list = load_items() self.items = ItemList() self.mode = LIST_MODE self.mode1 = HIRE_MODE self.mode2 = RETURN_MODE self.items.generate_list(temp_item_list) self.pressed_items = []
def __init__(self, **kwargs): """ Acts as the constructor for ItemsForHire which loads the items.csv to read the files and stores them in a list. """ super(ItemsForHire, self).__init__(**kwargs) self.list_item = ItemList() item_lines_list = open("items.csv", "r+") self.items = [] for line in item_lines_list: self.items.append(line + ",False") self.list_item.store(line) self.names = [] self.price = 0.00
def __init__(self): self.order_number = 0 self.customer = Customer() self.price_paid = 0.0 self.status = "" self.list = ItemList() self.date = ""
def update_database(self): self.root.ids['user_input_screen'].ids[ 'expiry_date'].text = "Expiration Date: " + self.date grocery_item = self.root.ids['user_input_screen'].ids[ "grocery_item"].text notes = self.root.ids['user_input_screen'].ids["extra_notes"].text quantity = self.root.ids['user_input_screen'].ids["quantity"].text if grocery_item == '' or notes == '' or quantity == '': self.root.ids['user_input_screen'].ids[ 'invalid_items'].text = "Please fill out all fields." else: update_items = { 'name': grocery_item, 'notes': notes, 'quantity': quantity, 'expiration date': self.date } self.my_firebase.db.collection(self.local_id).add(update_items) layout = self.root.ids['list_screen'].ids['list_layout'] I = ItemList(name=grocery_item, exp_date=self.date, extra_notes=notes, quantity=quantity) # creates card layout.add_widget(I) self.root.current = 'list_screen'
def build(self): self.items = ItemList('items.csv') self.items.load() self.main = MainScreen(name='main') self.main.add_widget(self.build_main()) sm.add_widget(self.main) self.add_item_screen = AddItemScreen(name='add_item') self.add_item_screen.items = self.items sm.add_widget(self.add_item_screen) self.sm = sm sm.current = "main" return sm
def __init__(self, **kwargs): """Initializer to construct the app""" super(MainApp, self).__init__(**kwargs) self.item_list = ItemList() stock = open("inventory.csv", "r+") for items in stock: self.item_list.store(items)
def __init__(self, **kwargs): """ Construct main app """ super(EquipmentHire, self).__init__(**kwargs) # This loads the item list from the csv self.itemlist = ItemList() self.itemlist.add_items(load_items()) self.mode = LIST_MODE self.selected_items = [] self.status_text = 'Choose action from the left menu, then select items on the right'
def build(self): self.mode = List_Items self.list_item = ItemList() temp_list = load_items() self.item_listing = [] self.list_item.save_items(temp_list) self.action_label = "Select a mode on the left side, then select items on the right" self.title = 'Experiment Hire' self.root = Builder.load_file('GUI A2.kv') self.create_entry_buttons() return self.root
def __init__(self, **kwargs): """ Initializer for app class - allows for other classes to be imported and declared :param kwargs: :return: """ super(ItemsGUI, self).__init__(**kwargs) self.items = ItemList() self.mode = LIST_MODE self.selected_items = [] self.status_text = "Choose action from the left menu, then select items on the right"
class User: def __init__(self, user_id): self._fines = float() self._identification = int() self._item_list = ItemList() self.user_id = user_id def __del__(self): pass def able_to_borrow(self, max_number_loans, max_total_fine): # checks if user is able to borrow fine_total = self.get_fine_total() num_items = self._item_list.number_of_items() if num_items <= max_number_loans and fine_total <= max_total_fine: return True elif fine_total > max_total_fine: raise FineHighError(fine_total, max_total_fine - fine_total) elif num_items > max_number_loans: raise TooManyItems(num_items, max_number_loans) def checkout_item(self, item_requested, date): # checks out item self._item_list.append(item_requested) def get_fine_total(self): # returns the total amount of fines for the user return self._item_list.get_fines() def get_identification(self): return self._identification def pay_fine(self, amount): # subtracts amount from user's total fines self._fines = ItemList.get_fines(self._item_list) - amount pass def return_item(self): # updates user's returned item list return
def signed_in(self): #get data from database data = self.my_firebase.get_database_data(self.local_id) print(data) #populate fridge data in list screen layout = self.root.ids['list_screen'].ids['list_layout'] for key in data: name = data[key]['name'] exp_date = data[key]['expiration date'] extra_notes = data[key]['notes'] quantity = data[key]['quantity'] I = ItemList(name=name, exp_date=exp_date, extra_notes=extra_notes, quantity=quantity) # creates card layout.add_widget(I)
def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.resize(1143, 732) self.setWindowTitle("FireDES") self.centralWidget = QWidget(self) self.layout = QGridLayout(self.centralWidget) self.centralWidgetSetup() self.visualTools = VisualTools(self.centralWidget) self.layout.addWidget(self.visualTools, 0, 0) self.menuBarSetup() self.automataGrid = AutomataGrid(self.centralWidget) self.layout.addWidget(self.automataGrid, 0, 1) self.itemList = ItemList(self.centralWidget) self.layout.addWidget(self.itemList, 0, 2) self.terminal = Terminal(self.centralWidget) self.layout.addWidget(self.terminal, 1, 0, 1, 3)
class ItemHire(App): # creating class ItemHire status_text = StringProperty() # for showing the status of each button and item def __init__(self, **kwargs): # initializer function super().__init__(**kwargs) temp_item_list = load_items() self.items = ItemList() self.mode = LIST_MODE self.mode1 = HIRE_MODE self.mode2 = RETURN_MODE self.items.generate_list(temp_item_list) self.pressed_items = [] def build(self): # creating function for connecting GUI self.title = "Item hiring Application" # creating title self.root = Builder.load_file('app.kv') # loading .kv file self.create_buttons() return self.root # reference to root the widget def create_buttons(self): # creating the layout and buttons in GUI self.root.ids.statusLabel.text = "Choose action from the left Menu,then select item on the right" for item in self.items.items: temp_button = Button(text=item.name) if item.status == "in": temp_button.background_color = (0, 1, 1, 1) temp_button.bind(on_press=self.press_entry) self.root.ids.entriesBox.add_widget(temp_button) if item.status == "out": temp_button.background_color = (1, 0, 1, 1) temp_button.bind(on_press=self.press_entry) self.root.ids.entriesBox.add_widget(temp_button) def press_button(self): self.mode = LIST_MODE self.root.ids.statusLabel.text = "Choose action from the left Menu,then select item on the right" self.root.ids.ListItem.state = 'down' self.root.ids.HireItem.state = 'normal' self.root.ids.ReturnItem.state = 'normal' def press_entry(self, instance): # function to handle the pressing of items in GridLayout item = self.items.get_item(instance) if self.mode == LIST_MODE: name = instance.text self.status_text = name for item in self.items.items: if name == item.name and item.status == "out": self.root.ids.statusLabel.text = item.name + '(' + item.description + ')' + '$' + str( item.price) + 'is out' if name == item.name and item.status == "in": self.root.ids.statusLabel.text = item.name + '(' + item.description + ')' \ + 'is available for hire' + '$' + str(item.price) elif self.mode == HIRE_MODE: pass instance.state = 'down' def press_hire(self): # function to hire items self.mode1 = HIRE_MODE self.root.ids.HireItem.state = "down" self.root.ids.ListItem.state = "normal" self.root.ids.ReturnItem.state = "normal" self.root.ids.statusLabel.text = "Select available item to hire" def press_entry_hire(self, instance1): # function to handle the pressing of items in GridLayout under press_hire if self.mode1 == HIRE_MODE: name = instance1.text self.status_text = name for item in self.items.items: if name == item.name and item.status == "out": self.root.ids.statusLabel.text = item.name + '(' + item.description + ')' + 'is out' elif name == item.name and item.status == "in": self.root.ids.statusLabel.text = 'Hiring' + item.name + '(' + item.description + ')' \ + 'for' + '$' + str(item.price) elif self.mode1 == LIST_MODE: pass instance1.state = 'down' def press_return(self): # function to return items self.root.ids.statusLabel.text = "Select item to return" self.root.ids.ReturnItem.state = "down" self.root.ids.ListItem.state = "normal" self.root.ids.HireItem.state = "normal" self.mode2 = RETURN_MODE def press_entry_return(self, instance2): # function to handle the pressing of items in GridLayout under press_return if self.mode2 == RETURN_MODE: name = instance2.text self.status_text = name for item in self.items.items: if name == item.name and item.status == "in": self.root.ids.statusLabel.text = item.name + 'is not hired' elif name == item.name and item.status == "out": self.root.ids.statusLabel.text = 'Returning:' + item.name + '(' + item.description + ')' \ + 'for' + '$' + str(item.price) elif self.mode1 == LIST_MODE: pass instance2.state = 'down' def press_confirm(self): # function to confirm the changes like hiring and returning self.root.ids.Confirm.state = "down" self.root.ids.HireItem.state = "normal" self.root.ids.ListItem.state = "normal" self.root.ids.ReturnItem.state = "normal" if self.mode1 == HIRE_MODE: for item in self.pressed_items: if item.status == "in": item.status = "out" if self.mode2 == RETURN_MODE: for item in self.pressed_items: if item.status == "out": item.status = "in " def on_stop(self): # function to save all the changes when the window is closed(stopped) save_list(self.items.make_list()) def press_add(self): self.status_text = "Enter details for new item" # status line for add_item popup self.root.ids.popup.open() def press_save(self, added_name, added_description, added_price): # function for saving new item to the list self.items.add_item(added_name, added_description, str(added_price), "in") self.root.ids.entriesBox.cols = 2 # setting the column format in GridLayout temp_button = Button(text=added_name) temp_button.bind(on_release=self.press_entry) temp_button.background_color = (0, 1, 1, 1) self.root.ids.entriesBox.add_widget(temp_button) self.root.ids.popup.dismiss() self.clear_fields() def press_cancel(self): # function to cancel the adding of new item self.root.ids.popup.dismiss() # dismissing the popup self.clear_fields() self.status_text = "" def clear_fields(self): # function for clearing the fields in add_item popup self.root.ids.AddName.text = "" self.root.ids.AddDescription.text = "" self.root.ids.AddPrice.text = ""
class ExperimentHire(App): action_label = StringProperty() def __init__(self, **kwargs): super(ExperimentHire, self).__init__(**kwargs) # Builds the GUI Kivy def build(self): self.mode = List_Items self.list_item = ItemList() temp_list = load_items() self.item_listing = [] self.list_item.save_items(temp_list) self.action_label = "Select a mode on the left side, then select items on the right" self.title = 'Experiment Hire' self.root = Builder.load_file('GUI A2.kv') self.create_entry_buttons() return self.root # This function controls the status display of the items def listing_items(self): self.mode = List_Items self.item_listing = [] statusLable = "Select a mode on the left side, then select items on the right" self.action_label = str(statusLable) self.root.ids.listItems.state = 'down' self.root.ids.hireItem.state = 'normal' self.root.ids.addButton.state = 'normal' self.root.ids.itemConfirm.state = 'normal' self.root.ids.returnItem.state = 'normal' # This function controls when the user wants to hire out an item, it passes it through the confirm button andthen deselects it from the GUI making it unavailable. It can only hire out items that are available def hiring_item(self): statusLable = 'Select Available Items to Hire' self.root.ids.action_label.text = str(statusLable) self.mode = Hire_Items self.item_listing = [] self.root.ids.listItems.state = 'normal' self.root.ids.hireItem.state = 'down' self.root.ids.addButton.state = 'normal' self.root.ids.itemConfirm.state = 'normal' self.root.ids.returnItem.state = 'normal' # This function controls when the user wants to return out an item, it passes it through the confirm button and then you are able to select unavailable items it from the GUI making them available def return_item(self): statuslabel = 'Select available items to return' self.root.ids.action_label.text = str(statuslabel) self.mode = Return_Items self.item_listing = [] self.root.ids.listItems.state = 'normal' self.root.ids.hireItem.state = 'normal' self.root.ids.addButton.state = 'normal' self.root.ids.itemConfirm.state = 'normal' self.root.ids.returnItem.state = 'down' # This function controls the hiring and return fucntions, if items are 'out' you can return them, if items are 'in' you can hire them def confirm_item(self): if self.mode == Hire_Items: for item in self.item_listing: item.stock = "out" self.set_button_to_normal() self.listing_items() elif self.mode == Return_Items: for item in self.item_listing: item.stock = "in" self.set_button_to_normal() # self.item_listing.state = 'normal' self.listing_items() for self.item in self.item_listing: if self.item.stock == "in": self.item.state = 'down' for button in self.root.ids.newItem.children: button.state = 'down' self.item_listing = [] elif self.item.stock == "in": self.item.state = 'normal' for button in self.root.ids.newItem.children: button.state = 'normal' self.item_listing = [] # Creates the entry button and then adds it to the GUI Kivy def create_entry_buttons(self): # creates a button for each new item entry being added for item in self.list_item.items: temp_button = Button(text=item.name) temp_button.bind(on_release=self.press_entry) # adds the button to "newItem" using add.widget self.root.ids.newItem.add_widget(temp_button) # updates the button status reloading if the button selected is in or out and passes them def button_status(self, status): while status != 'in' or 'out': if status == 'in': pass elif status == 'out': pass # Handles the entry buttons pressing and updates the status text def press_entry(self, instance): item = self.list_item.get_item(instance.text) if self.mode == List_Items: self.action_label = str(item) elif self.mode == Hire_Items: if item.stock == 'in': if item not in self.item_listing: self.item_listing.append(item) instance.state = 'down' running_total = 0 names = [] for item in self.item_listing: running_total += item.price names.append(item.name) self.action_label = "Hiring: {} for ${}".format(', '.join(names), running_total) elif self.mode == Return_Items: if item.stock == 'out': if item not in self.item_listing: self.item_listing.append(item) instance.state = 'down' names = [] for item in self.item_listing: names.append(item.name) self.action_label = "Returning: {}".format(', '.join(names)) elif self.mode == Add_Items: pass # Sets the button status back to normal after being selected def set_button_to_normal(self): # uses the .children attribute to access all widgets that are located in another widget for button in self.root.ids.newItem.children: button.state = 'normal' self.item_listing = [] # Handles the add button, and opens up the pop up window def press_add(self): self.mode = Add_Items self.item_listing = [] self.action_label = '' self.root.ids.listItems.state = 'normal' self.root.ids.hireItem.state = 'normal' self.root.ids.addButton.state = 'down' self.root.ids.itemConfirm.state = 'normal' self.root.ids.returnItem.state = 'normal' self.action_label = "Enter Details For New Item" self.root.ids.popup.open() pass # clears any button that has been selected by user and reset the status text def clear_fields(self): # if this function is not completed, the popup will continue to have text in the fields after submission self.root.ids.addedName.text = "" self.root.ids.addedDescription.text = "" self.root.ids.addedPrice.text = "" # handles the cancel button in the popup window def press_cancel(self): self.root.ids.popup.dismiss() self.clear_fields() self.action_label = "" # handles the save item button in the popup window, saves a new entry to the memory def press_save(self, added_name, added_description, added_price): # changes the number of columns based on the number of entries try: if added_name == "" or added_description == "" or added_price == "": self.root.ids.popup_label.text = "All Fields Must Be Completed" if float(added_price) < 0: self.root.ids.popup_label.text = "Must Be a Valid Number" self.list_item.add_item(added_name, added_description, float(added_price), 'in') # number of entries self.root.ids.newItem.cols = len(self.list_item.items) // 5 + 1 # add button for new entry new_button = Button(text=added_name) new_button.bind(on_release=self.press_entry) self.root.ids.newItem.add_widget(new_button) self.root.ids.popup.dismiss() self.clear_fields() except ValueError: self.root.ids.addedPrice.text = '' # creates an error check if the fields are empty # after the GUI is closed this saves the created items to the list def on_stop(self): save_items(self.list_item.get_items_as_list())
def __init__(self, keyword_class=Keyword, items=None, parent=None): ItemList.__init__(self, keyword_class, items, parent=parent)
def pay_fine(self, amount): # subtracts amount from user's total fines self._fines = ItemList.get_fines(self._item_list) - amount pass
class ShoppingListApp(App): """ This Class is the main program. Methods are called from other classes to provide the kivy with tasks for buttons labels etc. """ top_status_label = StringProperty() bottom_status_label = StringProperty() def build(self): """ Builds the GUI using kivy and performs tasks on boot. Loads items as a list of lists, into items as lists """ self.items = ItemList() items_as_lists = load_items() self.items.add_items_from_list(items_as_lists) self.title = "Shopping List App" self.root = Builder.load_file('app.kv') self.list_required() return self.root def on_stop(self): """ Writes self.items to csv by calling the method save_items in itemlist.py """ items = self.items.save_items() write_items(items) def list_required(self): """ Lists required items by creating widgets for marking off items and giving them colour based on priority. This is also sorted by priority and keeps the list required button highlighter after press. """ self.items.sort_item_by_priority() self.root.ids.entry_box.clear_widgets() self.root.ids.list_required.state = "down" self.root.ids.list_completed.state = "normal" self.bottom_status_label = "Click items to mark them as completed" for item in self.items.items: if item.required == Item.REQUIRED: temp_button = Button( text=item.name, background_color=BUTTON_COLOURS[item.priority]) # create a button for each item temp_button.bind(on_release=self.mark_item) # add the button to the "entry_box" using add_widget() self.root.ids.entry_box.add_widget(temp_button) total_price = self.items.get_total_price() self.top_status_label = "Total price: ${}".format(total_price) def list_completed(self): """ Lists completed items by creating widgets for completed items. Also keeps the list completed button highlighted after press. """ self.root.ids.entry_box.clear_widgets() self.root.ids.list_required.state = "normal" self.root.ids.list_completed.state = "down" self.bottom_status_label = "Showing completed items" for item in self.items.items: if item.required == Item.COMPLETED: # create a button for each item temp_button = Button(text=item.name) temp_button.bind(on_release=self.display_item_info) # add the button to the "entry_box" using add_widget() self.root.ids.entry_box.add_widget(temp_button) def mark_item(self, instance): """ Marks the item clicked on as completed """ name = instance.text item = self.items.get_item_by_name(name) item.mark_item() self.clear_all() self.list_required() def display_item_info(self, instance): """ Displays the items information in the bottom status label (at the bottom of the app) """ name = instance.text item = self.items.get_item_by_name(name) self.bottom_status_label = "{}, ${}, priority {} (completed)".format( item.name, item.price, item.priority) def clear_new_item_inputs(self): """ Clears the input boxes that ask for item name, pirce and priority """ self.root.ids.new_item_name.text = "" self.root.ids.new_item_price.text = "" self.root.ids.new_item_priority.text = "" def get_new_item(self): """ Gets the inputs from the text input boxes and runs them through error checking before calling the add new item method in itemlist.py and then resets the list required to include the new item """ name = self.root.ids.new_item_name.text price = self.root.ids.new_item_price.text priority = self.root.ids.new_item_priority.text if name == "" or price == "" or priority == "": self.bottom_status_label = "All fields must be completed" else: try: price = float(price) # The error checking enables the user to correctly input and any incorrect inputs is dealt by displaying # an error if price < 0: self.bottom_status_label = "Price must not be negative" return except ValueError: self.bottom_status_label = "Please enter a valid number" return try: priority = int(priority) if priority <= 0 or priority > 3: self.bottom_status_label = "Priority must be 1, 2 or 3" return except ValueError: self.bottom_status_label = "Please enter a valid number" return # this is the method from itemlist that appends the new item to the existing list self.items.add_item_input(name, price, priority) self.list_required() self.clear_new_item_inputs()
def on_start(self): """ Load items from the CSV file on start """ source_items = load_items() self.item_list = ItemList(source_items) self.create_item_buttons() self.set_mode(Mode.listing)
class ItemsHiring(App): """ Main application class """ status_text = StringProperty() def on_start(self): """ Load items from the CSV file on start """ source_items = load_items() self.item_list = ItemList(source_items) self.create_item_buttons() self.set_mode(Mode.listing) def on_stop(self): """ Save items to the CSV file on exit """ save_items(self.item_list.export_items()) def build(self): """ Build Kivy app from the kv file """ self.title = "Items Hiring" self.root = Builder.load_file('app.kv') return self.root def create_item_button(self, item, item_index): """ Create an item button for a certain item """ button = ItemButton(text=item.name, hired=item.hired, item_index=item_index) button.bind(on_release=self.press_item) self.root.ids.itemsGrid.add_widget(button) def create_item_buttons(self): """ Create the item buttons and add them to the GUI """ for i, item in enumerate(self.item_list.items): self.create_item_button(item, i) def clear_selection(self): """ Clear any buttons that have been selected """ for instance in self.root.ids.itemsGrid.children: instance.set_selected(False) def update_item_buttons(self): """ Update colours of item buttons """ for instance in self.root.ids.itemsGrid.children: item = self.item_list.items[instance.item_index] instance.hired = item.hired def set_mode(self, mode): """ Switch between 'listing', 'hiring' and 'returning' modes """ ids = self.root.ids for button in [ids.buttonList, ids.buttonHire, ids.buttonReturn]: button.state = 'normal' if mode == Mode.listing: self.status_text = "Choose action from the left menu, then select items on the right" ids.buttonList.state = 'down' elif mode == Mode.hiring: if self.item_list.count(hired=False) > 0: self.status_text = "Select available items to hire" else: self.status_text = "No items available for hire" ids.buttonHire.state = 'down' elif mode == Mode.returning: if self.item_list.count(hired=True) > 0: self.status_text = "Select available items to return" else: self.status_text = "No items are currently on hire" ids.buttonReturn.state = 'down' self.clear_selection() self.mode = mode def show_details(self, item_index): """ Display item details in the status bar """ item = self.item_list.items[item_index] status = "out" if item.hired else "in" self.status_text = "{}({}), ${:.2f} is {}".format(item.name, item.description, item.price, status) def selecting_allowed(self, hired): """ Check if item is selectable depending on hired status """ if self.mode == Mode.hiring and not hired: return True elif self.mode == Mode.returning and hired: return True return False def show_selection_status(self): """ Display selected items in the status bar """ names = [] total_price = 0 for i, button in enumerate(self.root.ids.itemsGrid.children): item = self.item_list.items[button.item_index] if button.selected: names.append(item.name) total_price += item.price if len(names) == 0: names = "no items" else: names = ", ".join(names) if self.mode == Mode.hiring: self.status_text = "Hiring: {} for ${:.2f}".format(names, total_price) else: self.status_text = "Returning: {}".format(names) def press_item(self, instance): """ Handler for pressing an item button """ if self.mode == Mode.listing: self.show_details(instance.item_index) return if self.selecting_allowed(instance.hired): instance.set_selected(not instance.selected) self.show_selection_status() def press_list(self): """ Handler for pressing the 'List Items' button """ self.set_mode(Mode.listing) def press_hire(self): """ Handler for pressing the 'Hire Items' button """ self.set_mode(Mode.hiring) def press_return(self): """ Handler for pressing the 'Return Items' button """ self.set_mode(Mode.returning) def press_confirm(self): """ Handler for pressing the 'Conrirm' button """ for button in self.root.ids.itemsGrid.children: if not button.selected: continue item = self.item_list.items[button.item_index] if self.mode == Mode.hiring: self.item_list.hire_item(button.item_index) elif self.mode == Mode.returning: self.item_list.return_item(button.item_index) self.update_item_buttons() self.set_mode(Mode.listing) def press_add(self): """ Handler for pressing the 'Add New Item' button """ self.status_text = "Enter details for new item" self.root.ids.popup.open() def press_save(self, name, description, price): """ Handler for pressing the save button in the popup """ if not name or not description or not price: self.status_text = "All fields must be completed" return try: price = float(price) except: self.status_text = "Price must be a valid number" return if price <= 0: self.status_text = "Price must not be negative or zero" return self.item_list.add_item(name, description, price, hired=False) last_index = len(self.item_list.items) - 1 item = self.item_list.items[last_index] self.create_item_button(item, last_index) self.close_popup() def close_popup(self): """ Close the popup and clear input fields """ self.root.ids.popup.dismiss() self.clear_fields() def clear_fields(self): """ Clear input fields in the popup """ self.root.ids.itemName.text = "" self.root.ids.itemDescription.text = "" self.root.ids.itemPrice.text = ""
class LibraryController(object): """Responsible for all access to objects in library Including all items (books, DVDs and journals), and users.""" MAX_LOANS = 5 MAX_FINE = 50 def _log(self, message): """Poor man's 'logging'!""" if self._verbose: print(message) def __init__(self, verbose=False): """Initialize library, optionally setting verbose mode.""" self._verbose = verbose self._log('Initializing {}'.format(self)) # Initialize internal lists. self._item_list = ItemList() self._user_list = UserList() def add_item(self, item): """Add an item to the library.""" self._log('Adding item: {}'.format(item)) self._item_list.add_item(item) def add_user(self, user): """Add an user to the library.""" #self._log('Adding user: {}'.format(user)) self._user_list.add_user(user) def is_on_loan(self, item_title): """Find out if an item is on load.""" return self._item_list.is_on_loan(item_title) def pay_fine(self, user_id, amount): """Pay a find for a user.""" self._log('Paying fine: {} - {}'.format(user_id, amount)) self._user_list.pay_fine(user_id, amount) def user_checkout(self, user_id, item_title, date=dt.now()): """Checkout an item for a user.""" self._log('User checkout: {} - {}'.format(user_id, item_title)) if self._user_list.able_to_borrow(user_id, self.MAX_LOANS, self.MAX_FINE): self._log('User {} able to borrow.'.format(user_id)) item = self._item_list.checkout_item(item_title, date) self._user_list.checkout_item(user_id, item, date) return True else: self._log('User {} not able to borrow'.format(user_id)) return False def get_user_fine(self, user_id): """Get fines that apply to a user.""" return self._user_list.get_fine_total(user_id) def user_return(self, user_id, item_title): """Return an item for a user.""" self._log('User returning: {} - {}'.format(user_id, item_title)) self._user_list.return_item(user_id, item_title) self._item_list.return_item(item_title)
class MainWindow(App): label_text = StringProperty() selection = [] on_selection = None def set_selection(self, grid, *args): description = [] total_price = 0 self.selection = [] self.selection_with_idx = {} for node in grid.selected_nodes: record = self.items.items[node.storage_idx] self.selection.append(record) self.selection_with_idx[node.storage_idx] = record for record in self.selection: price = record.price name = record.name total_price += float(price) description.append(name) self.main_label.text = ",".join(description) + ":"+ str(total_price) def on_button_pressed(self, button): print(button.state) def list_items(self,*args): self.main_label.text = "Choose action from the left menu, then choose items on the right " def hire_items(self, *args): inst = args[0] ## This will hire items for the current selection for record in self.selection: if record.status == 'out': self.main_label.text = "You are trying to hire an already hired equipment. Please return it first!" self.selection_with_idx = {} return True self.main_label.text = "Please click Confirm to hire!" return True def return_items(self,*args): for record in self.selection: if record.status == 'in': self.main_label.text = "You are trying to return a non-hired equipment. Please check your selections!" self.selection_with_idx = {} return False self.main_label.text = "Please click to Confirm to return!" return True def confirm(self,*args): ## Check if selected_functions is selected products = [] if len(self.selection_with_idx) == 0: self.main_label.text = "Confirm won't work! Fix your choices" return False ## If hire is being selected - then we set hired to all items in the file for key, record in self.selection_with_idx.items(): #print key, record if self.items.items[key].status=='in': self.items.items[key].status = 'out' products.append(self.items.items[key].name) out_message = ' Items Hired' else: self.items.items[key].status = 'in' products.append(self.items.items[key].name) out_message = ' Items Returned' self.items.save() self.main_label.text = ','.join(products) + out_message return True def add_new_item(self,*args): self.sm.transition.direction = 'left' self.sm.current = "add_item" def build_main(self): main_layout = BoxLayout(padding=5, orientation='vertical') group_layout = BoxLayout(padding=5) actions = { 'List items':self.list_items, 'Hire items':self.hire_items, "Return Items":self.return_items, "Confirm":self.confirm, "Add New Item":self.add_new_item } items = self.items.load() colors = [red, green, blue, purple] h_layout = BoxLayout(padding=5, orientation='vertical', size_hint_x=None, width=150,) for action_name in sorted(actions.keys()): callback = actions[action_name] btn = ToggleButton(text=action_name,background_color=gray, group="actions") btn.bind(on_press=callback) h_layout.add_widget(btn) group_layout.add_widget(h_layout) items = list(items.values()) layout = SelectableGrid(cols=2, up_count=5, multiselect=True, scroll_count=1) for idx, item in self.items.items.items(): #print(idx) # category, name, cost, state = item btn = Button(text=item.name, background_color=color_for_state(item.status)) btn.bind(on_touch_down=layout.do_touch) btn.storage_idx = idx layout.add_widget(btn) layout.bind(selected_nodes=self.set_selection) layout.items = self.items group_layout.add_widget(layout) main_layout.add_widget(group_layout) self.main_label = Label(text="loading...", size_hint_y=None, height=50) self.selected_functions = [] main_layout.add_widget(self.main_label) return main_layout def build(self): self.items = ItemList('items.csv') self.items.load() self.main = MainScreen(name='main') self.main.add_widget(self.build_main()) sm.add_widget(self.main) self.add_item_screen = AddItemScreen(name='add_item') self.add_item_screen.items = self.items sm.add_widget(self.add_item_screen) self.sm = sm sm.current = "main" return sm
class MainApp(App): string_property = StringProperty() def __init__(self, **kwargs): """Initializer to construct the app""" super(MainApp, self).__init__(**kwargs) self.item_list = ItemList() stock = open("inventory.csv", "r+") for items in stock: self.item_list.store(items) def build(self): self.title = "A2" self.root = Builder.load_file('layout.kv') return self.root def itemlist(self): """Function to show all the list item in the inventory.csv""" self.root.ids.itemlistbox.clear_widgets() self.root.ids.bottomlabel.text = 'Choose action from the left menu, then select items on the right' self.root.ids.listitem.background_color = (1, 1, 0.5, 1) self.root.ids.hireitem.background_color = (1, 1, 1, 1) self.root.ids.returnitem.background_color = (1, 1, 1, 1) self.root.ids.confirm.background_color = (1, 1, 1, 1) self.root.ids.additem.background_color = (1, 1, 1, 1) for items in self.item_list: name, desc, price, availability = items.split(",") if "in" in availability: tempbutton = Button(text=name, background_color=(0, 1, 0, 1)) else: tempbutton = Button(text=name, background_color=(0.9, 0.3, 0.5, 1)) tempbutton.bind(on_press=self.pressitem) self.root.ids.itemlistbox.add_widget(tempbutton) def itemhire(self): """Function to hire the items from inventory.csv, red color item mean the item is out""" self.root.ids.itemlistbox.clear_widgets() self.root.ids.bottomlabel.text = 'Choose action from the left menu, then select items on the right' self.root.ids.listitem.background_color = (1, 1, 1, 1) self.root.ids.hireitem.background_color = (1, 1, 0.5, 1) self.root.ids.returnitem.background_color = (1, 1, 1, 1) self.root.ids.confirm.background_color = (1, 1, 1, 1) self.root.ids.additem.background_color = (1, 1, 1, 1) for items in self.item_list: name, desc, price, availability = items.split(",") if "in" in availability: tempbutton = Button(text=name, background_color=(0, 1, 0, 1)) else: tempbutton = Button(text=name, background_color=(0.9, 0.3, 0.5, 1)) tempbutton.bind(on_press=self.pressitem) self.root.ids.itemlistbox.add_widget(tempbutton) def itemreturn(self): """Function to return the items that is out from the inventory.csv""" self.root.ids.itemlistbox.clear_widgets() self.root.ids.bottomlabel.text = 'Choose action from the left menu, then select items on the right' self.root.ids.listitem.background_color = (1, 1, 1, 1) self.root.ids.hireitem.background_color = (1, 1, 1, 1) self.root.ids.returnitem.background_color = (1, 1, 0.5, 1) self.root.ids.confirm.background_color = (1, 1, 1, 1) self.root.ids.additem.background_color = (1, 1, 1, 1) for items in self.item_list: name, desc, price, availability = items.split(",") if "in" in availability: tempbutton = Button(text=name, background_color=(0, 1, 0, 1)) else: tempbutton = Button(text=name, background_color=(0.9, 0.3, 0.5, 1)) tempbutton.bind(on_press=self.pressitem) self.root.ids.itemlistbox.add_widget(tempbutton) def pressitem(self, instance): """Function will show the description of the selected item the bottomlabel will also change when the item_return or item_hire button is being selected""" for items in self.item_list: name, desc, price, availability = items.split(",") if instance.text == name: if self.root.ids.listitem.background_color == [1, 1, 0.5, 1]: self.root.ids.bottomlabel.text = "{} ({}), ${:,.2f} is {}".format(name, desc, float(price), availability) elif self.root.ids.hireitem.background_color == [1, 1, 0.5, 1]: if "in" in availability: self.root.ids.bottomlabel.text = "Hiring: {} for ${:,.2f}".format(name, float(price)) else: self.root.ids.bottomlabel.text = "Hiring: no items for $0.00" elif self.root.ids.returnitem.background_color == [1, 1, 0.5, 1]: if "out" in availability: self.root.ids.bottomlabel.text = "Returning: {}".format(name) else: self.root.ids.bottomlabel.text = "Returning: no items" def confirm(self): """Function to make changes on the inventory.csv file""" itemcount = 0 with open("inventory.csv") as itemfile: read = itemfile.readlines() for items in read: name, desc, price, availability = items.split(",") if name in self.root.ids.bottomlabel.text: if self.root.ids.hireitem.background_color == [1, 1, 0.5, 1]: self.item_list.clear() read[itemcount] = read[itemcount].replace("in", "out") with open("inventory.csv", "w") as itemfile: itemfile.writelines(read) for items in read: self.item_list.store(items) itemfile.close() self.itemlist() elif self.root.ids.returnitem.background_color == [1, 1, 0.5, 1]: self.item_list.clear() read[itemcount] = read[itemcount].replace("out","in") with open("inventory.csv", "w") as itemfile: itemfile.writelines(read) for items in read: self.item_list.store(items) itemfile.close() self.itemlist() itemcount += 1 def additem(self): """Function to display the popup window""" self.root.ids.listitem.background_color = (1, 1, 1, 1) self.root.ids.hireitem.background_color = (1, 1, 1, 1) self.root.ids.returnitem.background_color = (1, 1, 1, 1) self.root.ids.confirm.background_color = (1, 1, 1, 1) self.root.ids.additem.background_color = (1, 1, 0.5, 1) self.string_property = 'Enter new item' self.root.ids.popupbox.open() def save(self, name, desc, price, instruction): """Function to save the input item to inventory.csv and dismiss the pop up window after saving""" def error(price): # error checking try: float(price) return True except ValueError: return False if name.strip == '' or desc == '' or price == '': instruction.text = "All fields must be completed" elif error(price) == False: instruction.text = "Price must be valid number" elif error(price) == True and float(price) < 0: instruction.text = "Price cannot be negative" else: additems = "\n{},{},{},in".format(name, desc, float(price)) with open("inventory.csv", "a") as itemfile: itemfile.writelines(additems) self.item_list.store(additems) self.cancel() self.itemlist() def cancel(self): """Function to dismiss pop up window""" self.root.ids.popupbox.dismiss() self.root.ids.itemname.text = "" self.root.ids.desc.text = "" self.root.ids.priceinput.text = ""
class EquipmentHire(App): """ Main program - Kivy app for Equiptment Hire(Assignment) """ status_text = StringProperty() def __init__(self, **kwargs): """ Construct main app """ super(EquipmentHire, self).__init__(**kwargs) # This loads the item list from the csv self.itemlist = ItemList() self.itemlist.add_items(load_items()) self.mode = LIST_MODE self.selected_items = [] self.status_text = 'Choose action from the left menu, then select items on the right' def build(self): """ Build kivy app from the kv file """ self.title = "Equipment Hire" self.root = Builder.load_file('gui.kv') self.create_entry_buttons() return self.root def on_stop(self): # get items from self.itemlist # call save functioon from AlexSilva1 pass # save_items() def press_add(self): """ Handler for pressing the add button :return: None """ self.status_text = "Enter details for new Item" # this opens the popup self.root.ids.popup.open() def create_entry_buttons(self): """ Create the entry buttons and add them to the GUI :return: None """ for item in self.itemlist.items: # create a button for each phonebook entry temp_button = Button(text=item.name) temp_button.bind(on_release=self.press_entry) # add the button to the "entriesBox" using add_widget() self.root.ids.entriesBox.add_widget(temp_button) def press_entry(self, instance): """ Handler for pressing entry buttons :param instance: the Kivy button instance :return: None """ name = instance.text clicked_item = self.itemlist.get_item(name) # Checks mode selected if self.mode == LIST_MODE: # update status text self.status_text = "{} ({}), ${} is {}".format(name, clicked_item.description, clicked_item.cost, clicked_item.status) elif self.mode == HIRE_MODE: new_cost = 0 if clicked_item.name not in self.selected_items and clicked_item.status == 'in': self.selected_items.append(clicked_item) # set instance state instance.state = 'down' # creates an empty list then adds each slected item names = [] for item in self.selected_items: names.append(item.name) new_cost += item.cost self.status_text = "Hiring: {} for ${}".format(','.join(names), clicked_item.cost + new_cost) else: self.status_text = "Hiring: no items for $0.00" elif self.mode == RETURN_MODE: if clicked_item.name not in self.selected_items and clicked_item.status == 'out': self.selected_items.append(clicked_item) # creates an empty list then adds each slected item names = [] for item in self.selected_items: names.append(item.name) self.status_text = "Returning: {}".format(','.join(names)) def press_list(self): """ :return: """ # Sets the mode the instance is in self.mode = LIST_MODE # changes state of each button self.root.ids.hireItems.state = 'normal' self.root.ids.listItems.state = 'down' self.root.ids.returnItems.state = 'normal' def press_hire(self): """ Puts the user into hire mode and changes states of each button :return: """ self.mode = HIRE_MODE # changes state of each button self.root.ids.hireItems.state = 'down' self.root.ids.listItems.state = 'normal' self.root.ids.returnItems.state = 'normal' def press_return(self): """ Puts the user into return mode and changes states of each button :return: """ # Sets the mode the instance is in self.mode = RETURN_MODE # changes state of each button self.root.ids.hireItems.state = 'normal' self.root.ids.listItems.state = 'normal' self.root.ids.returnItems.state = 'down' def press_confirm(self): """ Changes the selected item/s to in or out state :return: """ if self.mode == HIRE_MODE: names = [] for item in self.selected_items: names.append(item.name) item.status = 'out' self.status_text = "{} are now out.".format(','.join(names)) elif self.mode == RETURN_MODE: names = [] for item in self.selected_items: names.append(item.name) item.status = 'in' self.status_text = "{} are now back in.".format(','.join(names)) def press_clear(self): """ Clear any buttons that have been selected (visually) and reset status text :return: None """ # use the .children attribute to access all widgets that are "in" another widget for instance in self.root.ids.entriesBox.children: instance.state = 'normal' self.status_text = "" def press_save(self, added_name, added_description, added_priceperday): """ Handler for pressing the save button in the add entry popup - save a new entry to memory :param ? :return: None """ self.itemlist[added_name] = added_priceperday # change the number of columns based on the number of entries (no more than 5 rows of entries) self.root.ids.entriesBox.cols = len(self.itemlist) // 5 + 1 # add button for new entry (same as in create_entry_buttons()) temp_button = Button(text=added_name) temp_button.bind(on_release=self.press_entry) self.root.ids.entriesBox.add_widget(temp_button) # close popup self.root.ids.popup.dismiss() self.clear_fields() # try: # pass # except: # pass def clear_fields(self): """ Clear the text input fields from the add entry popup If we don't do this, the popup will still have text in it when opened again :return: None """ self.root.ids.addedItemName.text = "" self.root.ids.addedDescription.text = "" self.root.ids.addedPricePerDay.text = "" def press_cancel(self): """ Handler for pressing cancel in the add entry popup :return: None """ self.root.ids.popup.dismiss() self.clear_fields() self.status_text = ""
class Assignment2(App): def __init__(self, **kwargs): super (Assignment2, self).__init__(**kwargs) self.item_list = ItemList() items_storage = open("items.csv", "r+") for line in items_storage: self.item_list.store(line) def build(self): self.title = "Items Hire" self.root = Builder.load_file('Assignment2.kv') self.itemlist() return self.root def itemlist(self): self.root.ids.itemsBox.clear_widgets() self.root.ids.label.text = 'Choose action from the left menu, then select items on the right' self.root.ids.item_list.background_color = [0, 0.5, 0.5, 1] self.root.ids.hire_item.background_color = [1, 1, 1, 1] self.root.ids.return_item.background_color = [1, 1, 1, 1] self.root.ids.confirm.background_color = [1, 1, 1, 1] self.root.ids.add_item.background_color = [1, 1, 1, 1] item_count = 0 for line in self.item_list: name, description, price_per_day, availability = line.split(",") if "in" in availability: temp_button = Button(text=name, background_color=[0, 1, 0, 1]) else: temp_button = Button(text=name, background_color=[0.9, 0.3, 0.5, 1]) temp_button.bind(on_press=self.press_item) self.root.ids.itemsBox.add_widget(temp_button) item_count += 1 def itemreturn(self): self.root.ids.itemsBox.clear_widgets() self.root.ids.label.text = 'Choose action from the left menu, then select items on the right' self.root.ids.item_list.background_color = [1, 1, 1, 1] self.root.ids.hire_item.background_color = [1, 1, 1, 1] self.root.ids.return_item.background_color = [0, 0.5, 0.5, 1] self.root.ids.confirm.background_color = [1, 1, 1, 1] self.root.ids.add_item.background_color = [1, 1, 1, 1] for line in self.item_list: name, description, price_per_day, availability = line.split(",") if "in" in availability: temp_button = Button(text=name, background_color=[0, 1, 0, 1]) else: temp_button = Button(text=name, background_color=[0.9, 0.3, 0.5, 1]) temp_button.bind(on_press=self.press_item) self.root.ids.itemsBox.add_widget(temp_button) def itemhire(self): self.root.ids.itemsBox.clear_widgets() self.root.ids.item_list.background_color = [1, 1, 1, 1] self.root.ids.hire_item.background_color = [0, 0.5, 0.5, 1] self.root.ids.return_item.background_color = [1, 1, 1, 1] self.root.ids.confirm.background_color = [1, 1, 1, 1] self.root.ids.add_item.background_color = [1, 1, 1, 1] for line in self.item_list: name, description, price_per_day, availability = line.split(",") if "in" in availability: temp_button = Button(text=name, background_color=[0, 1, 0, 1]) else: temp_button = Button(text=name, background_color=[0.9, 0.3, 0.5, 1]) temp_button.bind(on_press=self.press_item) self.root.ids.itemsBox.add_widget(temp_button) def press_item(self, instance): for line in self.item_list: name, description, price_per_day, availability = line.split(",") if instance.text == name: if self.root.ids.item_list.background_color == [0, 0.5, 0.5, 1]: self.root.ids.label.text = "{} ({}), ${:,.2f} is {}".format(name, description, float(price_per_day), availability) elif self.root.ids.hire_item.background_color == [0, 0.5, 0.5, 1]: if "in" in availability: self.root.ids.label.text = "Hiring: {} for ${:,.2f}".format(name, float(price_per_day)) else: self.root.ids.label.text = "Hiring: no items for $0.00" elif self.root.ids.return_item.background_color == [0, 0.5, 0.5, 1]: if "out" in availability: self.root.ids.label.text = "Returning: {}".format(name) else: self.root.ids.label.text = "Returning: no items" def confirm(self): #this made a confirm change on the hire/return item_count = 0 with open("items.csv") as file: read_items = file.readlines() for line in read_items: name, description, price_per_day, availibility = line.split(",") if name in self.root.ids.label.text: if self.root.ids.hire_item.background_color == [0, 0.5, 0.5, 1]: self.item_list.clear() read_items[item_count] = read_items[item_count].replace("in", "out") with open("items.csv", "w") as file: file.writelines(read_items) for line in read_items: self.item_list.store(line) file.close() self.itemlist() elif self.root.ids.return_item.background_color == [0, 0.5, 0.5, 1]: self.item_list.clear() read_items[item_count] = read_items[item_count].replace("out", "in") with open("items.csv", "w") as file: file.writelines(read_items) # commit changes to the csv file for line in read_items: self.item_list.store(line) file.close() self.itemlist() item_count += 1 def save(self, name, description, price_per_day, availibility): #saves the details in the popup menu def price_check(cost): try: float(cost) return True except ValueError: return False if len(name.strip()) == 0 or len(description.strip()) == 0 or len(price_per_day.strip()) == 0: availibility.text = "All fields must be completed" elif price_check(price_per_day) == False: availibility.text = "Price must be valid number" elif price_check(price_per_day) == True and float(price_per_day) < 0: availibility.text = "Price cannot be negative" else: add_item = "\n{},{},{},in".format(name, description, float(price_per_day)) with open("items.csv", "a") as file: file.writelines(add_item) self.item_list.store(add_item) self.cancel() self.itemlist() def additem(self): #opens up the popup menu self.root.ids.item_list.background_color = [1, 1, 1, 1] self.root.ids.hire_item.background_color = [1, 1, 1, 1] self.root.ids.return_item.background_color = [1, 1, 1, 1] self.root.ids.confirm.background_color = [1, 1, 1, 1] self.root.ids.add_item.background_color = [0, 0.5, 0.5, 1] self.root.ids.popup.open() def cancel(self): #turn back the popup as it's default self.root.ids.itemName.text = "" self.root.ids.description.text = "" self.root.ids.price_per_day.text = "" self.root.ids.popup.dismiss() #closes the popup
def __init__(self, user_id): self._fines = float() self._identification = int() self._item_list = ItemList() self.user_id = user_id
def __init__(self, **kwargs): super (Assignment2, self).__init__(**kwargs) self.item_list = ItemList() items_storage = open("items.csv", "r+") for line in items_storage: self.item_list.store(line)
class ItemsForHire(App): # INITIALISER def __init__(self, **kwargs): """ Acts as the constructor for ItemsForHire which loads the items.csv to read the files and stores them in a list. """ super(ItemsForHire, self).__init__(**kwargs) self.list_item = ItemList() item_lines_list = open("items.csv", "r+") self.items = [] for line in item_lines_list: self.items.append(line + ",False") self.list_item.store(line) self.names = [] self.price = 0.00 # LOAD KIVY FILE def build(self): """ Is used to set the title of the app and loads the Kivy file for listing, hiring, returning, confirming. """ self.title = "Equipment Hire" self.root = Builder.load_file('main.kv') self.listing_items() return self.root # LIST ITEMS def listing_items(self): """ Is used to list items present in items.csv """ self.root.ids.item_buttons.clear_widgets() self.root.ids.list_item.background_color = (0, 0.99, 0.99, 1) self.root.ids.hire_item.background_color = (1, 1, 1, 1) self.root.ids.return_item.background_color = (1, 1, 1, 1) item_count = 0 for line in self.list_item: name, desc, price, hire = line.split(',') if "in" in hire: temp_button = Button(text=name, background_color=(0, 1, 0, 1)) else: temp_button = Button(text=name, background_color=(1, 0, 0, 1)) temp_button.bind(on_press=self.item_press) self.root.ids.item_buttons.add_widget(temp_button) item_count += 1 # HIRE ITEMS def hiring_items(self): """ Is used to hire an item if it is available """ self.names = [] self.price = 0.00 for item_count, line in enumerate(self.items): part = line.split(',') part[4] = "False" self.items[item_count] = "{},{},{},{},{}".format( str(part[0]).strip("[]").replace("'", ""), str(part[1]).strip("[]").replace("'", ""), str(part[2]).strip("[]").replace("'", ""), part[3].replace("'", ""), str(part[4]).strip("[]").replace("'", "")) self.root.ids.item_buttons.clear_widgets() self.root.ids.list_item.background_color = (1, 1, 1, 1) self.root.ids.hire_item.background_color = (0, 0.99, 0.99, 1) self.root.ids.return_item.background_color = (1, 1, 1, 1) for line in self.list_item: name, desc, price, hire = line.split(',') if "in" in hire: temp_button = Button(text=name, background_color=(0, 1, 0, 1)) else: temp_button = Button(text=name, background_color=(1, 0, 0, 1)) temp_button.bind(on_press=self.item_press) self.root.ids.item_buttons.add_widget(temp_button) # RETURN ITEM def returning_items(self): """ Is used to return an item that has been hired. """ self.names = [] for item_count, line in enumerate(self.items): part = line.split(',') part[4] = "False" self.items[item_count] = "{},{},{},{},{}".format( str(part[0]).strip("[]").replace("'", ""), str(part[1]).strip("[]").replace("'", ""), str(part[2]).strip("[]").replace("'", ""), part[3].replace("'", ""), str(part[4]).strip("[]").replace("'", "")) self.names = [] self.root.ids.item_buttons.clear_widgets() self.root.ids.list_item.background_color = (1, 1, 1, 1) self.root.ids.hire_item.background_color = (1, 1, 1, 1) self.root.ids.return_item.background_color = (0, 0.99, 0.99, 1) for line in self.list_item: name, desc, price, hire = line.split(',') if 'in' in hire: temp_button = Button(text=name, background_color=(0, 1, 0, 1)) else: temp_button = Button(text=name, background_color=(1, 0, 0, 1)) temp_button.bind(on_press=self.item_press) self.root.ids.item_buttons.add_widget(temp_button) # CONFIRM ITEM TO BE HIRED OR RETURNED def confirming_items(self): """ Is used to confirm an item when it is needed to be hired or returned """ with open("items.csv") as file: item_lines_list = file.readlines() for instance in self.root.ids.item_buttons.children: for item_count in range(len(self.items)): self.part = self.items[item_count].split(',') if instance.text in self.part: if (self.part)[3] == 'in\n' and (self.part)[4] == 'True': (self.part)[3] = 'out\n' (self.part)[4] = "False" self.items[item_count] = "{},{},{},{},{}".format( str(self.part[0]).strip("[]").replace("'", ""), str(self.part[1]).strip("[]").replace("'", ""), str(self.part[2]).strip("[]").replace("'", ""), self.part[3].replace("'", ""), str(self.part[4]).strip("[]").replace("'", "")) item_lines_list[item_count] = item_lines_list[ item_count].replace('in', 'out') self.list_item.clear() for line in item_lines_list: self.list_item.store(line) with open("items.csv", "w") as file: file.writelines(item_lines_list) self.listing_items() elif (self.part)[3] == 'out\n' and ( self.part)[4] == 'True': (self.part)[3] = 'in\n' (self.part)[4] = "False" self.items[item_count] = "{},{},{},{},{}".format( str(self.part[0]).strip("[]").replace("'", ""), str(self.part[1]).strip("[]").replace("'", ""), str(self.part[2]).strip("[]").replace("'", ""), self.part[3].replace("'", ""), str(self.part[4]).strip("[]").replace("'", "")) item_lines_list[item_count] = item_lines_list[ item_count].replace('out', 'in') self.list_item.clear() for line in item_lines_list: self.list_item.store(line) with open("items.csv", "w") as file: file.writelines(item_lines_list) self.listing_items() def item_press(self, instance): """ This converts an item from hire to hired and also displays message if an item is available to hire inside the label. """ item_count = 0 for line in self.list_item: name, desc, price, hire = line.split(',') if instance.text == name: if self.root.ids.list_item.background_color == [ 0, 0.99, 0.99, 1 ]: self.root.ids.main_label.text = "{} ({}), ${:,.2f} is {}".format( name, desc, float(price), hire) elif self.root.ids.hire_item.background_color == [ 0, 0.99, 0.99, 1 ]: part = self.items[item_count].split(",") if "in" in hire: if part[4] == "False": part[4] = "True" self.items[item_count] = "{},{},{},{},{}".format( str(part[0]).strip("[]").replace("'", ""), str(part[1]).strip("[]").replace("'", ""), str(part[2]).strip("[]").replace("'", ""), part[3].replace("'", ""), str(part[4]).strip("[]").replace("'", "")) self.root.ids.main_label.text = "Hiring: {} for ${:,.2f}.".format( name, float(price)) else: self.root.ids.main_label.text = "Hiring nothing." elif self.root.ids.return_item.background_color == [ 0, 0.99, 0.99, 1 ]: part = self.items[item_count].split(",") if "out" in hire: if part[4] == "False": part[4] = "True" self.items[item_count] = "{},{},{},{},{}".format( str(part[0]).strip("[]").replace("'", ""), str(part[1]).strip("[]").replace("'", ""), str(part[2]).strip("[]").replace("'", ""), part[3].replace("'", ""), str(part[4]).strip("[]").replace("'", "")) self.root.ids.main_label.text = "Returning: {}.".format( name) else: self.root.ids.main_label.text = "Returning nothing." item_count += 1 # ADDING A NEW ITEM def adding_new_items(self): """ Is used to add a new item to the csv file and I decided to use a different Kivy file because I found it to be messy when it was implemented on the main Kivy file. """ self.root.ids.item_buttons.clear_widgets() self.root.ids.list_item.background_color = (1, 1, 1, 1) self.root.ids.hire_item.background_color = (1, 1, 1, 1) self.root.ids.return_item.background_color = (1, 1, 1, 1) new_item = Builder.load_file('new_item.kv') self.pop_up = Popup(title="Add New Item", content=new_item) self.pop_up.open() def saving_new(self, name, desc, price, label): """ Is used to save new item to the csv and also does error checking incase the user enters funny values. """ def price_validity(price): try: float(price) return True except ValueError: return False if len(name.strip()) == 0 or len(desc.strip()) == 0 or len( price.strip()) == 0: label.text = "All fields must be completed" elif price_validity(price) == False: label.text = "Price must be valid number" elif price_validity(price) == True and float(price) < 0: label.text = "Price cannot be negative" else: item_new = "{},{},{},in".format(name, desc, float(price)) with open("items.csv", "a") as file: file.writelines(item_new) self.list_item.store(item_new) self.cancelling_new() self.listing_items() def cancelling_new(self): """ Is used when the user decides not to add a new item. """ self.pop_up.dismiss() self.listing_items() def on_stop(self): """ Displays the number of items present in items.csv after the App is closed. """ num_lines = sum(1 for line in open('items.csv')) print("{} items saved to items.csv".format(num_lines))
class MainWindow(App): label_text = StringProperty() selection = [] on_selection = None def set_selection(self, grid, *args): description = [] total_price = 0 self.selection = [] self.selection_with_idx = {} for node in grid.selected_nodes: record = self.items.items[node.storage_idx] self.selection.append(record) self.selection_with_idx[node.storage_idx] = record for record in self.selection: price = record.price name = record.name total_price += float(price) description.append(name) self.main_label.text = ",".join(description) + ":" + str(total_price) def on_button_pressed(self, button): print(button.state) def list_items(self, *args): self.main_label.text = "Choose action from the left menu, then choose items on the right " def hire_items(self, *args): inst = args[0] ## This will hire items for the current selection for record in self.selection: if record.status == 'out': self.main_label.text = "You are trying to hire an already hired equipment. Please return it first!" self.selection_with_idx = {} return True self.main_label.text = "Please click Confirm to hire!" return True def return_items(self, *args): for record in self.selection: if record.status == 'in': self.main_label.text = "You are trying to return a non-hired equipment. Please check your selections!" self.selection_with_idx = {} return False self.main_label.text = "Please click to Confirm to return!" return True def confirm(self, *args): ## Check if selected_functions is selected products = [] if len(self.selection_with_idx) == 0: self.main_label.text = "Confirm won't work! Fix your choices" return False ## If hire is being selected - then we set hired to all items in the file for key, record in self.selection_with_idx.items(): #print key, record if self.items.items[key].status == 'in': self.items.items[key].status = 'out' products.append(self.items.items[key].name) out_message = ' Items Hired' else: self.items.items[key].status = 'in' products.append(self.items.items[key].name) out_message = ' Items Returned' self.items.save() self.main_label.text = ','.join(products) + out_message return True def add_new_item(self, *args): self.sm.transition.direction = 'left' self.sm.current = "add_item" def build_main(self): main_layout = BoxLayout(padding=5, orientation='vertical') group_layout = BoxLayout(padding=5) actions = { 'List items': self.list_items, 'Hire items': self.hire_items, "Return Items": self.return_items, "Confirm": self.confirm, "Add New Item": self.add_new_item } items = self.items.load() colors = [red, green, blue, purple] h_layout = BoxLayout( padding=5, orientation='vertical', size_hint_x=None, width=150, ) for action_name in sorted(actions.keys()): callback = actions[action_name] btn = ToggleButton(text=action_name, background_color=gray, group="actions") btn.bind(on_press=callback) h_layout.add_widget(btn) group_layout.add_widget(h_layout) items = list(items.values()) layout = SelectableGrid(cols=2, up_count=5, multiselect=True, scroll_count=1) for idx, item in self.items.items.items(): #print(idx) # category, name, cost, state = item btn = Button(text=item.name, background_color=color_for_state(item.status)) btn.bind(on_touch_down=layout.do_touch) btn.storage_idx = idx layout.add_widget(btn) layout.bind(selected_nodes=self.set_selection) layout.items = self.items group_layout.add_widget(layout) main_layout.add_widget(group_layout) self.main_label = Label(text="loading...", size_hint_y=None, height=50) self.selected_functions = [] main_layout.add_widget(self.main_label) return main_layout def build(self): self.items = ItemList('items.csv') self.items.load() self.main = MainScreen(name='main') self.main.add_widget(self.build_main()) sm.add_widget(self.main) self.add_item_screen = AddItemScreen(name='add_item') self.add_item_screen.items = self.items sm.add_widget(self.add_item_screen) self.sm = sm sm.current = "main" return sm
def __init__(self, keyword_class=Keyword, parent=None, keywords=None): ItemList.__init__(self, keyword_class, {'parent': parent}, keywords)
class ItemsGUI(App): # This status text is a label that changes dynamically depending on item selected. Default value is within __init__ status_text = StringProperty() def __init__(self, **kwargs): """ Initializer for app class - allows for other classes to be imported and declared :param kwargs: :return: """ super(ItemsGUI, self).__init__(**kwargs) self.items = ItemList() self.mode = LIST_MODE self.selected_items = [] self.status_text = "Choose action from the left menu, then select items on the right" def build(self): """ This actually builds and constructs the GUI :return: self.root """ self.title = "Equipment Hire" self.root = Builder.load_file('GUI.kv') self.create_item_buttons() return self.root def create_item_buttons(self): """ This class function dynamically builds and constructs the buttons dependant upon how many items are within the CSV file :return: """ for item in self.items.items: temp_button = Button(text=item.name) temp_button.bind(on_release=self.press_entry) self.root.ids.itemsBox.add_widget(temp_button) # The below statement changes the buttons colour to red if the items availability is 'out' if item.in_or_out == "out": temp_button.background_color = (1.0, 0.0, 0.0, 1.0) def update_buttons(self): """ This function runs upon the selection of a menu button to both reset the state of the buttons and also to update the colours depending upon changes made. :return: """ for instance in self.root.ids.itemsBox.children: instance.state = 'normal' item_name = instance.text item = self.items.get_item(item_name) if item.in_or_out == "out": instance.background_color = (1.0, 0.0, 0.0, 1.0) else: instance.background_color = (1.0, 1.0, 1.0, 1.0) def press_entry(self, instance): """ This class function changes the text notification within the bottom status label :param instance: --> instance is derived from the 'create_item_buttons' function :return: """ item_name = instance.text item = self.items.get_item(item_name) if self.mode == LIST_MODE: self.status_text = "{} ({}) = ${:.2f} is {}".format(item.name, item.description, item.cost, item.in_or_out) elif self.mode == HIRE_MODE: self.hire_mode_functionality(item, instance) elif self.mode == RETURN_MODE: self.return_mode_functionality(item, instance) def hire_mode_functionality(self, item, instance): """ Code within this function is segregated into separate function from where it is used to increase readability and actually performs the workings of HIRE_MODE :param item: :param instance: :return: """ if item.in_or_out == "in": if item not in self.selected_items: self.selected_items.append(item) instance.state = "down" else: self.selected_items.remove(item) instance.state = "normal" names = [] total_cost = 0 for item in self.selected_items: total_cost += item.cost names.append(item.name) name_str = ",".join(names) if name_str == '': self.status_text = "Hiring : Nothing" else: self.status_text = "Hiring : {} for ${:.2f}".format(name_str, total_cost) def return_mode_functionality(self, item, instance): """ Code within this function is segregated into separate function from where it is used to increase readability and actually performs the workings RETURN_MODE :param item: :param instance: :return: """ if item.in_or_out == "out": if item not in self.selected_items: self.selected_items.append(item) instance.state = "down" else: self.selected_items.remove(item) instance.state = "normal" names = [] for item in self.selected_items: names.append(item.name) name_str = ",".join(names) if name_str == '': self.status_text = "Returning : Nothing" else: self.status_text = "Returning : {}".format(name_str) def handle_list_items(self): """ This function occurs when the 'list items' button is selected and changes button states, status texts and sets the mode. The list constructed for the selected items is also reset. :return: """ self.selected_items = [] self.status_text = "Choose action from the left menu, then select items on the right" self.mode = LIST_MODE self.root.ids.list_items_btn.state = "down" self.root.ids.hire_items_btn.state = "normal" self.root.ids.return_items_btn.state = "normal" self.update_buttons() def handle_hire_item(self): """ This function occurs when the 'hire items' button is selected and changes button states, status texts and sets the mode. The list constructed for the selected items is also reset. :return: """ self.selected_items = [] self.status_text = "Select available items to hire" self.mode = HIRE_MODE self.root.ids.list_items_btn.state = "normal" self.root.ids.hire_items_btn.state = "down" self.root.ids.return_items_btn.state = "normal" self.update_buttons() def handle_return_item(self): """ This function occurs when the 'return items' button is selected and changes button states, status texts and sets the mode. The list constructed for the selected items is also reset. :return: """ self.selected_items = [] self.status_text = "Select available items to return" self.mode = RETURN_MODE self.root.ids.list_items_btn.state = "normal" self.root.ids.hire_items_btn.state = "normal" self.root.ids.return_items_btn.state = "down" self.update_buttons() def handle_confirm(self): """ This function runs when the 'confirm' button is selected and changes items and button states according to current mode the user is in (HIRE_MODE or RETURN_MODE). The mode is then reset back to the default LIST_MODE :return: """ self.root.ids.list_items_btn.state = "normal" self.root.ids.hire_items_btn.state = "normal" self.root.ids.return_items_btn.state = "normal" for item in self.selected_items: if self.mode == HIRE_MODE: item.in_or_out = "out" elif self.mode == RETURN_MODE: item.in_or_out = "in" self.mode = LIST_MODE self.update_buttons() def handle_add_item(self): """ This opens the popup for add items :return: """ self.root.ids.popup.open() def handle_save_item(self): """ Function allows for added items to be appended to the already constructed items list. :return: """ # Gets item information from kv file added_name = self.root.ids.added_name.text added_description = self.root.ids.added_description.text added_price = self.root.ids.added_price.text # Adds in error checking --> Try statement checks if numeric value is entered into item cost try: # Further error checking --> While checks values aren't NULL and that item cost > 0 # N.B attempted to add price > $0 into own error checking loop but repeatedly crashed GUI so left as is while added_name != "" and added_description != "" and float(added_price) > 0: # Adds information found within kv file to function within itemlist self.items.add_item_from_values(added_name, added_description, added_price) temp_button = Button(text=added_name) temp_button.bind(on_release=self.press_entry) self.root.ids.itemsBox.add_widget(temp_button) # closes popup self.root.ids.popup.dismiss() self.clear_fields() # Updates the popups status text with error message, also changes colour to red to let show that it is error self.root.ids.popup_status_text.text = "ITEM INPUT CAN NOT BE NULL AND ITEM COST MUST BE > $0" self.root.ids.popup_status_text.color = (1.0, 0.0, 0.0, 1.0) except ValueError: self.root.ids.popup_status_text.text = "ITEM COST MUST BE NUMERIC" self.root.ids.popup_status_text.color = (1.0, 0.0, 0.0, 1.0) def clear_fields(self): """ This clears inputted data from add group if cancel button is clicked. :return: """ self.root.ids.added_name.text = "" self.root.ids.added_description.text = "" self.root.ids.added_price.text = "" def handle_cancel(self): """ This handles the actions of the cancel button within the add group :return: none """ # closes the popup window self.root.ids.popup.dismiss() self.clear_fields() def on_stop(self): """ This function uses kivy method to activate upon closing of GUI. Actual function will return and export to csv :return: """ items_to_save = self.items.get_items_for_saving() # calls previous assignments csv updating function update_csv(items_to_save)