I have a pretty simple script running, it works in one folder but doesnt work in the other. Have been going at this for a couple hours ):. Permissions for both files are the same, script is the same, nothing python side. Seems very technical. I have tried allowing full control to the files I am attempting to interact with and the duplicated python script aswell. I tested the duplicate script in C:/ and Program Files (x86) with no resolution. The script only seems to work from one folder. Nothing is different from both scripts.
Script I am attempting to copy into a new folder and use:
import os
import sys
import shutil
def parse(p):
q = p
return q
#per line in textbox, create element in list
zz = ((parse(sys.argv[1]).replace("'", "")).split("\n"))
zz = list(filter(("").__ne__, zz))
last_element = zz[-1:]
last_element = (last_element[0]).split("[[")
zz = zz[:-1]
zz.append(last_element[0])
last_element = last_element[1]
if last_element == "product_url.txt":
os.chdir(r"C:\Cactus (2022)\supported_websites\XXX")
else:
os.chdir(r'C:\Program Files (x86)\Cactus (2022)\supported_websites\XXX\XXX')
a_file = open('%s' % last_element, "w")
for x in zz:
if x == "":
pass
else:
a_file.write("%s\n" % x)
Calling from C#:
MessageBox.Show(richTextBox4.Text);
panel1.Visible = false;
string task_information;
task_information = richTextBox4.Text + #"[[product_url.txt";
ProcessStartInfo rtInfo = new ProcessStartInfo(#"C://Program Files (x86)//Cactus (2022)//repo//python.exe");
rtInfo.FileName = "C://Program Files (x86)//Cactus (2022)//repo//python.exe";
rtInfo.Arguments = "C://Cactus (2022)//modifytextfilelines.py '" + task_information + "'";
rtInfo.UseShellExecute = false;
rtInfo.CreateNoWindow = true;
Process.Start(rtInfo);
Only way it works:
MessageBox.Show(richTextBox4.Text);
panel1.Visible = false;
string task_information;
task_information = richTextBox4.Text + #"[[product_url.txt";
ProcessStartInfo rtInfo = new ProcessStartInfo(#"C://Program Files (x86)//Cactus (2022)//repo//python.exe");
rtInfo.FileName = "C://Program Files (x86)//Cactus (2022)//repo//python.exe";
rtInfo.Arguments = "C://Cogs//modifytextfilelines.py '" + task_information + "'";
rtInfo.UseShellExecute = false;
rtInfo.CreateNoWindow = true;
Process.Start(rtInfo);
Let me emphasize, the script is exactly the same, copy and pasted from my "Cogs" folder. It doesnt work at all if I attempt to copy and paste it to a new folder and modify my Arguments line to that directory for C#.
Edit:
Did more testing, seems it is the space in "Cactus (2022)", I replaced the folder name with XXX in the pasted code below... I copy and pasted my Cogs folder into C:/ and it worked fine, I renamed it to "REPO", I changed this to "RE PO" and it stopped working. So a syntax error is the issue underneath arguments.
Related
Is there a cleaner, shorter, perhaps more elegant or Pythonic way to do this?
Unique constraint: The same code has to work on both Python 3.x and MicroPython. This means that a lot of the nice tools available in Python 3.x cannot be used. Hence the "back to basics" feel to the code.
It attempts to clean-up some malformed input. That's not super important. Also, yes, it has to behave on both Windows and Linux. I tested on Windows and MicroPython on an RP2040 processor (RaspberryPi Pico). Works fine.
Warning: If you run this code on your system it will create over twenty directories. Make sure you run it on a junk directory.
import os
def create_path(path:str) -> str:
"""Given a path with a file name, create any missing directories
Does NOT create files.
:param path: "some/subdirectory/file.txt"
:return: The new full path, ready to open the file
"""
result = os.getcwd()
# Cleaning up an leading and multiple slashes
while "//" in path:
path = path.replace("//", "/")
if len(path) > 0:
path = path if path[0] != "/" else path[1:]
elements = path.split("/")
for element in elements:
if element == "":
break
else:
result += "/" + element
if "." in element:
break # It's a file; we are done
else:
# It's a directory, does it exist?
try:
os.listdir(result)
except:
# It does not, create it
os.mkdir(result)
# This is necessary to remove a leading double slash
# when used in MicroPython
return result.replace("//", "/")
if __name__ == "__main__":
# Tests
# WARNING: This will create over twenty directories!
# Does not create the file, just the path
print(create_path("/"))
print(create_path("//"))
print(create_path("///"))
print(create_path("file_01.txt"))
print(create_path("/file_02.txt"))
print(create_path("//file_03.txt"))
print(create_path("///file_04.txt"))
print(create_path("dir_00"))
print(create_path("/dir_01"))
print(create_path("//dir_02"))
print(create_path("dir_03/"))
print(create_path("dir_04//"))
print(create_path("dir_05///"))
print(create_path("/dir_06"))
print(create_path("/dir_07/"))
print(create_path("//dir_08/"))
print(create_path("//dir_09//"))
print(create_path("dir_10/file_05.txt"))
print(create_path("/dir_11/file_06.txt"))
print(create_path("//dir_12/file_07.txt"))
print(create_path("//dir_13//file_08.txt"))
print(create_path("//dir_14//file_09.txt/"))
print(create_path("//dir_15//file_10.txt//"))
print(create_path("dir_16/dir_116/file_11.txt"))
print(create_path("/dir_17/dir_117/file_12.txt"))
print(create_path("//dir_18/dir_118/file_13.txt"))
print(create_path("//dir_19///dir_119/file_14.txt"))
print(create_path("//dir_20///dir_120///file_15.txt"))
print(create_path("//dir_21//dir_121//file_16.txt/"))
print(create_path("//dir_22//dir_122//file_17.txt/"))
I have several functions/methods in a class that are kind of connected. I am building a class that mimics terminal commands and links. However, someone told me this is not proper OOP. How can I separate these methods to work independently. Methods shouldn't call other methods. Correct?
class directory:
#FILES, LINKS AND DIRECTORIES
current_path = []
hold_files = [
'test1.txt', 'test2.py',
{'/desktop': ['computer.txt','tfile.doc',
{'/peace':{
'/pictures': [
'hello.gif',
'smile.gif',
'run.gif'
]},
'/work':[
'file1.txt',
'file2.txt'
]
}]
}
]
#recursively delete folder (if dot in)
def delete(itself):
#if dictionary, call self, else delete
del itself
return
## HELPER METHODS
# Join list together to produce new link, basically return the added folder to the link
def concatenate(self):
new_link ="".join(current_path)
return new_link
#strip slashes and place in list
def adjust_link(self, paths):
new_string = ""
# shorten link, if someone uses cd .., basically go back to previous folder
if paths == "cd ..":
current_path.pop()
#extend link, if someone is cding into another folder, remove /'s and append to separate list
elif "cd " in paths:
paths = paths[3:]
for slash in paths:
if slash == "/":
current.append(new_string)
new_string = ""
else:
new_string+=slash
# This shouldn't be here as OOP must be separated but this calls the other function to concatenate a new link
stripped = concatenate()
return stripped
#returns link
def link(self, paths):
address_location = adjust_link(paths)
return address_location
directory.link("cd desktop/peace")
directory.link("cd pictures")
directory.link("cd ..")
directory.delete()
Thank you.
*Also, this is not a refactoring question. I already asked on stack exchange code review and they told me to come here. Code does not work.
Edit 2: why won't "directory.link()" work?
"I have a program here and I want to convert it to OOP" is not usually how it's done: "I have a problem I want to solve using OOP" is usually the approach. It looks like you are creating something that will traverse an internal directory structure. So a skeleton might look like:
class DirectoryTraverser:
def __init__(self, directory_tree):
self.hold_files = directory_tree
self.current_path = []
def... # all your other functions
# then to use it might look like:
# create a directory traversal object with directory tree
dt = DirectoryTraverser(hold_files)
dt.link("cd desktop/peace")
dt.link("cd pictures")
dt.link("cd ..")
dt.delete()
Well I am calling a VBScript inside a python code. I get error "ActiveX component can't create object"
But it is fine When I call Seperate (When I double click that or run using cmd).
This is part of python code. I tried csript, wscript. changed the path to system32 / SYSVOW64.. But nothing is working
for i in range(printInput):
print("range")
print(i)
os.system(r"C:\Windows\system32\cmd.exe /k c:\windows\SysWOW64\cscript.exe C:\Users\muneeb.kalathil\PycharmProjects\moodledownload\vcconverter\labelprint\new.vbs")
#subprocess.call("run.bat")
And this is VBSscript
'<SCRIPT LANGUAGE="VBScript">
' Data Folder
Const sDataFolder = "C:\Users\muneeb.kalathil\PycharmProjects\moodledownload\vcconverter\labelprint\"
DoPrint(sDataFolder & "label.lbx")
'*******************************************************************
' Print Module
'*******************************************************************
Sub DoPrint(strFilePath)
Set ObjDoc = CreateObject("bpac.Document")
bRet = ObjDoc.Open(strFilePath)
If (bRet <> False) Then
ObjDoc.GetObject("AssetName").Text = "text"
ObjDoc.GetObject("AssetTag").Text = "text"
ObjDoc.GetObject("company").Text = "text"
Call ObjDoc.SetBarcodeData(ObjDoc.GetBarcodeIndex("QR"), "link")
' ObjDoc.SetMediaByName ObjDoc.Printer.GetMediaName(), True
ObjDoc.StartPrint "", 0
ObjDoc.PrintOut 1, 0
ObjDoc.EndPrint
ObjDoc.Close
End If
Set ObjDoc = Nothing
End Sub
It shows the error in
Set ObjDoc = CreateObject("bpac.Document")
So after lot of tries, I converted vbscript to exe file and then executed. Now it is working.
os.system("run.exe")
I have used this software as some converters are not really converting to exe. This software has some limitations. But works well for me.
https://www.battoexeconverter.com/
I needed to find a free drive letter on windows from a python script. Free stands for not assigned to any physically or remote device.
I did some research and found a solution here on stackoverflow (cant remember the exact link):
# for python 2.7
import string
import win32api
def getfreedriveletter():
""" Find first free drive letter """
assigneddrives = win32api.GetLogicalDriveStrings().split('\000')[:-1]
assigneddrives = [item.rstrip(':\\').lower() for item in assigneddrives]
for driveletter in list(string.ascii_lowercase[2:]):
if not driveletter in assigneddrives:
return driveletter.upper() + ':'
This works fine for all physically drives and connected network drives. But not for currently disconnected drives.
How can I get all used drive letter, also the temporary not used ones?
Creating a child process is relatively expensive, and parsing free-form text output isn't the most reliable technique. You can instead use PyWin32 to call the same API functions that net use calls.
import string
import win32api
import win32wnet
import win32netcon
def get_free_drive():
drives = set(string.ascii_uppercase[2:])
for d in win32api.GetLogicalDriveStrings().split(':\\\x00'):
drives.discard(d)
# Discard persistent network drives, even if not connected.
henum = win32wnet.WNetOpenEnum(win32netcon.RESOURCE_REMEMBERED,
win32netcon.RESOURCETYPE_DISK, 0, None)
while True:
result = win32wnet.WNetEnumResource(henum)
if not result:
break
for r in result:
if len(r.lpLocalName) == 2 and r.lpLocalName[1] == ':':
drives.discard(r.lpLocalName[0])
if drives:
return sorted(drives)[-1] + ':'
Note that this function returns the last available drive letter. It's a common practice to assign mapped and substitute drives (e.g. from net.exe and subst.exe) from the end of the list and local system drives from the beginning.
As i will pass the found letter to an external script which will run the Winshell cmd 'subst /d letter'. I must not pass a currently not mounted drive, as it will remove the network-drive mapping.
The only way I found, was the result of the winshellcmd 'net use' to find unavailable drives.
Here is my solution, if you have a better way, please share it with me:
# for python 2.7
import string
import win32api
from subprocess import Popen, PIPE
def _getnetdrives():
""" As _getfreedriveletter can not find unconnected network drives
get these drives with shell cmd 'net use' """
callstr = 'net use'
phandle = Popen(callstr, stdout=PIPE)
presult = phandle.communicate()
stdout = presult[0]
# _stderr = presult[1]
networkdriveletters = []
for line in stdout.split('\n'):
if ': ' in line:
networkdriveletters.append(line.split()[1] + '\\')
return networkdriveletters
def getfreedriveletter():
""" Find first free drive letter """
assigneddrives = win32api.GetLogicalDriveStrings().split('\000')[:-1]
assigneddrives = assigneddrives + _getnetdrives()
assigneddrives = [item.rstrip(':\\').lower() for item in assigneddrives]
for driveletter in list(string.ascii_lowercase[2:]): #array starts from 'c' as i dont want a and b drive
if not driveletter in assigneddrives:
return driveletter.upper() + ':'
I ran a spark job that culminated in saving a Parquet file, and the job completed successfully. However, I only specified the name of the file, and did not specify the HDFS path. Is there a way to print out the default HDFS path that spark wrote the file to? I looked at sc._conf.getAll(), but there doesn't seem to be anything useful there.
AFAIK this is one of the way (apart from simple command way is hadoop fs -ls -R | grep -i yourfile)....
Below is example scala code snippet.... (if you want to do it in python or java you can emulate the same api calls)
To get list of parquet files. and filter them like below....
import org.apache.hadoop.conf.Configuration
import org.apache.hadoop.fs.{FileStatus, FileSystem, Path}
import org.apache.hadoop.io.{BytesWritable, Text}
import org.apache.spark.{SparkConf, SparkContext}
//other imports here
lazy val sparkConf = new SparkConf()
lazy val sc = SparkContext.getOrCreate(sparkConf)
lazy val fileSystem = FileSystem.get(sc.hadoopConfiguration)
val fileSystem = listChaildStatuses(fileSystem , new Path("yourbasepathofHDFS")) // normally hdfs://server/user like this...
val allparquet = fileSystem.filter(_.getPath.getName.endsWith(".parquet"))
// now you can print these parquet files out of which your files will be present and you can know the base path...
Support methods are like below
/**
* Get [[org.apache.hadoop.fs.FileStatus]] objects for all Chaild children (files) under the given base path. If the
* given path points to a file, return a single-element collection containing [[org.apache.hadoop.fs.FileStatus]] of
* that file.
*/
def listChaildStatuses(fs: FileSystem, basePath: Path): Seq[FileStatus] = {
listChaildStatuses(fs, fs.getFileStatus(basePath))
}
/**
* Get [[FileStatus]] objects for all Chaild children (files) under the given base path. If the
* given path points to a file, return a single-element collection containing [[FileStatus]] of
* that file.
*/
def listChaildStatuses(fs: FileSystem, baseStatus: FileStatus): Seq[FileStatus] = {
def recurse(status: FileStatus): Seq[FileStatus] = {
val (directories, leaves) = fs.listStatus(status.getPath).partition(_.isDirectory)
leaves ++ directories.flatMap(f => listChaildStatuses(fs, f))
}
if (baseStatus.isDirectory) recurse(baseStatus) else Seq(baseStatus)
}