Example #1
0
    def printScreen(self):
        """
		Provides the main functionality of AnswerListMenu
		Calls various methods to print answers to the screen and
		provides the user with the ability to select one of them

		Returns:
			A Dictionary object representing an answer to the question
		"""
        invalidInput = True
        while invalidInput:
            Terminal.clear()
            PostPrinter.printTitle(self.__question__)
            print("\n")
            self.printMenu()
            userInput = input("Enter Selection: ")
            if userInput.upper() == "EXIT" or userInput.upper() == "QUIT":
                return None
            try:
                userInput = int(userInput)
                if userInput < 1 or userInput > len(self.__menuItems__):
                    print("Input is out of range")
                else:
                    invalidInput = False
            except Exception:
                print("Entered input is invalid!")
            finally:
                input("Press Enter to Continue: ")
        userInput += -1
        return self.__menuItems__[userInput].Post
    def printScreen(self):
        """
		The main loop of Menu. Serves to print all menu items,
		gather userInput and ensure that input is valid

		Returns:
			userInput if the input provided is valid
			None if the input provided is invalid
		"""
        while True:
            self.printItems()
            userInput = input(
                "Type the number of the item you would like to select: ")
            try:
                userInput = int(userInput) - 1
                if (userInput <= self.__length__ - 1 and userInput >= 0):
                    return userInput
                else:
                    input("Invalid selection, press enter to continue: ")
            except Exception:
                try:
                    if userInput.upper() == "EXIT":
                        return None
                except Exception:
                    input("Invalid input, press enter to continue: ")
            Terminal.clear()
Example #3
0
class AnswerList:
    """
	AnswerList provides an interface between AnswerListScreen and the database

	AnswerList queries the database to get answers for AnswerListScreen
	"""
    client = pymongo.MongoClient('localhost', int(Terminal.getPort()))
    db = client[Terminal.getDBName()]

    def getAnswers(question):
        """
		Grabs answers if their parent ID matches the selected questions ID

		Parameters:
			question:
				A Dictionary object representing a question from the database
		Returns:
			A Dictionary of dictionaries representing various answers to the question
		"""
        answers = {}
        collection = AnswerList.db['Posts']
        query = {'$and': [{'ParentId': question['Id']}, {'PostTypeId': '2'}]}
        results = collection.find(query)
        for result in results:
            answers[result['Id']] = result
        return answers
Example #4
0
    def printTitle(post):
        """
		Prints the post in a formatted fashion

		Parameters:
			post:
				A dictionary object representing a post retrieved from the database

		"""
        Terminal.clear()
        usedKeys = [
            "Id", "Title", "Body", "Tags", "Score", "ViewCount",
            "CommentCount", "AnswerCount", "FavoriteCount", "ContentLicense",
            "CreationDate", "LastEditDate"
        ]

        Terminal.printCenter("----------Post----------")
        for key in usedKeys:
            if (key in post):
                PostPrinter.printKeyTitle(key)
                Terminal.printCenter(key + ": " + str(post[key]) + "\n")

        Terminal.printCenter("----------Misc Info----------")
        for key in post:
            if (key is not None and key not in usedKeys and key != "_id"):
                Terminal.printCenter(str(key) + ": " + str(post[key]) + "\n")
