Calling a variable from one function, into another
So I have this code down below, and it works perfectly fine as it is currently, but I want it to work differently. This is just some practice code, so it's not a serious program: The purpose of the code is to allow someone to enter the names of a student, which will become a key in the dictionary "all_students", followed by their grade, which will become the value. Also in there is the option to remove students by "pop()"-ing the key, and the option to continue adding/removing students...
What I'm trying to do, which is what I hope somebody here will be able to help me out with, is set up a variable(all_students) within one of the functions (add_roster()), that I will be able to call from other functions. I understand dictionaries are immutable, but that's not really the issue: I'm struggling to get *any* variable within a function to successfully call from another function.
I understand I need to use parameters and arguments, so I guess what I'm really asking here, is for someone to help demonstrate how I'm supposed to use them. Because whenever I use parameters and arguments, no matter how many examples I follow or explanations I find online, it doesn't work.
This is Python 3.8. Thank you in advance.
The code:
all_students = {} def add_roster(): while True: add_student = input('Please add a student name. Enter \'Q\' to exit: ') add_student = add_student.title() if add_student == 'Q': break add_grade = input('Please input student grade. Enter \'Q\' to exit: ') add_grade = add_grade.title() if add_grade == 'Q': break all_students[add_student] = add_grade return all_students def get_roster(): print('The following students are in your class: ') print(all_students) def remove_roster(): while True: print(all_students) remove_student = input('Which student would you like to remove? Enter \'Q\' to exit: ') if remove_student.title() == 'Q': break if remove_student in all_students: all_students.pop(remove_student) else: print ('That student was not found!') def main(): while True: add_roster() get_roster() question = input ('Would you like to remove a student from the roster? Y/N: ') if question.title() == 'Y': remove_roster() continuing = input('Would you like to continue? Y/N: ') if continuing.title() == 'N': break if __name__ == '__main__': main()
I know I'm supposed to use the "return" command if I want the function to pass a variable to another function, it's just a matter of figuring out how I'm supposed to call it from that other function. If I use "def get_roster(students = all_students)" with "print (students)" or "print(all_students), for example, it doesn't work.
Edit: Thank you out for your input, everybody. I certainly learned a lot, especially about coding etiquette, but nobody actually answered my question in a way that was easy to understand, or was actually a bit off the mark, so I actually still had to figure out what the problem was on my own. The problem I was having was actually with the 'While" loop: the loop is, in-and-of itself, a closed scope, much like the function itself is. So in this case, my "return" function was outside of the "while" loop, so it returned an empty value after the loop was closed. The fix was to indent the "return" function to the same level as the rest of the "while" loop.
In other words: The function created one scope, and the "while" loop created a sort of "sub-scope". Once the value left the "sub-scope", it no longer existed anywhere, and therefore passed an empty value on to the next function.
submitted by
AChSynaptic to
learnpython
CS50AI Project 6 Questions: Code works but when I type query in it, there is no output
import nltk import sys import os import math nltk.download('stopwords')
FILE_MATCHES = 1 # only 1 file match for any given query SENTENCE_MATCHES = 1 # 1 sentence to be match for any given query def main():
# Check command-line arguments if len(sys.argv) != 2: sys.exit("Usage: python questions.py corpus")
# Calculate IDF values across files files = load_files(sys.argv[1]) file_words = { filename: tokenize(files[filename]) for filename in files } file_idfs = compute_idfs(file_words)
# Prompt user for query query = set(tokenize(input("Query: ")))
# Determine top file matches according to TF-IDF filenames = top_files(query, file_words, file_idfs, n=FILE_MATCHES)
# Extract sentences from top files sentences = dict() for filename in filenames: for passage in files[filename].split("\n"): for sentence in nltk.sent_tokenize(passage): tokens = tokenize(sentence) if tokens: sentences[sentence] = tokens
# Compute IDF values across sentences idfs = compute_idfs(sentences)
# Determine top sentence matches matches = top_sentences(query, sentences, idfs, n=SENTENCE_MATCHES) for match in matches: print(match)
def load_files(directory): """ Given a directory name, return a dictionary mapping the filename of each `.txt` file inside that directory to the file's contents as a string. """ wiki_sites = dict() folders = os.listdir(directory) for folder in folders: # join corpus to .txt file file_path = os.path.join(directory, folder) # ensure file path is valid if os.path.isdir(file_path): # read contents in txt file in dict key with open(file_path, 'r') as f: content = f.read() wiki_sites[folder] = content
return wiki_sites
def tokenize(document): """ Given a document (represented as a string), return a list of all of the words in that document, in order. Process document by coverting all words to lowercase, and removing any punctuation or English stopwords. """ # set all words to lowercase new_docs = document.lower() stop_words = set(nltk.corpus.stopwords.words("english")) words = nltk.word_tokenize(new_docs)
for word in words: # removing any punctuations if word.isalpha() is False: words.remove(word) # removing any stopwords if word in stop_words: words.remove(word)
# sorting words sorted_words = sorted(words, reverse=True)
return sorted_words
def compute_idfs(documents): """ Given a dictionary of `documents` that maps names of documents to a list of words, return a dictionary that maps words to their IDF values. Any word that appears in at least one of the documents should be in the resulting dictionary. """ idfdict = dict() # calculate number of documents num_of_docs = len(documents)
# merge all the words together into one words = set() for i in documents.values(): for j in range(len(i)): words.add(i[j]) # for now words does not contain any duplicates, so need to count no. of repeated words for word in words: docs_with_same_word = 0 for document in documents: if word in document: docs_with_same_word += 1 idf = math.log(num_of_docs / docs_with_same_word) idfdict[word] = idf
return idfdict
def top_files(query, files, idfs, n): """ Given a `query` (a set of words), `files` (a dictionary mapping names of files to a list of their words), and `idfs` (a dictionary mapping words to their IDF values), return a list of the filenames of the the `n` top files that match the query, ranked according to tf-idf. """ word_bank = dict()
# calculating Term Frequency for file, words in files.items(): tfidf = 0 for word in query: tfidf += words.count(word) * idfs[word] word_bank[file] = tfidf
# sort file rank according to tf-idf value filerank = sorted(word_bank.items(), key=lambda x: x[1], reverse=True) filerank = [x[0] for x in filerank]
return filerank[:n]
def top_sentences(query, sentences, idfs, n): """ Given a `query` (a set of words), `sentences` (a dictionary mapping sentences to a list of their words), and `idfs` (a dictionary mapping words to their IDF values), return a list of the `n` top sentences that match the query, ranked according to idf. If there are ties, preference should be given to sentences that have a higher query term density. """ sentence_score = dict()
# calculate sum of idf for sentence, words in sentences.items(): # determine words in sentences.items that matches query matching_words = query.intersection(words)
# calculate sum idf values idf = 0 for word in matching_words: idf += idfs[word]
# calculate query term density matching_words = sum(map(lambda x: x in matching_words, words)) query_term_density = (matching_words / len(words))
# update sentence scores with idf and query term density values sentence_score[sentence] = {'idf': idf, 'qtd': query_term_density}
# rank sentences by idf then query term density ranked_sentences = sorted(sentence_score.items(), key=lambda x: (x[1]['idf'], x[1]['qtd']), reverse=True) ranked_sentences = [x[0] for x in ranked_sentences]
return ranked_sentences[:n]
if __name__ == "__main__": main()
submitted by
teemo_mush to
cs50