Ejemplo n.º 1
0
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')
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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')
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
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")
Ejemplo n.º 9
0
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()