Example #5
0
    def printScreen(self):
        """
		The main loop of the module. Prints the title and get's users input on whether they
		are registering or logging in
		"""
        while True:
            self.printTitle()
            userInput = input(
                "If you're an existing user, please enter your id. Otherwise, press enter: "
            ).strip()

            #if the user presses enter
            if userInput == "":
                return -1
            #if the user enters an id
            elif userInput.upper() != "EXIT":
                #TODO: User report
                print("Loading...")
                report = self.report(userInput)
                print("Number of questions posted: {}. Average score: {}.".
                      format(report["num_questions"], report["qavg_score"]))
                print(
                    "Number of answers posted: {}. Average score: {}.".format(
                        report["num_answers"], report["aavg_score"]))
                print("Number of votes: {}".format(report["num_votes"]))
                input("Press enter to continue...")
                return userInput

            elif userInput.upper().strip() == "EXIT":
                return None
            else:
                input("Invalid input, press enter to continue: ")
                Terminal.clear()
    def printScreen(self):
        """
		Provides the main functionality of SearchQuestionMenu
		Prints various posts and prompts the user for input
		checks said input before returning the post selected

		Returns:
			A Dictionary object representing a post from the database
		"""
        continueRunning = True
        index = 0
        while continueRunning:
            self.printMenu(index)
            userInput = input("Enter Selection: ")
            if userInput.upper() == "EXIT" or userInput.upper() == "QUIT":
                return None
            elif userInput.upper() == "NEXT":
                if index + SearchQuestionMenu.POSTS_PER_PAGE < len(
                        self.__menuItems__):
                    index += SearchQuestionMenu.POSTS_PER_PAGE
                else:
                    print("You are currently on the last page!")
                    input("Type Enter to Continue: ")
            elif userInput.upper() == "PREV":
                if index >= SearchQuestionMenu.POSTS_PER_PAGE:
                    index += SearchQuestionMenu.POSTS_PER_PAGE
                else:
                    print("You are currently on the first page!")
                    input("Press Enter to Continue: ")
            else:
                try:
                    userInput = int(userInput)
                    if (userInput < 1
                            or userInput > SearchQuestionMenu.POSTS_PER_PAGE
                            or userInput > len(self.__menuItems__[index:])):
                        print("Input is out of range")
                    else:
                        continueRunning = False
                except Exception:
                    print("Entered input is invalid!")
                finally:
                    input("Press Enter to Continue: ")

        userInput += -1 + index

        selectedPost = self.__menuItems__[userInput]

        client = pymongo.MongoClient('localhost', int(Terminal.getPort()))
        db = client[Terminal.getDBName()]
        collection = SearchForQuestions.db["Posts"]

        updatedViewCount = selectedPost.Post['ViewCount'] + 1
        updateQuery = {'$set': {'ViewCount': updatedViewCount}}

        collection.update_one(selectedPost.Post, updateQuery)

        return selectedPost.Post
Example #7
0
    def report(self, uid):
        #TODO: print the user report out
        """
		(1) the number of questions owned and the average score for those questions
		(2) the number of answers owned and the average score for those answers
		(3) the number of votes registered for the user.
		"""
        client = pymongo.MongoClient('localhost', int(Terminal.getPort()))
        db = client[Terminal.getDBName()]

        posts = db.Posts
        votes = db.Votes

        #PART 1

        #all of the questions
        num_questions = 0
        total_score = 0

        questions = posts.find({"OwnerUserId": uid, "PostTypeId": "1"})

        for dictionary in questions:
            num_questions += 1
            total_score += dictionary["Score"]

        try:
            qavg_score = total_score / num_questions
        except ZeroDivisionError:
            qavg_score = 0
        #print("Number of questions: {}. Average score: {}.".format(num_questions, qavg_score))

        #PART 2
        num_answers = 0
        total_score = 0

        answers = posts.find({"OwnerUserId": uid, "PostTypeId": "2"})

        for dictionary in answers:
            num_answers += 1
            total_score += dictionary["Score"]

        try:
            aavg_score = total_score / num_answers
        except ZeroDivisionError:
            aavg_score = 0
        #PART 3

        num_votes = votes.count_documents({"UserId": uid})

        return {
            "num_questions": num_questions,
            "num_answers": num_answers,
            "qavg_score": qavg_score,
            "aavg_score": aavg_score,
            "num_votes": num_votes
        }
