python dictionary with function and arguments - python

I want to use a dictionary to call functions with arguments, ie this simple program. I'm a very novice coder in python. what am I doing wrong?
output:
what name? : s
what name? : f
f
s
want to write or read? w/r:
w
want singers or band members? s/b:
s
1

code:
def addToFile(filename, lineString):
file = open(filename,"a")
file.write(lineString + "\n")
file.close()
return 1
def readFile(filename):
file = open(filename)
for line in file:
print(line)
file.close()
return 2
whatToDo = {
"ws": addToFile("band.txt",input("what name? : ")),
"wb": addToFile("singers.txt",input("what name? : ")),
"rs": readFile("singers.txt"),
"rb": readFile("band.txt")
}
def promptWrite():
print("want to write or read? w/r: ")
choice = str(input())
print("want singers or band members? s/b: ")
choice += str(input())
val = whatToDo[choice]
print(val)
promptWrite()
I didn't know If I needed to have a value or something, so I put the returns in the functions and had val. That isn't nessisary, I just drafted this up as an example program.
I know that you can have a dictionary with the names of the functions and call
dictionaryName[whateverthing]() to run the function, but I don't know how to have the arguments vary in that

You're calling the functions when you create the dictionary, not when you access the dictionary. Use lambda to create anonymous functions, then add () when you fetch from the dictionary to call it.
def addToFile(filename, lineString):
file = open(filename,"a")
file.write(lineString + "\n")
file.close()
return 1
def readFile(filename):
file = open(filename)
for line in file:
print(line)
file.close()
return 2
whatToDo = {
"ws": lambda: addToFile("band.txt",input("what name? : ")),
"wb": lambda: addToFile("singers.txt",input("what name? : ")),
"rs": lambda: readFile("singers.txt"),
"rb": lambda: readFile("band.txt")
}
def promptWrite():
print("want to write or read? w/r: ")
choice = input()
print("want singers or band members? s/b: ")
choice += input()
val = whatToDo[choice]()
print(val)
promptWrite()

You can't set functions with parameters to be executed in a dictionary, but you can store functions to call them after, with the corresponding dict key and parenthesis. Example:
my_dict['write_output'] = print
my_dict['write_output']('hello from my key')
IMHO, storing your functions in dict keys is a design incosistency. Dicts are mutable objects, then someone could overwrite your keys without any restriction and mess up your code everywhere. Not a good idea at all.

Related

How to pass one variable/dictionary between two functions in Python

I want to pass a dictionary between two functions, but how to do this without using a global variable?
I'm trying to pass the dictionary that is in my "fileProcessing" function into the "swappingKandV_PrintingResults" function without having a global variable being modified.
dictionary = dict()
fileinputname = input("Please Input File Name: ")
try:
filehandling = open(fileinputname)
except:
print("Invalid Entry")
quit()
rawfile = filehandling.readlines()
def fileProcessing(rawfile):
for iteration in(range(len(rawfile))):
rawfile[iteration] = rawfile[iteration].lower()
for line in rawfile:
line.rstrip()
line.split()
for words in line:
letter = words.split()
for iteration in letter:
if iteration.isalpha() :
dictionary[iteration] = dictionary.get(iteration, 0) + 1
def swappingKandV_PrintingResults(dictionary):
finalresults = []
for (k,v) in dictionary.items():
newtuple = (v, k)
finalresults.append(newtuple)
finalresults = sorted(finalresults, reverse=True)
for iteration in finalresults:
print(iteration)
fileProcessing(rawfile)
swappingKandV_PrintingResults(dictionary)
By making the first function create and return the dictionary. Then pass that returned dictionary to the second function.
fileinputname = input("Please Input File Name: ")
try:
filehandling = open(fileinputname)
except:
print("Invalid Entry")
quit()
rawfile = filehandling.readlines()
def fileProcessing(rawfile):
dictionary = {}
for iteration in(range(len(rawfile))):
rawfile[iteration] = rawfile[iteration].lower()
for line in rawfile:
line.rstrip()
line.split()
for words in line:
letter = words.split()
for iteration in letter:
if iteration.isalpha() :
dictionary[iteration] = dictionary.get(iteration, 0) + 1
return dictionary
def swappingKandV_PrintingResults(dictionary):
finalresults = []
for (k,v) in dictionary.items():
newtuple = (v, k)
finalresults.append(newtuple)
finalresults = sorted(finalresults, reverse=True)
for iteration in finalresults:
print(iteration)
swappingKandV_PrintingResults(fileProcessing(rawfile))
From the way you phrased the question, it seems you have some confusion on how to work with passing arguments to functions and how to handle scope. I would suggest having at look at what a variable is in Python to begin with and then what passing it to a function means.
You can accomplish this task in 2 ways:
1. Nested Function Call :
If you want to necessarily call 2nd function after 1st, just write -
'swappingKandV_PrintingResults(dictionary)' as the ending line in the fileProcessing function.
2. Accepting Return from 1st and Passing as Argument to 2nd :
As insisted by #Reti43 too, just write -
'return dictionary' as the ending line in the fileProcessing function and replace your last 2 lines of code by -
Dict = fileProcessing(rawfile)
swappingKandV_PrintingResults(Dict)

