Save/load function in Python - python

I have to create a save function and a load function that saves a dictionary in the format of:
123;Kalle;
123;Maria;
321;Anna;
321;Olle;
My dictionary is supposed to look like a phonebook, with the key being the name and the value is the phonenumber:
telebook = {"jacob":"8472923777", "nisse":"092563243"}
How can I write a function that saves my phonebook in the format mentioned? It should look like this:
8472923777;jacob;
This is my current code:
def save(lista, telebook):
import pickle
filename = lista[1]
f = open(filename, "w")
pickle.dump(telebook, f)
f.close()
print telebook
def load(lista, telebook):
import pickle
try:
filename = lista[1]
f = open(filename, "r")
telebook_1 = pickle.load( f )
telebook.clear()
telebook.update(telebook_1)
f.close()
print telebook
except:
print "This file doesn't exist"
EDIT:
My save function was easier than I thought, managed to solve it on my own. Not sure how to get the load function to work though.
book = raw_input("telebook> ").lower()
lista = book.split()
def save(lista, telebook):
filename = lista[1]
f = open(filename, "w")
for name, num in telebook.items():
f.write(num+";"+name+";"+"\n")
f.close()
print telebook
My load is the same as before but obviously I can't use that one anymore.

def save(telebok, filepath):
with open(filepath, 'w') as outfile:
for name,num in telebok.items():
outfile.write("{};{};\n".format(num, name))
And to get it back:
import csv
def load(filepath):
with open(filepath) as infile:
telebok = dict((v,k) for v,k,_ in csv.reader(infile, delimiter=';'))
return telebok

Related

How to unittest a method that print to file?

I have a method to print some values to a file.
from typing import TextIO
def print_to_file(file: TextIO, value: str) -> None:
print(value, file=file)
Here is my current unittest but it will got PermissionError when running unittest on online server. What is the correct way to test it?
def test_print_to_file(self):
file_name = 'temp_file.txt'
value = '123'
expected_content = '123\n'
with open(file_name, 'w') as file:
print_to_file(file, value)
with open(file_name, 'r') as file:
self.assertEqual(file.read(), expected_content)
Try adding + in w & r & try
def test_print_to_file(self):
file_name = 'temp_file.txt'
value = '123'
expected_content = '123\n'
with open(file_name, 'w+') as file:
print_to_file(file, value)
with open(file_name, 'r+') as file:
self.assertEqual(file.read(), expected_content)
I got it fixed via using tempfile.
import tempfile
def test_print_to_file(self):
value = '123'
expected_content = '123\n'
with tempfile.TemporaryFile('w+t') as file:
print_to_file(file, value)
file.seek(0)
self.assertEqual(file.read(), expected_content )

How to read pickled files using command line in Python?