Example #8
0
    def __init__(self):
        """
		Creates an instance of WelcomeScreen, which is the UI interface for welcoming users to the
		program.
		Parameters:
			N/A
		Returns:
			An instance of WelcomeScreen
		"""
        Terminal.clear()
    def __init__(self):
        """
		Creates an instance of Menu

		Parameters:
			terminal:
				A Terminal object allowing this module to interface
				with the OS terminal
		Returns:
			An instance of Menu
		"""
        self.__menuItems__ = []
        self.__length__ = 0

        Terminal.clear()
Example #10
0
	def __check_tag__(self, user_tags):
		"""
		Looks up the tag in the document of tags. If it's there, increase the count by 1. If not, add the tag and set the count to 1.
		
		Parameters:
			user_tags: list of strings. All of the tags to alter/enter in the tags collection
			
		Returns: N/A
		"""		
		#opens the tags collection
		client = pymongo.MongoClient('localhost', int(Terminal.getPort()))
		db = client['291db']
		tags = db.Tags
		
		#for each tag the user gives
		for tag in user_tags:
			
			#See if the tag exists
			result = tags.find_one({"TagName": tag})
			
			#If it exists, increment the count by 1
			if result:
				count = result["Count"]
				tags.update_one({"TagName": tag}, {'$set':{"Count": count + 1}})
			#If it doesn't exist, add it to the db
			else:
				
				tid = self.get_tagID()
				tags.insert_one({"Id": str(tid), "TagName": tag, "Count": 1})
    def printTitleKeyword():
        """
		Prints identifying information telling the user what screen
		they are on and information about how to give keywords
		"""
        Terminal.clear()
        Terminal.printCenter("Search for Posts")
        Terminal.printCenter("Enter terms delimited by commas")
Example #12
0
	def get_info(self, pid):
		"""
		Given a pid, returns the title and body of a question.
		
		Parameters: 
			Pid: 4 char string. The post ID of the post to get info from
		
		Returns:
			Tuple of title and body of post, both of which are strings.
		"""
		#log into db
		client = pymongo.MongoClient('localhost', int(Terminal.getPort()))

		db = client['291db']

		posts = db.Posts
		
		#grab the post by post ID, this should be really really fast
		post = posts.find_one({"Id": pid})
		
		return [post["Title"], post["Body"]]
Example #13
0
    def printKeyTitle(key):
        """
		printKeyTitle prints a sort of descriptor for subcategories of the post
		delimited as Title, Body, Tags, Post Data (ViewCount, CommentCount, Score, etc.), 
		Dates (Creation, Edited, etc.)

		Parameters:
			key:
				A String object representing a key of the dictionary
		"""
        if key == "Title" or key == "Body" or key == "Tags":
            string = "----------" + key + "----------" + "\n"
            Terminal.printCenter(string)
        if key == "Score":
            string = "----------" + "Post Data" + "----------" + "\n"
            Terminal.printCenter(string)
        if key == "CreationDate":
            string = "----------" + "Dates" + "----------" + "\n"
            Terminal.printCenter(string)
Example #14
0
	def get_tagID(self):
		"""
		Generates a unique TagID.
		
		Parameters: N/A
		
		Returns: 
			tagID: Integer. Unique ID for the tag
		"""
		
		client = pymongo.MongoClient('localhost', int(Terminal.getPort()))

		db = client['291db']

		tags = db.Tags
		
		def findMaxAndMin(collection):
			"""
			Generates a min and max starting point for binary search. 
			
			Parameters: 
				Collection: a pymongo collection. The place to find the min and max within the ID's
				
			returns:
				list of ints. It will always return [2^n, 2^n+1] for some n, found by seeing if the current max number is a used ID.
			"""
			maxNum = 1
			minNum = 1
			while  collection.find_one({'Id': str(maxNum)}) is not None:
				minNum = maxNum
				maxNum *= 2
			
			return [minNum, maxNum]


		nums = findMaxAndMin(tags)
		minNum = nums[0]
		maxNum = nums[1]
		"""TESTING
		print(minNum, maxNum)
		print(type(minNum), type(maxNum))
		print("+++++++++++\n")
		"""

		while True:
			num = (minNum + maxNum) // 2
			
			search = tags.find_one({'Id': str(num)})
			
			try:
				if int(search["Id"]) >= minNum:
					minNum = num
				else:
					maxNum = num
			except:
				maxNum = num
			
			"""TESTING
			print("Min", minNum)
			print(maxNum)
			print(num)
			"""
				
			if minNum == maxNum or minNum+1 == maxNum:
				num = maxNum
				break
				
		#print("Final tagID:", num)
		return num