How do I create a dictionary from a file using Python?

Question: How do I open a file and turn it into my dictionary when I run the program?
So I created a test dictionary, saved it as .txt and .dat. Below I have entered the dictionary manually, but instead I want the program to open the file when ran, convert it to the dictionary, then continue into the functions.
(The overall objective of the program is to enter a key (productCode) to retrieve the product number, all of which works), but I want it to do it with the file, and not the manually entered data.
As always, guidance is appreciated!
file = open("test.dat", "r")
FILENAME = "test.dat"
# ------ Global Variables -------
d = {'ABCD': '0123', 'HJKL': '0987'}
user_cont = True
# ------- Functions -------
print("Product number finder.")
def get_productNum2():
global d
user_cont = True
while user_cont:
productCode = input("Enter an existing product code: ")
if productCode in d:
productNum = d[productCode]
print("Product #: " + productNum)
else:
print("Error finding product number; product code does not exist.")
user_cont = user_continue()
def user_continue():
global user_cont
prompt_user = input("Do you wish to continue? Enter y/n: ")
if prompt_user == "y":
user_cont = True
elif prompt_user == "n":
user_cont = False
return user_cont
# ------- Start Execution -------
get_productNum2()
You can (and should) write a dictionary to file in JSON format. Not only is it saved in a human-readable way, the JSON format also means the dictionary can even be loaded into many other programming languages and programs if needed!
Here is an example using the standard library package json:
import json
dict = {'ABCD': '0123', 'HJKL': '0987'}
dict_json = json.dumps(dict) #this line turns the dictionary into a JSON string
with open("my_dictionary.json", "w") as outfile:
outfile.write(dict_json)
Given a dictionary in JSON format, we can load it like this:
with open("my_dictionary.json", "r") as infile:
dict = json.load(infile)
Now you can access dict which you loaded from file as if it were the original dictionary:
>>> print(dict["ABCD"])
0123

New function doesn't accept returned values from other function

I'm reading from a CSV file and created a function that separates the players from that file into 2 lists: experienced and fresh players.
Then, I tried to create another function that would print the length of each list. However, when I run my script and I call for the 2 functions, Python returns an error saying that the variables of the second function are not defined. Not sure what I'm doing wrong.
import csv
with open('soccer_players.csv', newline='') as csvfile:
players_reader = csv.DictReader(csvfile, delimiter=',')
players = list(players_reader)
def separate(players):
experienced = []
fresh = []
for player in players:
if player['Soccer Experience'] == 'YES':
experienced.append(player)
else:
fresh.append(player)
return experienced, fresh
def countexperience (experienced, fresh):
players_experience = len(experienced)
players_fresh = len(fresh)
print(players_experience)
print(players_fresh)
while True:
start = input("Want to start? (Y/n) ").lower()
if start == "y":
separate(players)
countexperience(experienced, fresh)
break
elif start == "n":
print("goodbye")
break
else:
print("letter not accepted! Please write 'Y' to start or 'N' to exit!\n")
Result:
countexperience(experienced, fresh)
NameError: name 'experienced' is not defined
The local variables in separate() are not added to the current scope, so you need to assign the return of separate() to variables in the current scope, e.g.:
experienced, fresh = separate(players)
Note: you can use any names you want, e.g.
e, f = separate(players)
countexperience(e, f)
You can also expand the tuple return from separate() directly in the function call to countexperience() using *, e.g.:
countexperience(*separate(players))

