Stuck on figuring out the logic for conditional IF ELSE statement - python

I have my code here that reads my config file:
def getConfig(env):
pwd=os.getcwd()
if "win" in (platform.system().lower()):
f = open(pwd+"\config_"+env.lower()+"_dataset2.json")
else:
f = open(pwd+"/config_"+env.lower()+"_dataset2.json")
config = json.load(f)
f.close()
return config
The thing is, I want it to read my other config file as well but I don't know how to incorporate it in the original code above. I know something like this won't work:
def getConfig(env):
pwd=os.getcwd()
if "win" in (platform.system().lower()):
f = open(pwd+"\config_"+env.lower()+"_dataset2.json")
else:
f = open(pwd+"/config_"+env.lower()+"_dataset2.json")
if "win" in (platform.system().lower()):
f = open(pwd+"\config_"+env.lower()+"_dataset1.json")
else:
f = open(pwd+"/config_"+env.lower()+"_dataset1.json")
config = json.load(f)
f.close()
return config
I'm stuck on having the option to run both config files at once, or just run dataset1.json individually, or just run dataset2.json individually.
Maybe something like:
dataset2=config_"+env.lower()+"_dataset2.json
dataset1=config_"+env.lower()+"_dataset1.json
if dataset2:
f = open(pwd+"\config_"+env.lower()+"_dataset2.json")....
#staticmethod
def getConfig(env):
pwd=os.getcwd()
env = env.lower()
with open(os.path.join(pwd, f"config_{env}_dataset2.json")) as f:
config2 = json.load(f)
with open(os.path.join(pwd, f"config_{env}_dataset1.json")) as f:
config1 = json.load(f)
return config2, config1
config2, config1 = getConfig(env)
TypeError: 'staticmethod' object is not callable

You can return multiple values from the function.
There's no need for the conditionals, use os.path.join() to combine pathnames with the OS-specific delimiter.
def getConfig(env):
pwd=os.getcwd()
env = env.lower()
with open(os.path.join(pwd, f"config_{env}_dataset2.json")) as f:
config1 = json.load(f)
with open(os.path.join(pwd, f"config_{env}_dataset1.json")) as f:
config2 = json.load(f)
return config1, config2
dataset1, dataset2 = getConfig(env)
You also don't really need to join with pwd, since relative pathnames are interpreted relative to the current directory.

Related

Why am I getting access denied when I try to replace files

I am trying to replace a file by basically copying a file named "test.csv" to "new.csv" But it cannot find test.csv even though its in the same working directory.
def cop(self):
with open('D:\\johnp\\kivy_venv\\betaapp2\\test.csv') as infile:
with open('D:\\johnp\\kivy_venv\\betaapp2\\new.csv', 'w') as outfile:
for line in infile:
# do things
outfile.write(line)
os.replace('D:\\johnp\\kivy_venv\\betaapp2\\new.csv', 'D:\\johnp\\kivy_venv\\betaapp2\\test.csv')
def sign_in(self, text_input):
self.text_input = text_input
count = 0
h = ""
d = ""
with open('D:\\johnp\\kivy_venv\\betaapp2\\test.csv', 'r') as fh:
reader = csv.reader(fh)
# get the headers out first, which is the first line
headers = next(reader)
for line in reader:
# this will make a dictionary with the header values as
# keys and the line entries as values
entry = dict(zip(headers, (l.strip() for l in line)))
# use key access, it makes the code a bit more readable
if entry['Name'] == text_input.strip():
if entry['Position'] == "Vice President":
line[8] = float(line[8]) + 3.5
self.cop()
self.signin()
else:
self.noUser()
The test.csv is supposed to be updated by running sign_in and then copying it to new.csv. And then replace test.csv with new.csv.
They are in the same directory, but you haven't instructed Python to check that:
import os
base_path = "D:\\johnp\\kivy_venv\\betaapp2\\"
with open(os.path.join(base_path, "test.csv")) as infile:
with open(os.path.join(base_path, "new.csv"), 'w') as outfile:
Without path Python just looks in the current working directory.

Open statement according to a file extension