Example #15
0
	def add_post(self, title, body, tags, qpid=None):
		"""
		Adds a question to the database, using a private function __get_pid__ to generate a unique PID.
		
		Parameters:
			Title: String. The title of the question.
			Body: String. The content of the question.
			Tags: List. List of all tags to add
			Qpid: optional argument. If included, the post is an answer.
				 Otherwise, qpid is None and the post is a question.
			
		Returns:
			N/A
		"""
		#log into db
		client = pymongo.MongoClient('localhost', int(Terminal.getPort()))

		db = client['291db']

		posts = db.Posts
		
		#Generates unique pid
		pid = self.get_pid()
		
		#Formats the tags for entry into db
		if tags:
			all_tags = ""
			for tag in tags:
				all_tags += "<{}>".format(tag)
		
		"""
		A unique id should be assigned to the post by your system, the post type id should be set to 1 (to indicate that the post is a question).
		The post creation date should be set to the current date and the owner user id should be set to the user posting it (if a user id is provided). 
		The quantities Score, ViewCount, AnswerCount, CommentCount, and FavoriteCount are all set to zero and the content license is set to "CC BY-SA 2.5".
		"""
		
		#if the post is a question, insert the question
		if qpid is None:
			
			#If the uid is given
			if self.__uid__ is not None:
				
				#If the user gives tags
				if tags is not None:
					post = {"Id": str(pid), "PostTypeId": "1", "CreationDate": str(datetime.datetime.utcnow().isoformat()), 
					"Score": 0, "ViewCount": 0, "Body": body, "OwnerUserId": self.__uid__, "Title": title,
					"Tags": all_tags, "AnswerCount": 0, "CommentCount": 0, "FavoriteCount": 0, "ContentLicense": "CC BY-SA 4.0"}
					
					posts.insert_one(post)
					#add the tags or add 1 to the counter for each tag
					self.__check_tag__(tags)
					
				#User gives no tags
				else:
					post = {"Id": str(pid), "PostTypeId": "1", "CreationDate": str(datetime.datetime.utcnow().isoformat()), 
					"Score": 0, "ViewCount": 0, "Body": body, "OwnerUserId": self.__uid__, "Title": title,
					 "AnswerCount": 0, "CommentCount": 0, "FavoriteCount": 0, "ContentLicense": "CC BY-SA 4.0"}
					
					posts.insert_one(post)
					
			#No uid is given	
			else:
				#Tags are given
				if tags is not None:
					post = {"Id": str(pid), "PostTypeId": "1", "CreationDate": str(datetime.datetime.utcnow().isoformat()),
					 "Score": 0, "ViewCount": 0, "Body": body, "Title": title,
					"Tags": all_tags, "AnswerCount": 0, "CommentCount": 0, "FavoriteCount": 0, "ContentLicense": "CC BY-SA 4.0"}
					#print(post)
					
					posts.insert_one(post)
					#add the tags or add 1 to the counter for each tag
					self.__check_tag__(tags)
					
				#Tags are not given
				else:
					post = {"Id": str(pid), "PostTypeId": "1", "CreationDate": str(datetime.datetime.utcnow().isoformat()),
					 "Score": 0, "ViewCount": 0, "Body": body, "Title": title,
					 "AnswerCount": 0, "CommentCount": 0, "FavoriteCount": 0, "ContentLicense": "CC BY-SA 4.0"}
					#print(post)
					
					posts.insert_one(post)
					
		#Post is an answer
		else:
			"""
			Question action-Answer. The user should be able to answer the question by providing a text. An answer record should be inserted into the database, with body field set to the provided text. A unique id should be assigned to the post by your system, the post type id should be set to 2 (to indicate that the post is an answer), the post creation date should be set to the current date and the owner user id should be set to the user posting it (if a user id is provided). The parent id should be set to the id of the question. The quantities Score and CommentCount are all set to zero and the content license is set to "CC BY-SA 2.5".
			"""
			if self.__uid__ is not None:
				post = {"Id": str(pid), "PostTypeId": "2", "ParentId": qpid, "CreationDate": str(datetime.datetime.utcnow().isoformat()), 
				"Score": 0, "ViewCount": 0, "Body": body, "OwnerUserId": self.__uid__, 
				"CommentCount": 0, "ContentLicense": "CC BY-SA 4.0"}
				posts.insert_one(post)
				
			else:
				post = {"Id": str(pid), "PostTypeId": "2", "ParentId": qpid, "CreationDate": str(datetime.datetime.utcnow().isoformat()), 
				"Score": 0, "ViewCount": 0, "Body": body, "CommentCount": 0, "ContentLicense": "CC BY-SA 4.0"}
				posts.insert_one(post)
