def sortByRank(canteens=db.readFile()): """ Sorts the list of canteens by rank Accepts optional argument list of canteens Returns a sorted list of canteens """ return mergesort(canteens, 'rank')
def foodDone(bot, update, user_data): """ User done with choosing food Checks if food chosen is in the database If yes, sends user to PRICE state Else, sends user back to FOOD state """ user = update.message.from_user if 'foodList' not in user_data: update.message.reply_text( "You did not input anything, so there will be no filter on the food" ) logger.info("{}'s list contains everything!".format(user.first_name)) update.message.reply_text('Okay now choose an upper price range') user_data['canteens'] = db.readFile() return PRICE logger.info("Adding to list") user_data['canteens'] = algo.searchByFood(user_data['foodList']) if not len(user_data['canteens']): user_data['foodList'] = [] update.message.reply_text( "Sorry, looks like the food you chose cannot be found. Please choose again. Type /done when finished" ) return FOOD else: logger.info("{}'s list contains {}".format(user.first_name, user_data['foodList'])) update.message.reply_text('Okay now choose an upper price range') return UPPER
def sortByDist(userLocation, canteens=db.readFile(), latlong=True): """ Gets the distance between the user's location and each of the canteens Accepts userLocation as tuple (x,y), and optional argument list of canteens If flag latlong is set, gets distance based on latitude and longtitude Returns a sorted list of canteens sorted by distances, in ascending order """ dist = [] for canteen in canteens: # Uses either latitude-longtitude or coordinates dist = getDistLatLong(userLocation, canteen['loc']) if latlong else getDistance( userLocation, canteen['coords']) canteen['dist'] = dist return mergesort(canteens, 'dist')
def formatCanteens(canteens=db.readFile()): """ Formats a list of canteens for printing Accepts an optional argument list of canteens to print out Returns a formated list of canteens """ msg = "" for c in canteens: msg += "{}\n".format(c['name']) if 'dist' in c: msg += " Distance - {} m\n".format(c['dist']) msg += " Rank - {}\n".format(c['rank']) msg += " Food:\n" for food, price in c['food'].items(): msg += " {0} - ${1:0.2f}\n".format(food, price) msg += "\n" return msg
def searchByPrice(upper, alist=db.readFile()): """ Searches through a list of canteens, and filters out the canteens which do not contain food within the price range Accepts an upper limit, and an option argument list of canteens Returns the filtered list of canteens """ # Iterates through the list to filter out the items based on food upper = upper if upper else float('inf') temp = [] for canteen in alist: temp2 = {} for k, v in canteen['food'].items(): if v <= upper: temp2[k] = v if len(temp2): canteen['food'] = temp2 temp.append(canteen) return temp
def searchByFood(food, alist=db.readFile()): """ Searches through a list of canteens, and filters out the canteens which do not contain any of the food Accepts a list of food names, and an optional argument list of canteens Returns the filtered list of canteens """ # Iterates through the list to filter out the items based on food temp = [] for canteen in alist: temp2 = {} # Searches for a string for k, v in canteen['food'].items(): formatedKey = ''.join(k.split('_')) for f in food: if formatedKey.find(f) >= 0: temp2[k] = v if len(temp2): canteen['food'] = temp2 temp.append(canteen) return temp
def getFood(canteens): """ Asks user for food that user wants to eat, and filters out the canteens Accepts a list of canteens Returns a list of canteens """ foodList = [] # Gets list of food from user food = input( "What food would you like to eat today?\nEnter all the food you want to eat, and press enter again when done\nIf empty, will take all foods\n" ) while food != '': foodList.append(food) food = input() print() # Empty list, no filter on food if not len(foodList): return db.readFile() # Filters out canteens based on the food list given else: for i in range(len(foodList)): # Reformat the searches foodList[i] = ''.join(foodList[i].lower().split()) # Searches for the food temp = algo.searchByFood(foodList, canteens) # Choice not found if not len(temp): print( "Please choose some other food, we could not find your choices in any of the canteens\n" ) return getFood(canteens) else: canteens = temp return canteens
def main(): """ Main function, handles user choice - Find a canteen based on: - Food - Price - Sorts the canteens based on: - Distance - Rank - Updates info of a canteen """ print() canteens = db.readFile() # Get choice action = getInput(actionMsg, actionList) # Finds the canteen based on criteria if action == '1': # Search by food canteens = getFood(canteens) # Search by price canteens = getPrice(canteens) # Sort sort = getInput(sortMsg, sortList, exit=False) # Sort by distance if sort == '1': print("Please click your current location") coords = gui.getCoordsClick(mapPath, scaledSize) canteens = algo.sortByDist(coords, canteens, False) # Sort by rank elif sort == '2': canteens = algo.sortByRank(canteens) print(algo.formatCanteens(canteens)) # Updates canteen elif action == '2': finish = False while not finish: # Asks user what he wants to do update = getInput(updateMsg, updateList) canteens = db.readFile() newCanteens = canteens # Exit if int(update) == len(updateList) + 1: finish = True # Lists all canteens elif update == '1': print(algo.formatCanteens(newCanteens)) continue # Fetch a canteen and edit information elif update == '2': # Asks user which canteen to update, or exits editCan = getInput(editMsg, editList) if int(editCan) == len(editList) + 1: break canIndex = int(editCan) - 1 # Asks user which property to update, or exits editType = getInput(typeMsg, typeList) if int(editType) == len(typeList) + 1: break type = typeList[int(editType) - 1] validInput = False while not validInput: # Prints out specific guidelines for the property that the user is trying to update print(guideline[type]) # Edit rank if type == 'Edit rank': rank = input("New rank for {}: ".format( editList[canIndex])) if rank.isdigit() and 1 <= int(rank) <= 10: newCanteens[canIndex]['rank'] = int(rank) validInput = True else: print( "Invalid input, try again with a number 1-10.\n" ) # Add food elif type == 'Add food': food = input("New food for {}: ".format( editList[canIndex])) price = input("New price for {}: ".format(food)) print() try: # Format food food = '_'.join(food.lower().split()) if food in newCanteens[canIndex]['food']: print("{} is already in the list of foods\n". format(food)) else: # Check if price is a positive float if float(price) < 0: raise ValueError # Assigns new price newCanteens[canIndex]['food'][food] = float( price) validInput = True except ValueError: print("Invalid input, please try again") # Remove food elif type == 'Remove food': foodList = list(newCanteens[canIndex]['food'].keys()) # Canteen still has food to remove if len(foodList): index = int( getInput("Select food to remove", foodList, exit=False)) - 1 newCanteens[canIndex]['food'].pop(foodList[index]) # No food in the canteen else: print("Sorry, no foods to remove\n") validInput = True # Edit food/price elif type == 'Edit food/price': foodList = list(newCanteens[canIndex]['food'].keys()) # Canteen still has food to edit if len(foodList): index = int( getInput("Select food to edit", foodList, exit=False)) - 1 price = input("Select new price for {}: ".format( foodList[index])) print() try: # Check if price is a positive float if float(price) < 0: raise ValueError # Assigns new price newCanteens[canIndex]['food'][ foodList[index]] = float(price) validInput = True except ValueError: print( "Invalid input, try again with price as a positive number" ) # No food in the canteen else: print("Sorry, no foods to edit\n") validInput = True else: print("Currently unavailable.") break db.writeFile(newCanteens) # End program print("Thanks for using our app")
mapSize = (1310, 1600) scaledSize = (int(mapSize[0] / 3), int(mapSize[1] / 3)) # List of messages / options actionMsg = "Welcome to NTU F&B Recommendations!\nWhat would you like to do?" actionList = ["Find a canteen", "Update information"] sortMsg = "How would you like to sort your choices?" sortList = ['Distance', 'Rank'] updateMsg = "What would you like to do?" updateList = [ "List out all information", "Select a canteen to update the information" ] editMsg = "which canteen?" editList = [c['name'] for c in db.readFile()] typeMsg = "Which type of info?" typeList = ['Edit rank', 'Add food', 'Remove food', 'Edit food/price'] guideline = { 'Edit rank': "For ranking, please input an integer between 1 and 10 :)", 'Add food': "Type in a new food, and a price", 'Remove food': "Select one of the foods", 'Edit food/price': "Which of these foods do you want to edit?" } if __name__ == '__main__': main()