How to make a path where the files will be created in? - python

I made a program that would create new text files every second but how can I make a path when those text files would be created in? (Example: Desktop)
Here is my code:
from time import sleep
import string
import random
def getR():
p = ""
for _ in range(0, 10):
p += random.choice(string.ascii_letters)
return p
getR()
n = input("Are you sure you want to start this program?. \n")
if n == "yes":
if __name__ == "__main__":
while True:
f = open("{}.txt".format(getR()), "w+")
f.close()
sleep (1)
else:
print("Closing the file...")

This does what you ask, although why you want to create an infinite number of randomly named empty files on your desktop is beyond me.
import os
from time import sleep
import string
import random
def getR():
return ''.join(random.choice(string.ascii_letters) for _ in range(10)
if __name__ == "__main__":
desktop = os.environ['USERPROFILE'] + "/Desktop/"
while True:
f = open(desktop + "{}.txt".format(getR()), "w+")
f.close()
sleep (1)

To change the working directory use os.chdir:
import os
os.chdir(PATH)
Or you can specify the path directly on open:
file = os.path.join(PATH, FILENAME)
f = open(file, 'w+')

Related

Why do these buttons open the same file regardless of which on I select?

I'm making a pdf 'date checker' in Python which tells me if every page of the pdf has tomorrows date at the top (for checking newspapers as part of my job).
So far so good until I attempted to put it all into a GUI, the buttons display the correct filename, but only open and check the last file in he list the buttons were generated from 'Files[i]'.
Can anybody figure out from my horrible nooby code why this is happening? please excuse the mess (I'm new) :)
Here is my ugly code :) I think the issue is either where I open the file using
'with open(files[i])' or 3rd line from the bottom where the buttons are created.
Any help would be greatly appreciated, thank you.
import os, glob
import fileinput
import tkinter as tk
import dateutil
import datetime
from dateutil.relativedelta import *
from dateutil.easter import *
from dateutil.parser import *
from dateutil.rrule import *
import PyPDF2
from PyPDF2 import PdfReader
from datetime import datetime, timedelta
from tkinter import *
folder_path = 'C:users/axlra/documents/datechecker'
for filename in glob.glob(os.path.join(folder_path, '*.pdf')):
with open(files[i], 'r') as f:
text = f.read()
print (files[i])
print (len(text))
def checknow():
tomorrow = (datetime.now() + timedelta(days=1)).strftime("%d-%m-%Y")
file = open(files[i], 'rb')
reader = PdfReader(files[i])
total = len(reader.pages)
for x in range(total+1):
if x > total: file.close()
page = reader.pages[0]
found = False
text = (page.extract_text())
parts = []
def visitor_body(text, cm, tm, fontDict, fontSize):
y = tm[5]
if y > 1600 and y < 10000:
parts.append(text)
page.extract_text(visitor_text=visitor_body)
text_body = "".join(parts)
#print(text_body)
word = text_body
word=word[22:-1]
#print(word)
prodate = parse(word)
str_date = prodate.strftime("%d-%m-%Y")
print(str_date)
print(files[i])
if tomorrow in str_date:
found = True
if found:
#print(x)
print("Tomorrow's date was found on page"+ " "+str(x))
else:
#print(x)
print("Tomorrow's date was NOT found on page"+ " "+str(x))
location = os.getcwd() # get present working directory location here
counter = 0 #keep a count of all files found
files = [] #list to store all pdf files found at location
for file in os.listdir(location):
try:
if file.endswith(".pdf"):
print ("pdf file found:\t", file)
files.append(str(file))
counter = counter
except Exception as e:
raise e
print ("No files found here!")
root = Tk()
btn = [] #creates list to store the buttons ins
for i in range(counter): #this just popultes a list as a replacement for the actual inputs for troubleshooting purposes
files.append(str(i))
for i in range(len(files)): #this says for *counter* in *however many elements there are in the list files*
#the below line creates a button and stores it in an array we can call later, it will print the value of it's own text by referencing itself from the list that the buttons are stored in
btn.append(Button(root, text=files[i], command=checknow))
btn[i].pack() #this packs the buttons
root.mainloop()
Based off the given solutions, this is the working code, the solution was to completely get rid of the 'i list' and just use file_path:
import os
import tkinter as tk
from tkinter import messagebox
import os, glob
import fileinput
import tkinter as tk
import dateutil
import datetime
from dateutil.relativedelta import *
from dateutil.easter import *
from dateutil.parser import *
from dateutil.rrule import *
import PyPDF2
from PyPDF2 import PdfReader
from datetime import datetime, timedelta
from tkinter import *
import re
location = os.getcwd()
counter = 0
files = []
for file in os.listdir(location):
try:
if file.endswith(".pdf"):
print ("pdf file found:\t", file)
files.append(str(file))
counter = counter
except Exception as e:
raise e
print ("No files found here!")
tomorrow = (datetime.now() + timedelta(days=-1)).strftime("%A,%B%e")
tomorrow = tomorrow.replace(" ", "")
tomorrow2 = (datetime.now() + timedelta(days=-1)).strftime("%d.%m.%Y")
tomorrow2 = tomorrow.replace(" ", "")
tomorrow3 = (datetime.now() + timedelta(days=-1)).strftime("%A%e%B%Y")
tomorrow3 = tomorrow.replace(" ", "")
tomorrow4 = (datetime.now() + timedelta(days=-1)).strftime("%A,%B%e")
tomorrow4 = tomorrow.replace(" ", "")
tomorrow5 = (datetime.now() + timedelta(days=-1)).strftime("%A,%e%B")
tomorrow5 = tomorrow.replace(" ", "")
def open_pdf(file_path):
file = open(file_path, 'rb')
reader = PdfReader(file)
total = len(reader.pages)
for x in range(total):
if x > x: file.close()
page = reader.pages[x]
text = (page.extract_text())
text = text.replace(" ", "")
#print(text)
substring = tomorrow
first_index = text.find(substring)
if first_index != -1:
second_index = text.find(substring, first_index + len(substring))
if second_index != -1:
print("Tomorrows date "+ tomorrow+ " appears twice on page"+ " "+str(x).format(substring))
else:
print("Tomorrows date "+ tomorrow+ " appears only once on page"+ " "+str(x)+" -".format(substring))
else:
print("Tomorrows date "+ tomorrow+ " does not appear on page"+ " "+str(x)+" ---".format(substring))
def create_buttons(directory):
for filename in os.listdir(directory):
if filename.endswith(".pdf"):
file_path = os.path.join(directory, filename)
button = tk.Button(root, text=filename, command=lambda f=file_path: open_pdf(f))
button.pack()
root = tk.Tk()
create_buttons(os.getcwd())
root.mainloop()
The basic answer is that at the end of for i in range(len(files)) the i does not get dereference like it does in some languages. A simple test to do is that this will give you an i of 2.
for i in range(3):
pass
print(i)
So when you call checknow() the referenced file would be the last file in files since your i doesn't change after the loop.
Something I've done in the past is create a class encompassing it so that each one holds to their own references. I did it without subclassing the tkinter class, but you could. A sample for an idea of what I did is
class FileButton:
def checknow(self):
file_name = self._file_name
#as an example of how you can reference the file_name.
#you can also do this by doing self._button.cget("text") and not have to store file_name
pass
def __init__(self, root, file_name):
self._root = root
self._file_name = file_name
self._button = tkinter.Button(root, text=file_name, command=self.checknow)
self._button.pack()
for i in range(len(files)):
btn.append(FileButton(root, files[i]))
I haven't tested this particular code, and my previous uses were more for labels and entries, but the principle of it was the same and I can confirm that using the callback in this manner worked. Also, if you don't need to reference the buttons anymore you don't have to append them to the btn list either.

How do I check file modified in python as a boolean, so I can implement in IF Statement?

Im trying to create a function where if file modified, then perform task. I am able to do this if a file exists by doing -
import os
file_path = 'C:/Hi/'
if os.listdir(file_path):
do xyz
But how can i do xyz based on if a files date was modified?
os.path.getmtime(file_path)
Only gets the time but cant be used in my if statement
Try:
import os
import time
no_of_seconds_since_last_check = 30
if time.time() - os.path.getmtime(file_path) < no_of_seconds_since_last_check :
print("doing xyz")
The if condition detects a file modification within the specified time span, preferably since the last check for modifications.
Try This Maybe This You want:
import os
from time import sleep
folder_path = r'C:/Hi/'
def check_if_modifed(files : list , data):
while True:
sleep(2)
for file in files:
last_modifed = os.path.getatime(file)
if last_modifed != data[file]:
print(f'{file} Modfied !')
data[file] = last_modifed
if os.listdir(folder_path):
files = os.listdir(folder_path)
current_data = {}
for file in files:
current_data [file] = os.path.getatime(file)
try:
check_if_modifed(files , current_data)
except:
print('Program Finish!')

Looping through folders and comparing files using win32

Looking to use win32 to compare multiple word docs. The naming convention is the same except the modified doc has test.docx added to the file name. The below is the code i have but it is coming up with "pywintypes.com_error: (-2147023170, 'The remote procedure call failed.', None, None)". Any ideas on how i can get this to work? I have around 200docs to compare so python seems to be the way to do it.
import win32com.client
from docx import Document
import os
def get_docx_list(dir_path):
'''
:param dir_path:
:return: List of docx files in the current directory
'''
file_list = []
for path,dir,files in os.walk(dir_path):
for file in files:
if file.endswith("docx") == True and str(file[0]) != "~": #Locate the docx document and exclude temporary files
file_root = path+"\\"+file
file_list.append(file_root)
print("The directory found a total of {0} related files!".format(len(file_list)))
return file_list
def main():
modified_path = r"C:\...\Replaced\SWI\\"
original_path = r"C:\...\Replaced\SWI original\\"
for i, file in enumerate(get_docx_list(modified_path), start=1):
print(f"{i}、Files in progress:{file}")
for i, files in enumerate(get_docx_list(original_path), start=1):
Application = win32com.client.gencache.EnsureDispatch("Word.Application")
Application.CompareDocuments(
Application.Documents.Open(modified_path + file),
Application.Documents.Open(str(original_path) + files))
Application.ActiveDocument.SaveAs(FileName=modified_path + files + "Comparison.docx")
Application.Quit()
if __name__ == '__main__':
main()
For anyone chasing the solution to do bulk word comparisons below is the code I successfully ran through a few hundred docs. Delete the print statements once you have the naming convention sorted.
import win32com.client
import os
def main():
#path directories
modified_path = r"C:\Users\Admin\Desktop\Replaced\SOP- Plant and Equipment\\"
original_path = r"C:\Users\Admin\Desktop\Replaced\SOP - Plant and Equipment Original\\"
save_path = r"C:\Users\Admin\Desktop\Replaced\TEST\\"
file_list1 = os.listdir(r"C:\Users\Admin\Desktop\Replaced\SOP- Plant and Equipment\\")
file_list2 = os.listdir(r"C:\Users\Admin\Desktop\Replaced\SOP - Plant and Equipment Original\\")
#text counter
Number = 0
#loop through files and compare
for file in file_list1:
for files in file_list2:
#if files match do comparision, naming convention to be changed
if files[:-5] + " test.docx" == file:
Number += 1
print(f"The program has completed {Number} of a total of {len(file_list1)} related files!")
try:
Application = win32com.client.gencache.EnsureDispatch("Word.Application")
Application.CompareDocuments(
Application.Documents.Open(modified_path + file),
Application.Documents.Open(str(original_path) + files))
Application.ActiveDocument.ActiveWindow.View.Type = 3
Application.ActiveDocument.SaveAs(FileName=save_path + files[:-5] + " Comparison.docx")
except:
Application.Quit()
pass
if __name__ == '__main__':
main()

How can I clasify files based on their extension in Python?

I want to move files into folders based on their extensions and categorize them.
I've tried shutil.move() to categorize it. But it gives an error like this:
shutil.Error: Cannot move a directory 'C:\Users\user\Desktop\deneme' into itself 'None'.
How can i fix the problem?
My code:
import os
from os import path
import pathlib
import shutil
path_ = input("Directory: ")
file_list = os.listdir(path_)
os.chdir(path_)
current_directory = os.getcwd()
e = []
a = 0
for i in file_list:
ext = os.path.splitext(i)[1][1:]
e.append(ext)
# print("Ext:", ext)
for j in range(len(e)):
if e[j] == ",":
j = j + 1
continue
os.mkdir(str(j))
os.rename(str(j), e[j])
new_folder = e[j]
for f in os.listdir(current_directory):
new_directory = os.chdir(new_folder)
if f == ",":
f +=1
continue
shutil.move(os.path.join(current_directory), str(new_directory))
#print("it is moved")
print(os.path.dirname(os.path.abspath(str(e[j]))))
Try os.path.splitext()[1] (it returns a list. The 0th element is the filename and the 1st is the extension) if you want to find the file extension

Run file inside a zipfile?

Is it possible to run a .html or .exe for example, that is inside a zipfile? I'm using the Zipfile module.
Here's my sample code:
import zipfile
z = zipfile.ZipFile("c:\\test\\test.zip", "r")
x = ""
g = ""
for filename in z.namelist():
#print filename
y = len(filename)
x = str(filename)[y - 5:]
if x == ".html":
g = filename
f = z.open(g)
After f = z.open(g), I don't know what to do next. I tried using the .read() but it only reads whats inside of the html, what I need is for it to run or execute.
Or is there any othere similar ways to do this?
The best approach will be to extract the required file to the Windows temp directory and execute it. I have modified your original code to create a temp file and execute it:
import zipfile
import shutil
import os
z = zipfile.ZipFile("c:\\test\\test.zip", "r")
x = ""
g = ""
basename = ""
for filename in z.namelist():
print filename
y = len(filename)
x = str(filename)[y - 5:]
if x == ".html":
basename = os.path.basename(filename) #get the file name and extension from the return path
g = filename
print basename
break #found what was needed, no need to run the loop again
f = z.open(g)
temp = os.path.join(os.environ['temp'], basename) #create temp file name
tempfile = open(temp, "wb")
shutil.copyfileobj(f, tempfile) #copy unzipped file to Windows 'temp' folder
tempfile.close()
f.close()
os.system(temp) #run the file
Run the first .html file in a zip archive specified at the command line:
#!/usr/bin/env python
import os
import shutil
import sys
import tempfile
import webbrowser
import zipfile
from subprocess import check_call
from threading import Timer
with zipfile.ZipFile(sys.argv[1], 'r') as z:
# find the first html file in the archive
member = next(m for m in z.infolist() if m.filename.endswith('.html'))
# create temporary directory to extract the file to
tmpdir = tempfile.mkdtemp()
# remove tmpdir in 5 minutes
t = Timer(300, shutil.rmtree, args=[tmpdir], kwargs=dict(ignore_errors=True))
t.start()
# extract the file
z.extract(member, path=tmpdir)
filename = os.path.join(tmpdir, member.filename)
# run the file
if filename.endswith('.exe'):
check_call([filename]) # run as a program; wait it to complete
else: # open document using default browser
webbrowser.open_new_tab(filename) #NOTE: returns immediately
Example
T:\> open-from-zip.py file.zip
As an alternative to webbrowser you could use os.startfile(os.path.normpath(filename)) on Windows.

Categories

Resources