Example #16
0
        #if the user doesn't enter an id
        if isUser == -1:
            uid = None
            pass
        #if the user enters an id
        elif isUser:
            uid = isUser
            pass
        else:
            #Quitting the program, leads to a goodbye message outside of loop.
            break

        #Input loop for command choice.
        while True:
            #indexing. This can take a couple seconds to do, but man is it worth it for the time it saves.
            client = pymongo.MongoClient('localhost', int(Terminal.getPort()))
            db = client["291db"]
            posts = db["Posts"]
            tags = db['Tags']
            votes = db["Votes"]

            #This index is used for generating new post ID's
            posts.create_index([("Id", 1)])

            #This index is used for checking how many votes a user has
            votes.create_index([("UserId", 1)])

            #This index is used for generating new vote ID's
            votes.create_index([("Id", -1)])

            #This index is used for searching for tags
class SearchForQuestions:
    """
	SearchForQuestions serves as an interface between SearchForQuestionsScreen
	and the database

	SearchForQuestions allows SearchForQuestionsScreen to query the database through
	it's methods
	"""
    client = pymongo.MongoClient('localhost', int(Terminal.getPort()))
    db = client[Terminal.getDBName()]

    def getQuestions(searchKeys):
        """
		getQuestions fetches any posts matching the searchKeys
		by calling various methods

		Parameters:
			searchKeys:
				A List of String objects representing search terms entered by
				the user
		Returns:
			A Dictionary object of dictionaries representing posts that match the search
			terms
		"""
        posts = {}
        posts = SearchForQuestions.getMatchingTitle(searchKeys, posts)
        posts = SearchForQuestions.getMatchingBody(searchKeys, posts)
        posts = SearchForQuestions.getMatchingTag(searchKeys, posts)
        return posts

    def getMatchingTitle(searchKeys, posts):
        """
		Fetches any posts whose title matches one of the
		searchTerms

		Parameters:
			searchKeys:
				A List of String objects representing search terms entered by
				the user
			posts:
				A Dictionary object of Dictionaries to append any posts
				retrieved through the query
		Returns:
			A Dictionary object of dictionaries representing posts that match the search
		"""
        collection = SearchForQuestions.db["Posts"]

        for keyWord in searchKeys:
            searchQuery = {
                '$and': [{
                    'Title': {
                        '$regex': keyWord,
                        '$options': 'i'
                    }
                }, {
                    'PostTypeId': '1'
                }]
            }

            queryResults = collection.find(searchQuery)
            for result in queryResults:
                posts[result['Id']] = result

        return posts

    def getMatchingBody(searchKeys, posts):
        """
		Fetches any posts whose body matches one of the searchTerms

		Parameters:
			searchKeys:
				A List of String objects representing search terms entered by
				the user
			posts: A Dictionary object of dictionaries representing posts that match the search
			terms

		Returns:
			A Dictionary object of dictionaries representing posts that match the search
			terms
		"""
        collection = SearchForQuestions.db["Posts"]

        for keyWord in searchKeys:
            searchQuery = {
                '$and': [{
                    'Body': {
                        '$regex': keyWord,
                        '$options': 'i'
                    }
                }, {
                    'PostTypeId': '1'
                }]
            }

            queryResults = collection.find(searchQuery)
            for result in queryResults:
                posts[result['Id']] = result

        return posts

    def getMatchingTag(searchKeys, posts):
        """
		Fetches any posts whose tags match one of the searchTerms

		Parameters:
			searchKeys:
				A List of String objects representing search terms entered by
				the user
			posts: A Dictionary object of dictionaries representing posts that match the search
			terms

		Returns:
			A Dictionary object of dictionaries representing posts that match the search
			terms
		"""
        searchKeys = SearchForQuestions.processSearchKeysForTags(searchKeys)
        collection = SearchForQuestions.db["Posts"]

        for keyWord in searchKeys:
            searchQuery = {
                '$and': [{
                    'Tags': {
                        '$regex': keyWord,
                        '$options': 'i'
                    }
                }, {
                    'PostTypeId': '1'
                }]
            }

            queryResults = collection.find(searchQuery)
            for result in queryResults:
                posts[result['Id']] = result

        return posts

    def processSearchKeysForTags(searchKeys):
        for i, searchKey in enumerate(searchKeys):
            searchKeys[i] = searchKey.replace(' ', '-')
        return searchKeys