I have 2 pickled files on the computer and I want to load it to my script. Would this code I wrote work in python?
import sys
import pickle
filename1 = sys.argv(1)
filename2 = sys.argv(2)
def read_file(filename1,filename2):
with open(filename1, 'rb') as file1:
file1=pickle.load()
with open(filename1, 'rb') as file2:
file2=pickle.load()
return file1
return file2
sys.exit()
As mentioned here:
1 # Load the dictionary back from the pickle file.
2 import pickle
3
4 favorite_color = pickle.load( open( "save.p", "rb" ) )
5 # favorite_color is now { "lion": "yellow", "kitty": "red" }
So in your case you can do:
def read_file(filename1,filename2):
with open(filename1, 'rb') as file1:
f1=pickle.load(file1)
with open(filename1, 'rb') as file2:
f2=pickle.load(file2)
return f1,f2
There are a few things that don't quite work here:
Your second with-clause is not inside of your function, neither are your returns
A function can only return once. When python reaches the first return inside a function, it exits that function. But you can return multiple things at once, e.g. with return file1, file2
Your pickle-loading is the other way around. Like this, you redefine your file1 and file2 - variables with whatever your call of pickle.load() (notice that it didn't get any arguments) would give you -- what you want is to pass the file you opened to pickle.load and then save the output of that to a new variable
You never actually called your read_file function
your indentation seems to be off
sys.argv is a list, you can't call it (Round braces, like sys.argv(1)) but you can index it (square brackets sys.argv[1])
import sys
import pickle
def read_file(filename1,filename2):
with open(filename1, 'rb') as file1:
data1 = pickle.load(file1)
with open(filename1, 'rb') as file2:
data2 = pickle.load(file2)
return data1, data2
filename1 = sys.argv[1]
filename2 = sys.argv[2]
your_data = read_file(filename1, filename2)
print(your_data) # Now you use your data, i used print as an example
sys.exit() # You usually only write that if you specifically need to
Further suggestion:
You don't necessarily have to make one function to handle two files, you can also just make one function to handle one file and call it twice.
import pickle
def read_file(filename):
with open(filename, 'rb') as file1:
data = pickle.load(file1)
return data1
filename1 = sys.argv[1]
filename2 = sys.argv[2]
your_data = read_file(filename1), read_file(filename2)
print(your_data)

Accessing dictionaries with field names

I have an unpickle function which returns a dict as:
def unpickle(file):
with open(file, 'rb') as fo:
dict = pickle.load(fo, encoding='bytes')
return dict
and a function which reads pickled object with fieldnames (Don't know if this is the correct definiton):
def do_sth():
all_data = unpickle('mypickle.pickle')
image_filenames = all_data["Filenames"]
conditions = all_data["Labels"]
I have two lists as Filenames = ['001.png','002.png'] and Labels = ['0','1'] for brevity, that I need to pickle and save under mypickle.pickle so I can call them under the do_sth function. Till now what I did is:
data = [Filenames,Labels]
with open("mypickle.pickle", "wb") as f:
pickle.dump(data, f)
and
data = dict(zip(file_paths, labels))
with open("mypickle.pickle", "wb") as f:
pickle.dump(data, f)
But I'm getting KeyError :'Filenames'. Which structure shall I use to save these 2 lists so they may work properly.
Thanks.
Change your function to this
def do_sth():
all_data = unpickle('mypickle.pickle')
image_filenames = all_data[0]
conditions = all_data[1]
Explanation
You saved pickle as list. When you load the pickle it is still a list.
or
Actually save it as a dict
data = {"Filenames": Filenames, "Labels": Labels}
with open("mypickle.pickle", "wb") as f:
pickle.dump(data, f)

How to make json file a list in Python

as said, I'd like to open a json file and make it into a list, in order to append new elements to it and then dump all back into the json file.
Here is my code(the commented part is what I previously tried):
class Carta:
def __init__(self,filename):
self.__filename = filename
self.__lista = []
# try:
# f = open(self.__filename,"r")
# except:
# f = open(self.__filename, "w")
# f.close()
# f = open(self.__filename, "r")
with open(self.__filename) as file:
self.__lista = json.load(file)
# read=json.load(f)
# for c in leggi:
# self.__lista.append(c)
# print(self.__lista)
# f.close()
def add(self, c):
self.__lista.append(c)
def save(self):
f = open(self.__filename, "w")
for c in self.__lista:
f.write("%s\n" % str(c))
f.close()
It wouldn't work if you read from a JSON file, json list and then write custom string. Because next time you read the JSON file it's gonna fail.
So, during write/save you should make it json itself. Here's the code the explains how to do it.
import json
class Carta:
def __init__(self, filename):
self.__filename = filename
self.__lista = list()
self.read_from_json_file()
def read_from_json_file(self):
with open(self.__filename) as file:
self.__lista = json.load(file)
def write_to_json_file(self):
with open(self.__filename, 'w') as f:
json.dump(self.__lista, f)
def add(self, value):
self.__lista.append(value)
The reason you should use with open(filename, mode) as f: instead of f = open(filename) is because at the end of with block the file is automatically closed. Otherwise you've to call f.close() every time you open a file.
json.load - reads json data from file, converts to python data type/structure.
json.dump - read python data type/structure, converts it into string and stores it in the file (file handle) and saves the file.
Using pdb to trace errors
import json
import pdb
class Carta:
def __init__(self, filename):
self.__filename = filename
self.__lista = list()
self.read_from_json_file()
def read_from_json_file(self):
pdb.set_trace() # to pause execution and start debugger
# When paused,
# type n to continue to next line,
# type c to continue execution or to continue to the next loop
# type b <file_name>:<line_number> to add another break point, where <file_name> and <line_number> are place holders
# Example, b /home/username/hello.py:43, will add breakpoint at 43 line of hello.py in /home/username path
# type q to quit debugger and halt execution
with open(self.__filename) as file:
self.__lista = json.load(file)
def write_to_json_file(self):
with open(self.__filename, 'w') as f:
json.dump(self.__lista, f)
def add(self, value):
# Second breakpoint
pdb.set_trace()
self.__lista.append(value)
Or just run your file with
python -m pdb file.py and then add breakpoints. It will pause in the first line itself and return you a (pdb) console where you can add breakpoint.
import json
#read from file
with open("demofile.txt", "r") as f: x = f.read()
#parse
y = json.loads(x)
#edit
y["user"] = { "fname": "John", "lname": "Who"}
#save to file
with open("demofile.txt", "w") as f: f.write(json.dumps(y))
https://repl.it/#KrzysztofPecyna/PythonJsonExample
To read JSON from a file:
import json
with open('data.txt') as json_file:
data = json.load(json_file)
To add new data:
data['key'] = "value"
To write JSON to a file:
with open('data.txt', 'w') as outfile:
json.dump(data, outfile)

Python / Function parameters

Main objective:
function to read top score from text file.
Parameters to be passed onto function:
A text document!
def highscore():
try:
text_file = open ("topscore.txt", "r")
topscore = int(text_file.read())
print topscore
text_file.close()
return topscore
except:
print "Error - no file"
topscore = 0
return topscore
How to add a text file as a parameter?
def highscore(filename):
try:
text_file = open (filename, "r")
Oh, and you should stop putting more code than necessary into your try block. A clean solution would look like this:
def highscore(filename):
if not os.path.isfile(filename):
return 0
with open(filename, 'r') as f:
return int(f.read())
Or, if you prefer to return 0 in any case where reading the file fails:
def highscore(filename):
try:
with open(filename, 'r') as f:
return int(f.read())
except:
return 0
Another option is to provide a keyword argument. That may be useful if, for example, you have old code that uses this function and can't be updated for some strange reason. Keyword arguments can include a default value.
def highscore( filename = "filename.txt" ):
try:
text_file = open (filename, "r")
Then you can call this function as before to use the default value, "filename.txt":
highscore()
Or specify any new filename:
highscore( filename = "otherfile.csv" )
See the python documentation for more information.
http://docs.python.org/tutorial/controlflow.html#default-argument-values
def highscore(filename):
try:
text_file = open(filename, "r")
...
Simply add a variable identifier (e.g.,filename) to your parameter list and then refer to it when you open the file.
Then call your function with the filename you choose.
topscore = highscore("topscore.txt")

Categories