I am making a program that will open multiple files, they are all very similar. All contains a few one word lines in lowercase on Notepad. I do not want to repeat the code multiple times. Ideally I want to use a while loop to repeat the code but change what file it opens each repeat. Is there a way to do it?
This is the current code:
File = open("Key Words\Audio.txt","r") #This will open the file called Audio.
Audio = [] #This creates the Audio list
Audio = File.read().splitlines() #This saves everything on each line of the Audio file to a diffrent section of the Audio list.
File = open("Key Words\Calls.txt","r") #This will open the file called Calls.
Calls = [] #This creates the Calls list
Calls = File.read().splitlines() #This saves everything on each line of the Calls file to a diffrent section of the Calls list.
File = open("Key Words\Charging.txt","r") #This will open the file called Charging.
Charging = [] #This creates the Charging list
Charging = File.read().splitlines() #This saves everything on each line of the Charging file to a diffrent section of the Charging list.
File.close() #This closes the File(s).
This is what functions are for:
def readfile(filepath):
with open(filepath, 'r') as f:
return f.read().splitlines()
audio = readfile('Key Words\Audio.txt')
calls = readfile('Key Words\Calls.txt')
charging = readfile('Key Words\Charging.txt')
Make a list of the files you need to open:
files_to_open = [
'file_1.txt',
'file_2.txt'
]
calls_info = {}
Iterate over the list, and open and process:
for file_ in files_to_open:
with open(file_) as f:
calls_info[file_] = f.read().splitlines()
Here, I created a calls_info variable. What this will do is store everything in a dictionary. These hold keys and values - to access the value of a file, simply index it like so:
calls_info[file_path] # Make sure file_path is the right path you put in the list!
Put the code in a function:
def openandread(filename):
# No need to close the file if you use with:
with open(filename,"r") as File:
return_this = File.read().splitlines()
return return_this
and then just call this function multiple times:
Audio = openandread("Key Words\Audio.txt")
Calls = openandread("Key Words\Calls.txt")
Charging = openandread("Key Words\Charging.txt")
or if you want to make it even shorter:
Audio, Calls, Charging = (openandread(i) for i in ["Key Words\Audio.txt", "Key Words\Calls.txt", "Key Words\Charging.txt"])
Try this
Audio = []
Calls = []
Charging = []
FILES_LISTS = (
( "Key Words\Audio.txt", Audio ),
( "Key Words\Calls.txt", Calls ),
( "Key Words\Charging.txt", Charging )
)
for file_name, list_var in FILES_LISTS:
File = open( file_name, 'r' )
list_var += File.read().splitlines()
File.close()
Make sure to type list_var += and not list_var =. This works because lists are mutable and because python works with references.
You can try unipath
# Install
$easy_install unipath
# In python
from unipath import Path
t1 = Path('Key Words\Audio.txt')
...
Related
So basically I want to create a variable that changes after every iteration of a for loop to be the same as the search term that is used in the for loop in question, is that possible? I explained better in the code I think.
with open ('lista1.txt','r') as file_1:
reader_0 = file_1.readlines() # Reads a list of searchterms,
# the first search term of this list is "gt-710".
for search in reader_0:
file_0 = search.replace("\n","") +".txt"
file_1 = str(file_0.strip())
try: #if the file named the same as the searchterm exists, read its contents
file = open(file_1,"r")
search = file.readlines() # How do I create a variable that
# changes names? for example I want the
# content of file readlines be saved in
# a variable called the same as the
# searchterm in this ase I want it to
# be gt-710 = file.readlines()...in the
# next iteration I want it to be
# next_search_term_in_the_list =
# file.readlines()..an so on...
print(str(search) + "I actually tried")
except: #if not, create it
file = open(file_1,"w")
file.write("hello")
print("I didnt")
file.close()
This is impossible in Python, but you can do something similar. Enter stage left, the DICTIONARY! A dictionary is like a list, but you set your own keys. Make it like this:
my_dict = {}
You can add to the dictionary like so:
my_dict["key"] = "value"
A way you could implement this into your code could be as follows:
the_dict = {}
with open ('lista1.txt','r') as file_1:
[...]
file = open(file_1,"r")
file_contents = file.readlines()
the_dict[search] = file_contents
print(str(file_contents) + "I actually tried")
[...]
When I run the code below I get this error message "EOFError: Ran out of input"
what does it mean?? How it can be corrected?? and how to output the records details on the screen.
import pickle # this library is required to create binary files
class CarRecord:
def __init__(self):
self.VehicleID = " "
self.Registration = " "
self.DateOfRegistration = " "
self.EngineSize = 0
self.PurchasePrice = 0.00
ThisCar = CarRecord()
Car = [ThisCar for i in range(2)] # list of 2 car records
Car[0].VehicleID = "CD333"
Car[0].Registration = "17888"
Car[0].DateOfRegistration = "18/2/2017"
Car[0].EngineSize = 2500
Car[0].PurchasePrice = 22000.00
Car[1].VehicleID = "AB123"
Car[1].Registration = "16988"
Car[1].DateOfRegistration = "19/2/2017"
Car[1].EngineSize = 2500
Car[1].PurchasePrice = 20000.00
CarFile = open ('Cars.TXT', 'wb' ) # open file for binary write
for j in range (2): # loop for each array element
pickle.dump (Car[j], CarFile) # write a whole record to the binary file
CarFile.close() # close file
CarFile = open ('Cars.TXT','rb') # open file for binary read
Car = [] # start with empty list
while True: #check for end of file
Car.append(pickle.load(CarFile)) # append record from file to end of list
CarFile.close()
Short answer: The simplest solution is to write the complete list to file using pickle.dump(). There's no need to write all objects one by one in a loop. Pickle is designed to do this for you.
Example code and alternative solutions:
Below is a fully working example. Some notes:
I've updated your __init__ function a bit to make the initialization code a lot easier and shorter.
I've also added a __repr__ function. This could be used to print the record details to screen, which you also asked. (Note that you could also implement a __str__ function, but I chose to implement __repr__ for this example).
This code example uses standard Python coding styles (PEP-8).
This code uses a context manager to open the file. This is safer and avoid the need to manually close the file.
If you really want to write the objects manually, for whatever reason, there are a few alternatives to do that safely. I'll explain them after this code example:
import pickle
class CarRecord:
def __init__(self, vehicle_id, registration, registration_date, engine_size, purchase_price):
self.vehicle_id = vehicle_id
self.registration = registration
self.registration_date = registration_date
self.engine_size = engine_size
self.purchase_price = purchase_price
def __repr__(self):
return "CarRecord(%r, %r, %r, %r, %r)" % (self.vehicle_id, self.registration,
self.registration_date, self.engine_size,
self.purchase_price)
def main():
cars = [
CarRecord("CD333", "17888", "18/2/2017", 2500, 22000.00),
CarRecord("AB123", "16988", "19/2/2017", 2500, 20000.00),
]
# Write cars to file.
with open('Cars.TXT', 'wb') as car_file:
pickle.dump(cars, car_file)
# Read cars from file.
with open('Cars.TXT', 'rb') as car_file:
cars = pickle.load(car_file)
# Print cars.
for car in cars:
print(car)
if __name__ == '__main__':
main()
Output:
CarRecord('CD333', '17888', '18/2/2017', 2500, 22000.0)
CarRecord('AB123', '16988', '19/2/2017', 2500, 20000.0)
Instead of dumping the list at once, you could also do it in a loop. The following code snippets are alternative implementations to "Write cars to file" and "Read cars from file".
Alternative 1: write number of objects to file
At the start of the file, write the number of cars. This can be used to read the same amount of cars from the file.
# Write cars to file.
with open('Cars.TXT', 'wb') as car_file:
pickle.dump(len(cars), car_file)
for car in cars:
pickle.dump(car, car_file)
# Read cars from file.
with open('Cars.TXT', 'rb') as car_file:
num_cars = pickle.load(car_file)
cars = [pickle.load(car_file) for _ in range(num_cars)]
Alternative 2: use an "end" marker
At the end of the file, write some recognizable value, for example None. When reading this object can be used to detect the end of file.
# Write cars to file.
with open('Cars.TXT', 'wb') as car_file:
for car in cars:
pickle.dump(car, car_file)
pickle.dump(None, car_file)
# Read cars from file.
with open('Cars.TXT', 'rb') as car_file:
cars = []
while True:
car = pickle.load(car_file)
if car is None:
break
cars.append(car)
You can change you while loop to this:
this will break out of your while loop at the end of the input when it recieves the EOFError
while True: #check for end of file
try:
Car.append(pickle.load(CarFile)) # append record from file to end of list
except EOFError:
break
CarFile.close()
You get that error when the file you are trying to load with pickle is empty.So make sure that there's things written into '.pkl file'
Ok so this snippet of code is a http response inside of a flask server. I dont think this information will be of any use but its there if you need to know it.
This Code is suppose to read in the name from the post request and write to a file.
Then it checks a file called saved.txt which is stored in the FILES dictionary.
If we do not find our filename in the saved.txt file we append the filename to the saved file.
APIResponce function is just a json dump
At the moment it doesn't seem to be appending at all. The file is written just fine but append doesn't go thru.
Also btw this is being run on Linino, which is just a distribution of Linux.
def post(self):
try:
## Create the filepath so we can use this for mutliple schedules
filename = request.form["name"] + ".txt"
path = "/mnt/sda1/arduino/www/"
filename_path = path + filename
#Get the data from the request
schedule = request.form["schedule"]
replacement_value = schedule
#write the schedule to the file
writefile(filename_path,replacement_value)
#append the file base name to the saved file
append = True
schedule_names = readfile(FILES['saved']).split(" ")
for item in schedule_names:
if item == filename:
append = False
if append:
append_to = FILES['saved']
filename_with_space =filename + " "
append(append_to,filename_with_space)
return APIResponse({
'success': "Successfully modified the mode."
})
except:
return APIResponse({
'error': "Failed to modify the mode"
})
Here are the requested functions
def writefile(filename, data):
#Opens a file.
sdwrite = open(filename, 'w')
#Writes to the file.
sdwrite.write(data)
#Close the file.
sdwrite.close()
return
def readfile(filename):
#Opens a file.
sdread = open(filename, 'r')
#Reads the file's contents.
blah = sdread.readline()
#Close the file.
sdread.close()
return blah
def append(filename,data):
## use mode a for appending
sdwrite = open(filename, 'a')
## append the data to the file
sdwrite.write(data)
sdwrite.close()
Could it be that the bool object append and the function name append are the same? When I tried it, Python complained with "TypeError: 'bool' object is not callable"
I created a notepad text document called "connections.txt". I need to have some initial information inside it, several lines of just URLs. Each URL has it's own line. I put that in manually. Then in my program I have a function that checks if a URL is in the file:
def checkfile(string):
datafile = file(f)
for line in datafile:
if string in line:
return True
return False
where f is declared at the beginning of the program:
f = "D:\connections.txt"
Then I tried to write to the document like this:
file = open(f, "w")
if checkfile(user) == False:
usernames.append(user)
file.write("\n")
file.write(user)
file.close()
but it hasn't really been working correctly..I'm not sure what's wrong..am I doing it wrong?
I want the information in the notepad document to stay there ACROSS runs of the program. I want it to build up.
Thanks.
EDIT: I found something wrong... It needs to be file = f, not datafile = file(f)
But the problem is... It clears the text document every time I rerun the program.
f = "D:\connections.txt"
usernames = []
def checkfile(string):
file = f
for line in file:
if string in line:
return True
print "True"
return False
print "False"
file = open(f, "w")
user = "aasdf"
if checkfile(user) == False:
usernames.append(user)
file.write("\n")
file.write(user)
file.close()
I was working with the file command incorrectly...here is the code that works.
f = "D:\connections.txt"
usernames = []
def checkfile(string):
datafile = file(f)
for line in datafile:
if string in line:
print "True"
return True
print "False"
return False
user = "asdf"
if checkfile(user) == False:
usernames.append(user)
with open(f, "a") as myfile:
myfile.write("\n")
myfile.write(user)
The code that checks for a specific URL is ok!
If the problem is not erasing everything:
To write to the document without erasing everything you have to use the .seek() method:
file = open("D:\connections.txt", "w")
# The .seek() method sets the cursor to the wanted position
# seek(offset, [whence]) where:
# offset = 2 is relative to the end of file
# read more here: http://docs.python.org/2/library/stdtypes.html?highlight=seek#file.seek
file.seek(2)
file.write("*The URL you want to write*")
Implemented on your code will be something like:
def checkfile(URL):
# your own function as it is...
if checkfile(URL) == False:
file = open("D:\connections.txt", "w")
file.seek(2)
file.write(URL)
file.close()
def fun(EACH) :
list1 = []
EACH = str(EACH)
for all in a: # contains names of different checks
for files in b :
for line in open(str(files)) :
if EACH in line :
print files
break
Here a is a directory which contains many files. I'm storing those files in list b.
I want to extract files with names in EACH
E.g. I want to open file which as a string "apple" in its content. this apple word is passed via arguments.
The problem is that I don't understand how to read that value and use the same string in the if condition.
Do you really have to parse each file line by line ? Couldn't you just do something like :
for b in a:
for fname in b:
with open(fname, "r") as f:
content = f.read()
if EACH in content:
print "There's a {0} in {1}".format(EACH, fname)
(the with open(...) as ... is to make sure your file is closed once you've read it...)
You can use the following code:
def grepFileForLines( self, fileName = "", keepLinesWith = "" ):
file = open( fileName, 'r' )
matches = []
for line in file:
if line.find( keepLinesWith ) > -1:
matches.append( line )
return matches