I need to process two types of files in a directory - .txt and .gz.
There are two types of open statements for this purpose:
.gz files:
with gzip.open(file_name, 'rt', encoding='utf-8') as f:
line = next(f)
while line:
some code
.txt files:
with open(file_name, 'r', encoding='utf-8') as f:
line = next(f)
while line:
some code
Any further processing commands are absolutely identical. Now I see two options to process these two file types:
Option 1 - Use two identical functions that differ only by open statement. Sounds ugly...
Option 2 - Use if construction as following:
if ext == '.gz':
f = gzip.open(file_name, 'rt', encoding='utf-8')
elif ext == '.txt':
f = open(file_name, 'r', encoding='utf-8')
line = next(f)
while line:
some code
But it still looks awkward to me :/
Question: what's pythonic way in Python 3.x to use open statement according to a file extension?
why not:
with (gzip.open if ext==".gz" else open)(file_name, 'rt', encoding='utf-8') as f:
the first argument of with is a ternary expression, where you decide which function to use depending on the extension. I used 'rt' in both cases, it's default for standard open. That method has the advantage to avoid copy/paste and to be able to use context manager.
Maybe some generic function could be created with an helper function:
def myopen(file_name)
return (gzip.open if os.path.splitext(file_name)[1]==".gz" else open)(file_name, 'rt', encoding='utf-8')
use like:
with myopen(file_name):
an alternative is to use a defaultdict with the extension as key
from collections import defaultdict
from pathlib import Path
open_functions = defaultdict(lambda: (open, ("r",), {encoding: "utf-8"}))
open_functions["gz"] = (gzip.open, ("rt",), {encoding: "utf-8"})
filename = Path(filename)
open_function, args, kwargs = open_functions[filename.suffix]
with open_function(filename, *args, **kwargs) as f:
...
I would like suggest the following way:
#------------------------------------
import zipfile
#-----------------------Common Code-------------------------
def disp_line(filee):
for line in filee.readlines():
print(line)
#-----------------------First File-----------------------
z = zipfile.ZipFile('D:\\DC-Data\\baby_names.zip', "r")
zinfo = z.namelist()
for name in zinfo:
with z.open(name) as filee:
disp_line(filee)
#-----------------------2nd File-------------------------
with open('D:\\DC-Data\\iris.txt', 'r') as filee:
disp_line(filee)
#------------------------End ----------------------

Combine two python with statements that share the same code

def test(file_name):
if file_name.lower().endswith('.gz'):
with gzip.open(file_name) as f:
f_csv = csv.reader(i.TextIOWrapper(f))
#### Same Code
if file_name.lower().endswith('.csv'):
with open(file_name) as f:
f_csv = csv.reader(i.TextIOWrapper(f))
#### Same Code
Question> Is there a better way to combine the above code without duplicating the 'Same Code' section? The function test uses gzip.open if the the file_name is a gz file otherwise it opens with regular open.
One way would be:
def test(file_name):
loader = None
if file_name.lower().endswith('.gz'):
loader = gzip.open
elif file_name.lower().endswith('.csv'):
loader = open
if loader is not None:
with loader(file_name) as f:
f_csv = csv.reader(i.TextIOWrapper(f))
#### Same Code
def test(file_name):
f = None
if file_name.lower().endswith('.gz'):
f = gzip.open(file_name)
if file_name.lower().endswith('.csv'):
f = open(file_name)
if f is not None:
f_csv = csv.reader(i.TextIOWrapper(f))
#### Same Code
f.close()

How do I get the contents of both pickle.dumps for my unit test?

I have a function like this:
def save_data(self):
nx.write_gpickle(self.graph, "popitgraph.pickle")
f = open("node_color.pickle", "w")
pickle.dump(self.colors, f)
f.close()
f = open("node_label.pickle", "w")
pickle.dump(self.labels, f)
f.close()
In my test I did this:
#patch("popit_to_networkx.nx.write_gpickle")
#patch("pickle.dump")
def test_networkx_save_data(self, mock_dump, mock_write_gpickle):
# Just assign graph a value to make sure it's passed in
from mock import mock_open
m_file = mock_open()
with patch("__builtin__.open", m_file):
self.popit2networkx.graph = "hulahoop"
self.popit2networkx.colors = {'color1', 'color2'}
self.popit2networkx.labels = {'label1', 'label2'}
self.popit2networkx.save_data()
self.assertEqual(mock_write_gpickle.call_args,
call('hulahoop', 'popitgraph.pickle'))
self.assertTrue(m_file.called)
self.assertEqual(m_file.call_args,
call('node_label.pickle', 'w'))
When I try to look at mock_dump.call_args I always get the contents of the latest call, how do I get the contents of the previous call ?
You should check the mock_dump.call_args_list property.

Invalid syntax of Else: 3.8

I'm a newbie in python scripting and would like to know how to fix the code below. I would like to know how to solve the Invalid Syntax of Else statement, thank you!
import os
import zipfile
f = open("filelist.txt","w+")
path=("pathtofile")
directory=os.fsencode(path)
filenames = []
for file in os.listdir(directory):
filename = os.fsdecode(file)
if filename.endswith(".zip"):
with zipfile.ZipFile(filename, 'r') as zipObj:
contents = zipObj.namelist()
listfile = (str(contents))
remchar = "'[]"
for char in remchar:
a = listfile.replace(char,"")
f.write (a)
continue
else:
pass
f.close()
Remember that indentation in python is significant. Your else: statement has no matching if statement on the same level. Make sure to indent properly to achieve what you're looking for:
if filename.endswith(".zip"):
with zipfile.ZipFile(filename, 'r') as zipObj:
contents = zipObj.namelist()
listfile = (str(contents))
remchar = "'[]"
for char in remchar:
a = listfile.replace(char,"")
f.write (a)
continue
else:
pass
The else statement is outside the end of the if one. You have to include an else right after you ended the other one. It's like this:
if filename.endswith(".zip"):
with zipfile.ZipFile(filename, 'r') as zipObj:
contents = zipObj.namelist()
else:
pass
If you're just going to write pass, then you can directly ommit the else.

Categories

Resources