class CollectionGenerator:
    """
	Collection Generator is a module which creates mongo db collections

	Collection Generator creates three mongo db collections from files located in 
	the main directory.
	"""

    client = pymongo.MongoClient('localhost', int(Terminal.getPort()))
    db = client['291db']

    def generateCollections():
        """
		Generates the three collections by calling various methods
		"""
        CollectionGenerator.generateTagCollection()
        CollectionGenerator.generatePostCollection()
        CollectionGenerator.generateVoteCollection()

    def generateTagCollection():
        """
		Generates the Tags collection by reading Tags.json to get a Dictionary
		object and calls a method which turns the dictionary into a mongo db collection
		"""
        tagDict = FileManager.readJsonFile("Tags.json")
        CollectionGenerator.dictToCollection(tagDict, "Tags")

    def generatePostCollection():
        """
		Generates the Posts collection by reading Posts.json to get a Dictionary
		object and calls a method which turns the dictionary into a mongo db collection
		"""
        postDict = FileManager.readJsonFile("Posts.json")
        CollectionGenerator.dictToCollection(postDict, "Posts")

    def generateVoteCollection():
        """
		Generates the Votes collection by reading Votes.json to get a Dictionary
		object and calls a method which turns the dictionary into a mongo db collection
		"""
        voteDict = FileManager.readJsonFile("Votes.json")
        CollectionGenerator.dictToCollection(voteDict, "Votes")

    def dictToCollection(dictionary, name):
        """
		Creates a collection from name, empties it then appends all
		of the dictionaries entries (which are dictionaries themselves)
		to a list before inserting all of them into the created collection

		Parameters:
			dictionary:
				A Dictionary object retrieved from one of the three json files
			name:
				A String object representing the name of the collection 
		"""
        collection = CollectionGenerator.db[name]
        collection.delete_many({})
        batchInsert = []
        for row in dictionary[name.lower()]["row"]:
            batchInsert.append(row)

        collection.insert_many(batchInsert)