How do I return information to another file?

So, I'm trying to make something simple:
shopping_list = []
print("Enter 'done' to stop adding items.")
while True:
new_item = input("> ")
if new_item.lower() == "done":
break
shopping_list.append(new_item)
print("Here's your list:")
for item in shopping_list:
print(item)
Can I, instead of printing this, return the list to another file in order to display that file? I'm new to this and am not sure if that's possible (though everything is possible with code, right?). My goal is to get the list to display, and to be saved so I can access it anytime.
For starters, you'll need to put your code inside a function. Or else, you won't be able to "return" anything.
def foo():
....
return shopping_list
So, your code would be something like:
def foo():
while True:
new_item = input("> ")
if new_item.lower() == "done":
break
shopping_list.append(new_item)
return shopping_list
And, you'd call your function like this:
my_shopping_list = foo()
Once the function returns, my_shopping_list is a list of shopping items, you are free to do as you please.
Also notice I removed the print statements from your loop. Please feel free to add them in if you need them, but I assume that's what you didn't want.
Now, when you say file, I assumed you just meant to somewhere else inside the same program. But if you do indeed want to call this function from another python script, here's what you'll do:
A.py:
def foo():
... # entire function definition here
B.py
import A
my_shopping_list = A.foo()
Create two python scripts. The first one houses your foo function. The second one calls it.
Alternatively, if you want to print your shopping list to an actual file (taking your words literally here), you'd do:
foo():
...
with open('cart.txt', 'w') as f:
for i in shopping_list:
f.write(i + '\n')
This writes your items to a file.
If you mean that you want to run the list to a text file outside of your python script you can do the following:
outfile = open(file, "w")
CODE
outfile.write(shoppping_list)
outfile.close()
You can try this way :
def func():
shopping_list = []
print("Enter 'done' to stop adding items.")
while True:
new_item = input("> ")
if new_item.lower() == "done":
break
shopping_list.append(new_item)
return shopping_list
if __name__ == '__main__':
print("Here's your list:")
outfile = open('test.txt', "w")
shopping_list = func()
# outfile.write(shopping_list)
for item in shopping_list:
# print(item)
outfile.write(item + "\n")
outfile.close()

Difficulties with an unruly program

