This question already has answers here:
How do I get a result (output) from a function? How can I use the result later?
(4 answers)
Closed 6 months ago.
Trying to simplify lots of repetitive reading and writing in a script of mine, and I can not figure out how to get data out of def readfile.
def writefile(FILE, DATA):
file = open(FILE, "w")
X = str(DATA)
file.write(X)
file.close()
def readfile(FILE):
file = open(FILE, "r")
readvar = file.read()
file.close()
readfile("BAL.txt")
print(readvar)
I would expect the value stored in BAL.txt to come back, but it always says that readvar is not defined. I just defined it in a function that I ran.
Error:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-6-f80fb5b2da05> in <module>
14
15 readfile("test.txt")
---> 16 print(readvar)
NameError: name 'readvar' is not defined
In Python, variables from inside a function are generally not accessible from the outside (Look up variable scoping).
You can put a return statement at the end of a function to return variables (readvar in this case) (and you almost always should).
Then you can assign the returned argument (readvar) to a new variable (e.g. rv).
You can also give it the same name.
Other Resources:
Python Scopes and Namespaces
Real Python: Defining Your Own Python Function
def writefile(FILE, DATA):
file = open(FILE, "w")
X = str(DATA)
file.write(X)
file.close()
def readfile(FILE):
file = open(FILE, "r")
readvar = file.read()
file.close()
return readvar
rv = readfile("BAL.txt")
print(rv)
You're unable to see the value of readvar because it's only locally defined within the scope of the readfile function, not globally, as you're attempting to use it when calling print(readvar).
If you need a value to persist outside the scope of the function, you must return it to where the function is called, like so:
def readfile(FILE):
file = open(FILE, "r")
file_data = file.read()
file.close()
return file_data
file_data = readfile("my_file.txt")
print(file_data)
I'd also suggest using a with block when performing file operations. It's best practice as to ensure the file handle is correctly closed, even if exceptions occur. This improves the handling of any errors the operation may encounter. For example:
def writefile(FILE, DATA):
data = str(DATA)
with open(FILE, 'w') as write_stream:
write_stream.write(data)
def readfile(FILE):
with open(FILE, 'r') as read_stream:
file_data = read_stream.read()
return file_data
file_data = readfile("my_file.txt")
print(file_data)
If you wanted to access the file line-by-line, we simply include a for loop within the scope of with. For example, printing each line of the file:
def readfile(FILE):
with open(FILE, 'r') as read_stream:
for line in read_stream
print(line)
simple. try this one
def personal_data():
name1 = input("What is you 1st Name?").upper()
name2 = input("What is your last Name?").upper()
return name1 + name2
fname = personal_data()
print(fname)
Related
Here is the code and I am trying to see what I have done wrong. I am new to python functions and linking external files so it would be nice if you could explain your code.
def get_data(filename):
records = []
with open(filename) as readfile:
lines = readfile.readlines()
for line in lines:
# variable line contains:
str_rec = line.split(",")
pname = str_rec[0]
price = int(str_rec[1])
quantity = int(str_rec[2])
records.append([pname, price, quantity])
#caution: indentation
return records
hell= get_data(data.txt)
print(hell)
data.txt is a link to another file that I am trying to pass as an argument.
open(filename) takes the filename as a string, so you should pass the name as a string, not the actual file.
hell= get_data("data.txt")
Im having a bit of trouble outputing 2 functions I created on my program.
I have the following dictionary:
def game():
return {
'players': [],
'active_players':[],
'running_game': False,
I gather the data from here:
def player_register(mm,name):
board1_for_ship_placement = create_grid(columns_size,rows_size)
board2_for_showing = create_grid(columns_size,rows_size)
player = {
'name':name,
'played_games': 0,
'victory': 0,
'ships_available' : {
"speeder":0,
"sub":0,
"frag":0,
"cruz":0,
"spaceship":0
},
'ships_in_use':[],
'board1': board1_for_ship_placement,
'board2': board2_for_showing
}
mm['players'].append(player)
Then I created 2 function to save and load:
def save():
my_dict = game()
with open("my_data.pkl", "wb") as f:
pickle.dump(my_dict, f)
def load():
with open("my_data.pkl", "rb") as f:
my_data = pickle.load(f)
This is my menu function:
def main():
mm = fun.game()
letters_dict = fun.dict_letters()
ships_size = fun.check_ships_size()
while True:
line = input("Insert Comand: ")
if not line: # checks if input is empty line , if so
break # it breaks out of while loop
commands = line.split(" ")
elif commands[0] == "G":
commandG(commands,fun)
elif commands[0] == "L":
commandL(commands,fun)
elif commands[0] == "teste":
print(mm['jogadores_em_ativo'])
elif commands[0] == "break":
break
I built this 2 functions (one for loading and one for saving):
def commandG(commands,fun):
dados = pickle.dump(game())
print("Game Saved")
def commandL(commands,fun):
dados = pickle.loads(game())
print("Game Loaded")
But it's not working...Am I missing up something? How can I make the program save and load data by pressing G or L?
Part of your problem is I think a misunderstanding of what pickle does and is intended for.
It can be used to preserve a save state, just not the way you're doing it.
Lets start with the error you're getting. There is no game function defined in the file your python file that you are calling it from. So you cant use game(). You would need to call it with fun.game().
Secondly, your game function is returning a dict with some empty list values and some False values so this is not the state you want to preserve anyway.
Finally, what pickle is intended for is serializing python objects such as dicts into bytes. The reason you'd want to do that is because you can then transfer those bytes over a socket or save them to a text file.
To load that saved dict or object you would then need to read the text file or receive the byte string through a socket and unpickle and voila, you have an object.
To test it and help you see how it works, hop into the python console and run these commands.
import pickle
test = {'test':69}
print(test)
pickled = pickle.dumps(test)
print(pickled)
Notice how your object is now just text?
with open('file.txt', 'wb') as file:
file.write(pickled)
Now open the test.txt file and see how it saved it?
with open('file.txt', 'rb') as file:
file_data = file.read()
Now we've retrieved our pickled dict so we need to unpickle it.
unpickled = pickle.loads(file_data)
print(unpickled)
Hopefully this is clear.
If you really want this to save your dict. Which, to be fair I only skimmed your code, but it looks like your data is in a dict named mm.
Try this with your save and load functions.
def commandG(mm):
with open("my_data.pkl", "wb") as f:
pickle.dump(mm, f)
def commandL():
with open("my_data.pkl", "rb") as f:
mm = pickle.load(f)
return mm
And call them like this.
commandG(mm)
mm = commandL()
You'll also need to import pickle in this python file
So this might be a simple solution but I can't seem to come up with it. When I use the following code I can open the file, read through it and do all the necessary functions, but if I use the commented line instead of the one underneath it gives me an error at line r = L[15] like it can't read it properly anymore. What can I do about this? If more code is needed I can provide it. Thanks!
def open_file():
while True:
file = input("Enter a file name: ")
try:
open(file)
return file
except FileNotFoundError:
print("Error. Please try again.")
print()
def read_file():
#fp = open_file()
fp = open("Texas_death_row.csv")
csv_fp = csv.reader(fp)
data = []
for L in csv_fp:
r = L[15]
g = L[16]
v = L[27]
T = (r,g,v)
my_list.append(T)
return data
Your open_file function is returning the variable file, that contains the string containing the filename, not the file object (file descriptor) which is what you can read and whatnot.
You should try something like this:
def open_file():
while True:
file = input("Enter a file name: ")
try:
f = open(file)
return f # Return the "file object", not the file name
except FileNotFoundError:
print("Error. Please try again.")
print()
PS: When you're dealing with files, don't forget to close them when you're done with them.
So I've seen this code;
with open(fname) as f:
content = f.readlines()
in another question. I just need some confirmation on how it works.
If I were to have a file named normaltrack.py which contains code;
wall 0 50 250 10
wall 0 -60 250 10
finish 200 -50 50 100
I should have a list called wall = [] and have the opening code as;
with open(normaltrack.py) as f:
wall = f.readlines()
to open the file and store the lines of code that start with "wall" into the list?
Do I always have the change the "fname" everytime I want to open a different file? Or is there a way to do it from the interpreter? Such as python3 assignment.py < normaltrack.py ?
In your example:
with open(fname) as f:
content = f.readlines()
'fname' is a variable reference to a string. This string is the file path (either relative or absolute).
To read your example file, and generate a list of all lines that with 'wall', you can do this:
fname = '/path/to/normaltrack-example.txt' # this would be an absolute file path in Linux/Unix/Mac
wall = []
with open(fname) as the_file:
for line in the_file:
if line.startswith('wall'):
wall.append(line) # or wall.append(line.rstrip()) to remove the line return character
In general, it's best to not call 'readlines()' on a file object unless you control the file (that is, it's not something the user provides). This is because readlines will read the entire file into memory, which sucks when the file is multiple GBs.
Here's a quick and dirty script that does what you want.
import sys
if len(sys.argv) > 1:
infile = sys.argv[1]
else:
print("Usage: {} <infile>".format(sys.argv[0]))
sys.exit(1)
with open(infile, 'r') as f:
walls = []
for line in f:
if line.startswith('wall'):
walls.append(line.strip())
If you name this script 'read_walls.py', you can run it from the command line like this,
python read_walls.py normaltrack.py
Ordinarily, I'd use argparse to parse command-line arguments, and write a main() function for the code. (That makes it testable in the interactive python interpreter.)
this code should work for you
#!/usr/bin/env python
import sys
def read_file(fname):
call = []
with file(fname) as f:
call = f.readlines()
call = filter(lambda l: l.startswith('wall'), call)
return call
if __name__ == '__main__':
fname = sys.argv[1]
call = read_file(fname)
print call
Ok here we go, i've been looking at this all day and i'm going crazy, i thought i'd done the hard bit but now i'm stuck. I'm making a highscores list for a game and i've already created a binary file that store the scores and names in order. Now i have to do the same thing but store the scores and names in a text file.
This is the binary file part but i have no idea where to start with using a text file.
def newbinfile():
if not os.path.exists('tops.dat'):
hs_data = []
make_file = open('tops.dat', 'wb')
pickle.dump(hs_data, make_file)
make_file.close
else:
None
def highscore(score, name):
entry = (score, name)
hs_data = open('tops.dat', 'rb')
highsc = pickle.load(hs_data)
hs_data.close()
hs_data = open('tops.dat', 'wb+')
highsc.append(entry)
highsc.sort(reverse=True)
highsc = highsc[:5]
pickle.dump(highsc, hs_data)
hs_data.close()
return highsc
Any help on where to start with this would be appreciated. Thanks
I think you should use the with keywords.
You'll find examples corresponding to what you want to do here.
with open('output.txt', 'w') as f:
for l in ['Hi','there','!']:
f.write(l + '\n')
Start here:
>>> mydata = ['Hello World!', 'Hello World 2!']
>>> myfile = open('testit.txt', 'w')
>>> for line in mydata:
... myfile.write(line + '\n')
...
>>> myfile.close() # Do not forget to close
EDIT :
Once you are familiar with this, use the with keyword, which guaranties the closure when the file handler gets out of scope:
>>> with open('testit.txt', 'w') as myfile:
... for line in mydata:
... myfile.write(line + '\n')
...
Python has built-in methods for writing to files that you can use to write to a text file.
writer = open("filename.txt", 'w+')
# w+ is the flag for overwriting if the file already exists
# a+ is the flag for appending if it already exists
t = (val1, val2) #a tuple of values you want to save
for elem in t:
writer.write(str(elem) + ', ')
writer.write('\n') #the write function doesn't automatically put a new line at the end
writer.close()