class Vote:
	"""
	Vote is an Interface which allows the user to interact with posts
	
	Vote allows the user to upvote posts and handles database updating
	to represent that
	"""
	client = pymongo.MongoClient('localhost', int(Terminal.getPort()))
	db = client[Terminal.getDBName()]
	def makeVote(post, userID=None):
		"""
		Provides the main functionality of Vote
		Creates a dictionary object representing a vote before inserting it
		into the vote collection. It then updates the post collections by increasing
		the number of votes on the given post

		Parameters:
			post:
				A Dictionary object representing the selected post from the database
			userID:
				A String object whose default value is none which represents the current
				users ID
		Returns:
			A Boolean object representing whether the vote was successfully added to the database
		"""
		postCollection = Vote.db['Posts']
		votesCollection = Vote.db['Votes']

		
		postID = post['Id']
		voteTypeID = '2'
		creationDate = str(datetime.datetime.utcnow().isoformat())
		
		if userID:
			if (not Vote.userVoted(votesCollection, post, userID)):
				voteID = Vote.getUniqueID(votesCollection)
				voteDict = {'Id' : voteID, 'PostId' : postID, 'VoteTypeId' : voteTypeID, 'UserId' : userID, 'CreationDate' : creationDate}
			else:
				print("You have already voted on this post!")
				input("Press Enter to Continue: ")
				return False
		else:
			voteID = Vote.getUniqueID(votesCollection)
			voteDict = {'Id' : voteID, 'PostId' : postID, 'VoteTypeId' : voteTypeID, 'CreationDate' : creationDate}
		
		votesCollection.insert_one(voteDict)
		Vote.updatePostVotes(post, postCollection)
		print("Vote Successfully added!")
		input("Press Enter to Continue: ")
		return True


	def getUniqueID(collection):
		"""
		Gets a unique ID for the vote being created by querying the database for all votes
		iterating to the last Dictionary object (representing a vote) grabbing it's id and incrementing
		by one

		Parameters:
			collection:
				A pymongo Collection Reference representing the current collection with which
				we are finding the unique ID for

		Returns:
			A String object representing a unique ID
		"""
		"""
		maxId = 0
		results = collection.find();
		for result in results:
			if int(result['Id']) > maxId:
				maxId = int(result['Id'])
		return str(maxId + 1)
		"""
		def findMaxAndMin(collection):
			maxNum = 1
			minNum = 1
			while  collection.find_one({'Id': str(maxNum)}) is not None:
				minNum = maxNum
				maxNum *= 2
			
			return [minNum, maxNum]
			
		votes = collection
		nums = findMaxAndMin(votes)
		minNum = nums[0]
		maxNum = nums[1]
		
		"""TESTING
		print(minNum, maxNum)
		print(type(minNum), type(maxNum))
		print("+++++++++++\n")
		"""

		while True:
			num = (minNum + maxNum) // 2
			
			search = votes.find_one({'Id': str(num)})
			
			try:
				if int(search["Id"]) >= minNum:
					minNum = num
				else:
					maxNum = num
			except:
				maxNum = num
				
			"""TESTING
			print("Min:", minNum)
			print("Max:", maxNum)
			print("Middle:", num)
			"""
				
			if minNum == maxNum or minNum+1 == maxNum:
				num = maxNum
				
				break
				
		#print("Final:", num)
		return str(num)


	def userVoted(collection, post, userID):
		"""
		Checks if the current user has voted on this post

		Parameters:
			collection:
				A pymongo Collection Reference representing the current collection with which
				we are finding the unique ID for
			post:
				A Dictionary object representing a post currently being voted on
			userID:
				A String object representing the current user's ID

		Returns:
			A Boolean representing whether the current user has voted
		"""
		query = {'$and' : 
						[{ 'UserId' : userID},
						{ 'PostId' : post['Id']}] 
				}
		return collection.find_one(query) is not None

	def updatePostVotes(post, collection): 		
		updatedScore = post['Score'] + 1
		updateQuery = { '$inc' : { 'Score' : 1 } }
		collection.update_one({'Id' : post['Id']}, updateQuery)
Example #20
0
    def printTitle(self):
        """
		Prints main elements of the UI
		"""
        Terminal.printCenter("--- Welcome User ---")
        Terminal.printCenter("(Type exit to quit at any time)")