I have been working on this code for a couple of hours now, and I am rather unsure what the problem is.
import random#imports random
import os#Imports os
print("Welcome to the maths quiz") # Welcomes user to quiz
score = (0)
def details():
plr_name = input ("Please Input Name:") # Asks user for name
plr_class = input("Input class number: ") # Asks the user for class numer
return (plr_name, plr_class)
def Q():
while qno < 10: # loops while qno is under 10
ran_num1 = random.randint(1,99) # Generates the first random number
ran_num2 = random.randint(1,99) # Generates the second random number
ran_fun = random.choice("X-+") # Picks a random function
print(ran_num1,ran_fun,ran_num2,"=") # Prints the Sum for the user
if ran_fun == "X":
sum_ans = ran_num1 * ran_num2 # Does the sum if it is a multiplication
if ran_fun == "+":
sum_ans = ran_num1 + ran_num2 # Does the sum if it is a addition
if ran_fun == "-":
sum_ans = ran_num1 - ran_num2 # Does the sum if it is a subtraction
plr_ans = int(input()) # Gets the user's answer
if plr_ans == sum_ans:
print("Correct!") # Prints correct
score = score + 1 # Adds 1 to score
else:
print("Incorrect!")
qno = qno + 1 # Adds 1 to qno
def plr_list_make(lines, listoreder):
index = 0
plr_names =[]
plr_scores =[]
for line in lines:
if listorder == 1:
column =0
rev = False
else:
column = 1
rev = True
return sorted(zip(plr_names, plr_scores),key = lambda x:(x[column]),reverse = rev)
def fileUP(plr_name, score, line ):
found = False
index = 0
for line in lines:
if line.startswith(plr_name):
line = line.strip("\n") + ","+str(score+"\n")
lines[index] = line
found = True
index = index + 1
if not found:
lines.append(plr_name+"|" +str(score)+"\n")
return lines
def save (plr_name, plr_class, score):
filename = "QuizScore_"+plr_class+".txt"
try:
fileI = open(filename)
except IOError:
fileI = open(filename, "w+")
fileI = open(filename)
lines = fileI.readlines()
fileI.close
lines = FileUP(plr_name, score, lines)
fileO = open(filename, "w")
fileO.writelines(lines)
fileO.close
def disp_list(): ## intialise_list
student_list=[]
filename = "QuizScore_"+plr_class+".txt"
try:
## open file read into list "lines"
input_file = open(filename)
lines = input_file.readlines() ## read file into list "lines"
input_file.close
student_list = create_student_list(lines, listorder) ### update "lines" with student list as requested by user
## output sorted list
for counter in range(len(student_list)):
print ("Name and Score: ", student_list[counter][0], student_list[counter][1])
except IOError:
print ("no class file!!!")
def menu():
print ("1 Test")
print ("2 Alphabetical")
print ("3 Highscore")
print ("4 Avg Score")
def Run():
selection = 0
while selection != 5:
menu()
option = int(input("Please select option: "))
if option == 1:
name, plr_class = details()
save(name, plr_class, Q())
else:
plr_class = input("input class ")
disp_list(plr_class, option-1)
Run()
Errors:
Traceback (most recent call last):
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 117, in
Run()
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 113, in Run
save(name, plr_class, Q())
File "C:\Users\user\Documents\CharlieStockham\cgsca\ca2.py", line 74, in save
lines = FileUP(plr_name, score, lines)
NameError: global name 'FileUP' is not defined
Line 110:
name, plr_class = details()
But the details function does not return anything - so Python tries to assign the default return value None to the tuple name, plr_class. It can't do this, because None is not an iterable (you can't assign two things to it). To fix it, add the following line to your details function:
return (plr_name, plr_class)
(I haven't tested this.)
I like your game but it's buggy as a mofo :P
score and qno aren't properly defined. Define them in the functions that need them, define them globally or pass them to the relevant functions as arguments.
details() doesn't return anything but you still attempt to use its output to define two other variables. Add return (plr_name, plr_class) to details()
Every time you cast user input to int without checking its value, your program will crash if an int can't be cast. This applies here:
option = int(input("Please select option: "))
here
plr_ans = int(input())#Gets the user's answer
and elsewhere.
Since your program is input-heavy you could make a a function to which you pass the expected datatype and an optional string to display to the user. This way you wouldn't have to write try/except 10 times and your program wouldn't crash on unexpected input.
In def fileUP(plr_name, score, line ): you have for line in lines: but lines isn't defined. Thus, the save() function that calls FileUP() also fails. Also, FileUP and fileUP are not the same thing. You call the function with a capital "f" but the defintion of the function calls it fileUP with a lower case "f".
While we're at it, the file handling in def save (plr_name, plr_class, score):looks weird. The standard way of opening files for simple reading and writing in Python is via with open().
disp_list() should take one or two arguments but it doesn't at the moment so this error is raised:
TypeError: disp_list() takes 0 positional arguments but 2 were given
These 2 positional arguments were given here:
disp_list(plr_class, option-1)

Categories