Im reading a file and checking the timestamps of the entries in that file... I want to check timestamps and if the time stamp has been modified from files with {/home/admin/backup}
#!/usr/bin/python3
import argparse
import os
parser = argparse.ArgumentParser()
parser.add_argument('-c', default="config.dat", help='file to read the config from')
args = parser.parse_args()
#this reads and prints times okay
f = open('config.dat','r')
list_contents = f.read().split('\n')
for a in list_contents:
b = os.path.getmtime(a)
#problem is here.
cache = dict((a, os.path.getmtime(a)) for a in list_contents)
print('cache')
#if file recently modified then do this next code:....
Related
This program scans through a log file and finds faults and timestamps for the faults. The problem I am having with my program is finding a way to modify my program so that it can iterate over multiple files given via the command line and wildcard. In the state the code is now, it can accept a single file and build the dictionary with my my desired info successfully. I have been struggling finding a way to perform this with multiple files simultaneously. The goal is to able to enter into the command line the filename with a wildcard to parse files associated. For example on the command line after the executable I would enter, -f filename.*txt**. However, I cannot find a way to parse multiple files through my fault finder. I have been successful in parsing multiple files and proved it by printing out the list of files parsed. But when it comes to using multiple files and building the dictionary, I am stumped. I would like to use my program and have the same result as it would when parsing a singular file.
import sys
import argparse
_TIME_STAMP_LENGTH = 16
_FAULT_STRING_HEADER_LENGTH = 15
class FaultList():
fault_dict = {}
fault_dict_counter = {}
def __init__(self, file):
self.file = file
self.find_faults()
print self.fault_dict
def find_faults(self):
with open(self.file) as f:
for line in f.readlines():
fault_index = line.find("Fault Cache id")
if(fault_index != -1):
time_stamp = line[:_TIME_STAMP_LENGTH]
fault_data = line[fault_index+_FAULT_STRING_HEADER_LENGTH:-11][:-1] #need the [:-1] to remove new line from string
self.handle_new_fault_found(fault_data, time_stamp)
def handle_new_fault_found(self, fault, time_stamp):
try:
self.fault_dict[fault] = [fault]
self.fault_dict[fault].append(int(time_stamp))
self.fault_dict_counter[0] += 1
except KeyError:
self.fault_dict_counter[fault] = [1, [time_stamp]]
def main(file_names):
parser = argparse.ArgumentParser()
parser.add_argument("-f", "--file", dest="file_names",
help="The binary file to be writen to flash")
args = parser.parse_args()
fault_finder = FaultList(args.file_names)
args = parser.parse_args()
if __name__ == '__main__':
main(sys.argv[1:])
Here is the output of dictionary when parsing a singular file
{'fault_01_17_00 Type:Warning': ['fault_01_17_00 Type:Warning', 37993146319], 'fault_0E_00_00 Type:Warning': ['fault_0E_00_00 Type:Warning', 38304267561], 'fault_05_01_00 Typ': ['fault_05_01_00 Typ', 38500887160]}
You can use the os module for listing files.
import os
# finds all files in a directory
files = [file for file in os.listdir('path of the files') if os.path.isfile(file)]
# filter them looking for files that end with 'txt'
txt_files = [file for file in files if file.endswith('txt')]
Im trying to add the switch -c and specify the config file.
I have it working at the moment using the config.dat but when i use -c and specify a new .dat it uses the default config.dat....
Any idea where im going wrong?
#!/usr/bin/python3
import argparse
import shutil
parser = argparse.ArgumentParser(description='Copy multiple Files from a specified data file')
parser.add_argument('-c', '--configfile', default="config.dat",help='file to read the config from')
def read_config(data):
try:
dest = '/home/admin/Documents/backup/'
#Read in date from config.dat
data = open('config.dat')
#Interate through list of files '\n'
filelist = data.read().split('\n')
#Copy through interated list and strip white spaces and empty lines
for file in filelist:
if file:
shutil.copy(file.strip(), dest)
except FileNotFoundError:
pass
args =parser.parse_args()
read = read_config(args.configfile)
args =parser.parse_args()
Take a close look at what you are doing on line 14. Even though you are retrieving and assigning the --configfile argument to args you are still using a string literal data = open('config.dat') instead of passing data (which is the value of your argument for the configfile passed as an argument to the function read_config):
def read_config(data):
try:
dest = '/home/admin/Documents/backup/'
#Read in date from config.dat
data = open(data)
...
I would also change the naming of the argument data you are passing to read_config-- it's a bit ambiguous. You know that this function expects a file name as an argument so why not simply call it filename.
def read_config(filename):
import pdb; pdb.set_trace()
try:
dest = '/home/admin/Documents/backup/'
#Read in date from config.dat
data = open(filename)
#Interate through list of files '\n'
filelist = data.read().split('\n')
#Copy through interated list and strip white spaces and empty lines
for file in filelist:
if file:
shutil.copy(file.strip(), dest)
except FileNotFoundError:
pass
This code works by converting the args to a dictionary, then getting the value via key. Also, the code you had on line 13 didn't open the passed in value. This one opens the passed in file. See if this works for you:
# !/usr/bin/python3
import argparse
import shutil
parser = argparse.ArgumentParser(description='Copy multiple Files from a specified data file')
parser.add_argument('-c', '--configfile', default="config.dat", help='file to read the config from')
def read_config(data):
try:
dest = '/home/admin/Documents/backup/'
# Read in date from config.dat
data = open(data)
# Interate through list of files '\n'
filelist = data.read().split('\n')
# Copy through interated list and strip white spaces and empty lines
for file in filelist:
if file:
shutil.copy(file.strip(), dest)
except FileNotFoundError:
pass
args = vars(parser.parse_args())
read = read_config(args['configfile'])
Make proper use of the function argument; names changed to clarify the nature of the variables.
def read_config(filename='config.dat'):
try:
dest = '/home/admin/Documents/backup/'
afile = open(filename)
#Interate through list of files '\n'
filelist = afile.read().split('\n')
#Copy through interated list and strip white spaces and empty lines
for file in filelist:
if file:
shutil.copy(file.strip(), dest)
except FileNotFoundError:
pass
I'm trying to give a TXT file with argparse and then to open it in a function.
Can you tell me why it say : error:unrecognized arguments : dataBase.txt
(ps: dataBase is the file I'm trying to open)
update(1)
my main :
if __name__ =='__main__':
parser=argparse.ArgumentParser()
parser.add_argument("file_name",type= argparse.FileType,help="name of file with network")
args=parser.parse_args()
z=args.file_name
names,network= loadNetwork()
a little part of my function:
def loadNetwork():
fileName=open('z', 'r')
name = fileName.readlines()
I think it's because file is not a valid type for argparse in Python3. The type argument takes a callable, and since file doesn't exist in Python3, it'll throw an error. Try using FileType instead.
parser = argparse.ArgumentParser()
parser.add_argument("file_name", type=argparse.FileType("r"), help="name of file with network")
Here's roughly, how I think your code should look:
def loadNetwork(afile):
name = afile.readlines()
return name
if __name__ =='__main__':
parser=argparse.ArgumentParser()
parser.add_argument("file",type= argparse.FileType('r'),
help="name of file with network")
# FileType opens the file you specified;
# so you don't need to open it
args = parser.parse_args()
names,network = loadNetwork(args.file)
args.file.close()
It's a good idea to pass values set by argparse to your functions as parameters, rather than setting global variables.
But if instead you would prefer to open and close the file yourself, I'd suggest:
def loadNetwork(filename):
with open(filename) as f:
name = f.readlines()
return name
if __name__ =='__main__':
parser=argparse.ArgumentParser()
parser.add_argument("filename", help="name of file with network")
args = parser.parse_args()
names,network = loadNetwork(args.filename)
the with statement opens and closes the file. A down side to this is that argparse isn't going to issue an error message if the filename isn't valid. But the with open will. Also this doesn't accept '-' as a filename (FileType takes that to mean sys.stdin).
I have a working code to print random lines from a csv column.
#!/usr/bin/python
import csv
from random import shuffle
filename = 'example.csv'
col = 2
sample = 100
with open(filename, 'r') as f:
reader = csv.reader(f)
data = [row[col] for row in reader]
shuffle(data)
print '\n'.join(data[:sample])
How can I parameterize this script by passing filename, col & sample (e.g. 100 values)?
Use argparse module:
The argparse module makes it easy to write user-friendly command-line
interfaces. The program defines what arguments it requires, and
argparse will figure out how to parse those out of sys.argv. The
argparse module also automatically generates help and usage messages
and issues errors when users give the program invalid arguments.
It's pretty powerful: you can specify help messages, make validations, provide defaults..whatever you can imagine about working with command-line arguments.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--position", type=int)
parser.add_argument("-s", "--sample", type=int)
args = parser.parse_args()
col = args.position
sample = args.sample
print col
print sample
Here's what on the command-line:
$ python test.py --help
usage: test.py [-h] [-p POSITION] [-s SAMPLE]
optional arguments:
-h, --help show this help message and exit
-p POSITION, --position POSITION
-s SAMPLE, --sample SAMPLE
$ python test.py -p 10 -s 100
10
100
$ python test.py --position 10 --sample 100
10
100
Speaking about the code you've provided:
unused import random statement
move from random import shuffle to the top of the script
no need to call f.close() (especially with ;) - with handles closing the file automagically
Here's how the code would look like after the fixes:
#!/usr/bin/python
import argparse
import csv
from random import shuffle
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--position", type=int)
parser.add_argument("-s", "--sample", type=int)
args = parser.parse_args()
with open('<filename>', 'r') as f:
reader = csv.reader(f)
data = [row[args.position] for row in reader]
shuffle(data)
print '\n'.join(data[:args.sample])
You can use the sys module like this to pass command line arguments to your Python script.
import sys
name_of_script = sys.argv[0]
position = sys.argv[1]
sample = sys.argv[2]
and then your command line would be...
./myscript.py 10 100
I could not install argparse due to lack of permission - meanwhile.
Here's the solution:
#!/usr/bin/python
import csv # This will help us reading csv formated files.
import sys
import optparse #import optparse
from random import shuffle
parser=optparse.OptionParser()
# import options
parser.add_option('-f','--filename',help='Pass the csv filename')
parser.add_option('-p','--position',help='column position in the file',type=int)
parser.add_option('-s','--sample',help='sample size',type=int)
(opts,args) = parser.parse_args() # instantiate parser
# Program to select random values
with open('<filepath>'+opts.filename,'r') as f:
reader=csv.reader(f)
data=[row[opts.position] for row in reader]
shuffle(data)
#print '\n'.join(data[:opts.sample])
# create o/p file
file=open("<opfilename>.txt","w")
file.write('\n'.join(data[:opts.sample]))
file.close()
I'm trying open a txt file and read it, but I'm getting a type error and I'm unsure why. If you you could please provide a reasoning along with the correct syntax, I'm trying to get a better grasp of what's going on underneath. Here's the code, it's pretty simple I think:
from sys import argv
script = argv
filename = argv
txt = open(filename)
print "Here's your file %r" %filename
print txt.read()
Muchas Gracias
argv is a list, not a string. You want
script = argv[0]
filename = argv[1]
Consider using argparse instead of handing sys.argv directly:
>>> import argparse
>>> parser = argparse.ArgumentParser(description="Print a file.")
>>> parser.add_argument("path", type=str, nargs=1, help="Path to the file to be printed.")
_StoreAction(option_strings=[], dest='path', nargs=1, const=None, default=None, type=<type 'str'>, choices=None, help='Path to the file to be printed.', metavar=None)
>>> args = parser.parse_args()
>>> print args
Namespace(path=[<...>])
It looks much more complicated, but it will make your command-line utility much more flexible, easier to expand, and it will ensure you get proper documentation on the command line.
First of all, argv is a list of arguments. Open doesn't take a list. That's why you're getting a type error.
Second, open (should) take 2 parameters, the filename and the mode (yes mode is optional, but get in the habit of putting it there. Replace with
import sys
script = sys.argv[0]
filename = sys.argv[1]
txt = open(filename, 'r')
print "Here's your file %r" %filename
print txt.read()
argv will be a list, while filename should be a string.
You should probably be using filename = argv[1]