I am a beginner in python . why the variable "env" being used while opening the file and other places in the following code . From the tutorials i have seen file opening formats were always like with open(filename) as f , but here a variable name is being used. Please explain .
def main():
global debug, testing,env, mode
newID=0
rv=[]
name=''
if "debug" in sys.argv:
debug = True
if "testing" in sys.argv:
testing = True
if debug:
print(sys.argv)
if "copyAccountProfile" in sys.argv:
mode = 'copyAccountProfile'
envProfile = sys.argv[1]
if debug:
print(envProfile)
with open(envProfile) as f_in:
lineList = list(line for line in (l.strip() for l in f_in) if line)
# ff = open(envProfile)
# lineList = [line for line in ff.readlines() if line.strip()]
for line in lineList:
if line.startswith('#'):
continue
[nm, v]=line.strip().split('=')
env[nm.strip()]=v.strip()
if debug:
print(env)
with open(env['accountProfile']) as f_in:
accountList = list(line for line in (l.strip() for l in f_in) if line)
if mode == 'copyData':
for acc in accountList:
[name,Id] = acc.strip().split(',')
name = name.strip()
#copyData(name, env['src_ror'], workingDir, env['dst_ror'], workingDir, 'bk_files', True)
copyData(name, env['src_ror'], workingDir, env['dst_ror'], workingDir, 'bk_files')
copyData(name, env['src_ror'], workingDir, env['dst_bpm'], backupDir, 'bk_files')
copyData(name, env['src_bpm'], workingDir, env['dst_bpm'], workingDir, 'ft_files')
localCopyData(name, env['dst_bpm'], workingDir, backupDir)
else:
#copy updated accountProfile from dst_ror to dst_bpm
fname = env['accountProfile']
# src = ip:port, dst = ip:port}
[sIp, sPort]=env['dst_ror'].split(':')
[dIp, dPort]=env['dst_bpm'].split(':')
copyFile(fname, sIp, sPort, toolDir, dPort, dIp, toolDir)
Welcome Prema. Variable names can be anything the author wishes them to be. Generally, a programmer should use descriptive variable names that relate to the data being stored in that variable.
Since this example is poorly documented, I'll have to assume that the author used "env" to show that this variable is somehow connected to an environment of some sort.
This author seems to be using the "f_in" variable name to indicate the file is an input file.
Related
Let's say that I have a file that contains different MAC address notations of multiple MAC addresses. I want to replace all the matching notations of one MAC address I have parsed from an argument input. So far my script generates all the notations I need and can loop through the lines of the text and show the lines that have to be changed.
import argparse, sys
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--filename")
parser.add_argument("-m", "--mac_address")
args = parser.parse_args()
mac = args.mac_address #In this case 00:1a:e8:31:71:7f
colon2 = mac #00:1a:e8:31:71:7f
dot2 = colon2.replace(":",".") # 00.1a.e8.31.71.7f
hyphen2 = colon2.replace(":","-") # 00-1a-e8-31-71-7f
nosymbol = colon2.replace(":","") # 001ae831717f
colon4 = ':'.join(nosymbol[i:i+4] for i in range(0, len(nosymbol), 4)) # 001a:e831:717f
dot4 = colon4.replace(":",".") # 001a.e831.717f
hyphen4 = colon4.replace(":","-") # 001a-e831-717f
replacethis = [colon2,dot2,hyphen2,dot4,colon4,nosymbol,hyphen4]
with open(args.filename, 'r+') as f:
text = f.read()
for line in text.split('\n'):
for n in replacethis:
if line.replace(n, mac) != line:
print line + '\n has to change to: \n'line.replace(n,mac)
else:
continue
If the file would look like this:
fb:76:03:f0:67:01
fb.76.03.f0.67.01
fb-76-03-f0-67-01
001a:e831:727f
001ae831727f
fb76.03f0.6701
001ae831727f
fb76:03f0:6701
001a.e831.727f
fb76-03f0-6701
fb7603f06701
it should change to:
fb:76:03:f0:67:01
fb.76.03.f0.67.01
fb-76-03-f0-67-01
00:1a:e8:31:71:7f
00:1a:e8:31:71:7f
fb76.03f0.6701
00:1a:e8:31:71:7f
fb76:03f0:6701
00:1a:e8:31:71:7f
fb76-03f0-6701
fb7603f06701
I am struggling at writing the new lines containing the changed MAC address notation back to the file replacing the previous line.
Is there a way to do this?
A simple way to achieve what you are asking you can add a line to store the final values you get, and after that include another ‘with open’ statement to write it to a new file.
replacethis = [colon2, dot2, hyphen2, dot4, colon4, nosymbol, hyphen4]
final_values =[]
with open(args.filename, 'r+') as f:
text = f.read()
for line in text.split('\n'):
for n in replacethis:
if line.replace(n, mac) != line:
print line + '\n has to change to: \n'line.replace(n,mac)
final_values.append(line.replace(n, mac)
else:
continue
final_values.append(line)
with open(new_file_name, ‘w’) as new_f:
new_f.write(final_values)
Note that if new_file_name = your old file name, you will overwrite the original file.
I hope that answers your question.
I have one file named mcelog.conf and I am reading this file in my code. Contents of the file are
no-syslog = yes # (or no to disable)
logfile = /tmp/logfile
Program will read the mcelog.conf file and will check for the no-syslog tag, if no-syslog = yes then program has to check for the tag logfile and will read the logfile tag. Can anyone let me know how I can get the value /tmp/logfile
with open('/etc/mcelog/mcelog.conf', 'r+') as fp:
for line in fp:
if re.search("no-syslog =", line) and re.search("= no", line):
memoryErrors = readLogFile("/var/log/messages")
mcelogPathFound = true
break
elif re.search("no-syslog =", line) and re.search("= yes", line):
continue
elif re.search("logfile =", line):
memoryErrors = readLogFile(line) # Here I want to pass the value "/tmp/logfile" but currently "logfile = /tmp/logfile" is getting passed
mcelogPathFound = true
break
fp.close()
You can just split the line to get the value you want:
line.split(' = ')[1]
However, you might want to look at the documentation for configparser module.
Change the code to:
with open('/etc/mcelog/mcelog.conf', 'r+') as fp:
for line in fp:
if re.search("no-syslog =", line) and re.search("= no", line):
memoryErrors = readLogFile("/var/log/messages")
mcelogPathFound = true
break
elif re.search("no-syslog =", line) and re.search("= yes", line):
continue
elif re.search("logfile =", line):
emoryErrors = readLogFile(line.split("=")[1].strip()) # Here I want to pass the value "/tmp/logfile" but currently "logfile = /tmp/logfile" is getting passed
mcelogPathFound = true
break
fp.close()
This is because you want to read only a part of the line rather the whole thing so I have just split it up by the "=" sign and then stripped it to remove any blanks
I liked the suggestion of the configparser module, so here is an example of that (Python 3)
For the given input, it will output reading /var/log/messages
import configparser, itertools
config = configparser.ConfigParser()
filename = "/tmp/mcelog.conf"
def readLogFile(filename):
if filename:
print("reading", filename)
else:
raise ValueError("unable to read file")
section = 'global'
with open(filename) as fp:
config.read_file(itertools.chain(['[{}]'.format(section)], fp), source = filename)
no_syslog = config[section]['no-syslog']
if no_syslog == 'yes':
logfile = "/var/log/messages"
elif no_syslog == 'no':
logfile = config[section]['logfile']
if logfile:
mcelogPathFound = True
memoryErrors = readLogFile(logfile)
with open(url_for('static', filename='bmidata.txt') as f:
the above line causes a syntax error (marked at the 'as'). The code is part of the following:
#app.route('/display')
def display():
page_info = {
'title':'Assignment Flask',
'heading': 'Python Flask Assignment'
}
filedata = []
with open(url_for('static', filename='bmidata.txt') as f:
for line in f:
str = line
dataarray = str.split(',')
it =iter(dataarray)
name = it.next()
height = it.next()
weight = it.next()
newPerson = Person(name, height,weight)
filedata.append(newPerson)
return render_template('display.html', info = page_info, fileinfo = filedata)
Any help appreciated
In this line:
with open(url_for('static', filename='bmidata.txt') as f:
you are missing one closing bracket:
with open(url_for('static', filename='bmidata.txt')) as f:
That's the reason for SyntaxError.
Opening file doesn't work this way, because open doesn't accept URL. If you need to open static file, use with app.open_resource('static/bmidata.txt') as f: or find the path of the file on the filesystem.
I am using this code to search for emails in a particular file and write them into a another file. I have used 'in' operator to make sure that the email are not duplicated.
But this code does not get executed after the for line in f: line.
Can any one point out the mistake i have made here?
tempPath = input("Please Enter the Path of the File\n")
temp_file = open(tempPath, "r")
fileContent = temp_file.read()
temp_file.close()
pattern_normal = re.compile("[-a-zA-Z0-9._]+#[-a-zA-Z0-9_]+.[a-zA-Z0-9_.]+")
pattern_normal_list = pattern_normal.findall(str(fileContent))
with open('emails_file.txt', 'a+') as f:
for item in pattern_normal_list:
for line in f:
if line in item:
print("duplicate")
else:
print("%s" %item)
f.write("%s" %item)
f.write('\n')
New solution:
tempPath = input("Please Enter the Path of the File\n")
temp_file = open(tempPath, "r")
fileContent = temp_file.read()
temp_file.close()
pattern_normal = re.compile("[-a-zA-Z0-9._]+#[-a-zA-Z0-9_]+.[a-zA-Z0-9_.]+")
addresses = list(set(pattern_normal.findall(str(fileContent))))
with open('new_emails.txt', 'a+') as f:
f.write('\n'.join(addresses))
I think your logic was wrong, this works:
addresses = ['test#wham.com', 'heffa#wham.com']
with open('emails_file.txt', 'a+') as f:
fdata = f.read()
for mail in addresses:
if not mail in fdata:
f.write(mail + '\n')
Without reading to much into your code,
it looks like youre looping line by line, checking if the address you've also looping through exists in the line, if it doesn't you append your e-mail to it? But in 99% of a 100 lines the address will not be in the line, hence you'll get an unwanted addition.
Output of my code snippet:
[Torxed#faparch ~]$ cat emails_file.txt
test#wham.com
Torxed#whoever.com
[Torxed#faparch ~]$ python test.py
[Torxed#faparch ~]$ cat emails_file.txt
test#wham.com
Torxed#whoever.com
heffa#wham.com
[Torxed#faparch ~]$
for line in f:
Shouldn't you first call f.readlines()?
lines = f.readlines()
for line in lines:
Check this.
I want to learn Python so I started writing my first program which is a phone book directory.
It has the options to add a name and phone number, remove numbers, and search for them.
Ive been stuck on the remove part for about 2 days now and just can't get it working correctly. I've been in the Python IRC and everything, but haven't been able to figure it out.
Basically, my program stores the numbers to a list in a file. I cannot figure out how to remove a particular line in the file but keep the rest of the file intact. Can someone please help me with this?
Some people have advised that it will be easier to do if I create a temp file, remove the line, then copy the remaining lines from the original file over to the temp file. Then write over the original file over with the temp file. So I have been trying this...
if ui == 'remove':
coname = raw_input('What company do you want to remove? ') # company name
f = open('codilist.txt', 'r') # original phone number listing
f1 = open('codilist.tmp', 'a') # open a tmp file
for line in f:
if line.strip() != coname.strip():
for line in f:
f1.write(line)
break # WILL LATER OVERWRITE THE codilist.txt WITH THE TMP FILE
else:
f1.write(line)
else:
print 'Error: That company is not listed.'
f1.close()
f.close()
continue
I assume your file contains something like <name><whitespace><number> on each line? If that's the case, you could use something like this for your if statement (error handling not included!):
name, num = line.strip().split()
if name != coname.strip():
# write to file
Suggestion:
Unless there is some specific reason for you to use a custom format, the file format json is quite good for this kind of task. Also note the use of the 'with' statement in these examples, which saves you having to explicitly close the file.
To write the information:
import json
# Somehow build a dict of {coname: num,...}
info = {'companyA': '0123456789', 'companyB': '0987654321'}
with open('codilist.txt', 'w') as f:
json.dump(info, f, indent=4) # Using indent for prettier files
To read/amend the file:
import json
with open('codilist.txt', 'r+') as f:
info = json.load(f)
# Remove coname
if coname in info:
info.pop(coname)
else:
print 'No record exists for ' + coname
# Add 'companyC'
info['companyC'] = '0112233445'
# Write back to file
json.dump(info, f, indent=4)
You'll need python2.6 or later for these examples. If you're on 2.5, you'll need these imports:
import simplejson as json
from __future__ import with_statement
Hope that helps!
Here is a pretty extensively rewritten version:
all the phone data is wrapped into a Phonebook class; data is kept in memory (instead of being saved and reloaded for every call)
it uses the csv module to load and save data
individual actions are turned into short functions or methods (instead of One Big Block of Code)
commands are abstracted into a function-dispatch dictionary (instead of a cascade of if/then tests)
This should be much easier to understand and maintain.
import csv
def show_help():
print('\n'.join([
"Commands:",
" help shows this screen",
" load [file] loads the phonebook (file name is optional)",
" save [file] saves the phonebook (file name is optional)",
" add {name} {number} adds an entry to the phonebook",
" remove {name} removes an entry from the phonebook",
" search {name} displays matching entries",
" list show all entries",
" quit exits the program"
]))
def getparam(val, prompt):
if val is None:
return raw_input(prompt).strip()
else:
return val
class Phonebook(object):
def __init__(self, fname):
self.fname = fname
self.data = []
self.load()
def load(self, fname=None):
if fname is None:
fname = self.fname
try:
with open(fname, 'rb') as inf:
self.data = list(csv.reader(inf))
print("Phonebook loaded")
except IOError:
print("Couldn't open '{}'".format(fname))
def save(self, fname=None):
if fname is None:
fname = self.fname
with open(fname, 'wb') as outf:
csv.writer(outf).writerows(self.data)
print("Phonebook saved")
def add(self, name=None, number=None):
name = getparam(name, 'Company name? ')
number = getparam(number, 'Company number? ')
self.data.append([name,number])
print("Company added")
def remove(self, name=None):
name = getparam(name, 'Company name? ')
before = len(self.data)
self.data = [d for d in self.data if d[0] != name]
after = len(self.data)
print("Deleted {} entries".format(before-after))
def search(self, name=None):
name = getparam(name, 'Company name? ')
found = 0
for c,n in self.data:
if c.startswith(name):
found += 1
print("{:<20} {:<15}".format(c,n))
print("Found {} entries".format(found))
def list(self):
for c,n in self.data:
print("{:<20} {:<15}".format(c,n))
print("Listed {} entries".format(len(self.data)))
def main():
pb = Phonebook('phonebook.csv')
commands = {
'help': show_help,
'load': pb.load,
'save': pb.save,
'add': pb.add,
'remove': pb.remove,
'search': pb.search,
'list': pb.list
}
goodbyes = set(['quit','bye','exit'])
while True:
# get user input
inp = raw_input("#> ").split()
# if something was typed in
if inp:
# first word entered is the command; anything after that is a parameter
cmd,args = inp[0],inp[1:]
if cmd in goodbyes:
# exit the program (can't be delegated to a function)
print 'Goodbye.'
break
elif cmd in commands:
# "I know how to do this..."
try:
# call the appropriate function, and pass any parameters
commands[cmd](*args)
except TypeError:
print("Wrong number of arguments (type 'help' for commands)")
else:
print("I didn't understand that (type 'help' for commands)")
if __name__=="__main__":
main()
Something simple like this will read all of f, and write out all the lines that don't match:
for line in f:
if line.strip() != coname.strip():
f1.write(line)
Ned's answer looks like it should work. If you haven't tried this already, you can set python's interactive debugger above the line in question. Then you can print out the values of line.strip() and coname.strip() to verify you are comparing apples to apples.
for line in f:
import pdb
pdb.set_trace()
if line.strip() != coname.strip():
f1.write(line)
Here's a list of pdb commands.
You probably don't want to open the temp file in append ('a') mode:
f1 = open('codilist.tmp', 'a') # open a tmp file
also, be aware that
for line in f:
...
f1.write(line)
will write everything to the file without newlines.
The basic structure you want is:
for line in myfile:
if not <line-matches-company>:
tmpfile.write(line + '\n') # or print >>tmpfile, line
you'll have to implement <line-matches-company> (there isn't enough information in the question to know what it should be -- perhaps if you showed a couple of lines from your data file..?)
I got this working...
if ui == 'remove':
coname = raw_input('What company do you want to remove? ') # company name
f = open('codilist.txt')
tmpfile = open('codilist.tmp', 'w')
for line in f:
if coname in line:
print coname + ' has been removed.'
else:
tmpfile.write(line)
f.close()
tmpfile.close()
os.rename('codilist.tmp', 'codilist.txt')
continue