I've written some code in Python2.7.3 and at some point I want a certain variable produced inside a function to be extracted and used later in my program. I have assigned the global definition on the variable but still no luck. Here is the code:
def target_fileopen():
dirname = ' '
dlg = wx.FileDialog(None, "Select file", dirname, "", "*.txt", wx.OPEN)
if dlg.ShowModal() == wx.ID_OK:
filename = dlg.GetFilename()
dirname = dlg.GetDirectory()
coordfile = open(os.path.join(dirname, filename), 'r')
dlg.Destroy()
global path
path = str(dirname + "\\" + filename)
return target_calc(coordfile)
return(path)
print(path)
The error I get is that global name 'path' is not defined
This is just a sample, I don't really want to print the path in reality, just want it to place it as a static text in the GUI part of the application.
Any help would be really appreciated.
It's OK on my computer.
I can access the global variable which defined in the function.
Do you invoke the method before you access the variable?
Related
I have a S3 Bucket Streaming logs to a lambda function that tags files based on some logic.
While I have worked around this issue in the past and I understand there are some characters that need to be handled I'm wondering if there is a safe way to handle this with some API or is it something I need to handle on my own.
For example I have a lambda function like so:
import boto3
def lambda_handler(event, context):
s3 = boto3.client("s3")
for record in event["Records"]:
bucket = record["s3"]["bucket"]["name"]
objectName = record["s3"]["object"]["key"]
tags = []
if "Pizza" in objectName:
tags.append({"Key" : "Project", "Value" : "Great"})
if "Hamburger" in objectName:
tags.append({"Key" : "Project", "Value" : "Good"})
if "Liver" in objectName:
tags.append({"Key" : "Project", "Value" : "Yuck"})
s3.put_object_tagging(
Bucket=bucket,
Key=objectName,
Tagging={
"TagSet" : tags
}
)
return {
'statusCode': 200,
}
This code works great. I upload a file to s3 called Pizza-Is-Better-Than-Liver.txt then the function runs and tags the file with both Great and Yuck (sorry for the strained example).
However If I upload the file Pizza Is+AmazeBalls.txt things go sideways:
Looking at the event in CloudWatch the object key shows as: Pizza+Is%2BAmazeBalls.txt.
Obviously the space is escaped to a + and the + to a %2B when I pass that key to put_object_tagging() it fails with a NoSuchKey Error.
My question; is there a defined way to deal with escaped characters in boto3 or some other sdk, or do I just need to do it myself? I really don't and to add any modules to the function and I could just use do a contains / replace(), but it's odd I would get something back that I can't immediately use without some transformation.
I'm not uploading the files and can't mandate what they call things (i-have-tried-but-it-fails), if it's a valid Windows or Mac filename it should work (I get that is a whole other issue but I can deal with that).
EDIT:
So after some comments on the GitHub I should have been using urllib.parse.unquote_plus in this situation. this would be the proper way to solve escaping issues like this.
from urllib.parse import unquote_plus
print(unquote_plus("Pizza+Is%2BAmazeBalls.txt"))
# Pizza Is+AmazeBalls.txt
Original Answer:
Since no other answers I guess I post my bandaid:
def format_path(path):
path = path.replace("+", " ")
path = path.replace("%21", "!")
path = path.replace("%24", "$")
path = path.replace("%26", "&")
path = path.replace("%27", "'")
path = path.replace("%28", "(")
path = path.replace("%29", ")")
path = path.replace("%2B", "+")
path = path.replace("%40", "#")
path = path.replace("%3A", ":")
path = path.replace("%3B", ";")
path = path.replace("%2C", ",")
path = path.replace("%3D", "=")
path = path.replace("%3F", "?")
return path
I'm sure there is a simpler, more complete way to do this but this seems to work... for now.
I'm making a intellij template MyClassController but I want to insert just MyClass as name because I need to create thousands with same pattern.
I tried
package ...
#set($BASENAME = $NAME)
#set($NAME=${BASENAME} + "Controller")
#set($OBJNAME = $BASENAME.substring(0, 1).toLowerCase() + $BASENAME.substring(1))
import ...
but if #set($NAME= ... ) is present filename popup is not showing.
BASENAME's value (that is "") became NAME's value so my file end being named "$BASENAME" or "$".
There's a way to force name popup to appear or rename file after file is generated?
In Crystal compiler source code I've seen such code
def dirname
filename = #filename
if filename.is_a?(String)
File.dirname(filename)
else
nil
end
end
def original_filename
case filename = #filename
when String
filename
when VirtualFile
filename.expanded_location.try &.original_filename
else
nil
end
end
def <=>(other)
self_file = #filename
other_file = other.filename
if self_file.is_a?(String) && other_file.is_a?(String) && self_file == other_file
{#line_number, #column_number} <=> {other.line_number, other.column_number}
else
nil
end
end
So, what the reason to assign an instance variable to a local variable instead of using instance variable directly?
Because #filename may be changed concurrently between the time we check if it's not nil (if #filename) and the time we access it. Crystal being a compiled program, would #filename not be the type it's expected to be, then the program would crash with a segfault.
By assigning to a local variable, we make sure the variable does exists.
I'm exporting data to a text file in qt every time a run a code. With my current code that file is overwritten each time. My question is how can I set the title to be a variable eg pulse_freq, this way new files will be created based on my variable values. I just can't get the syntax right.
Is there a way to put my files in a folder in the same directory as my build files? I need my code to be cross platform and if I use the full path name it's apparently incompatible with any non-windows OS. If I just name the files there'd be too much clutter in the folder. Relevant code is below:
// Export to data file
QString newname = QString::number(variables.nr_pulses);
QString filename = "C:/Users/BIC User/Documents/BIC Placement Documents/QT_data/Data.txt";
QFile file( filename );
You can just use something along lines:
QString s1 = "something";
QString s2 = " else";
QString s3 = s1 + s2;
QString concatenation with overloaded operator+ works like charm.
And about referencing folder you're in, instead of hardcoding its path, use QDir::currentPath()
Thus, your filename creation should look like the following:
QString folder = QDir::currentPath();
QString file = QString::number(variables.nr_pulses); //or whatever else you want it to be
QString extension = ".txt" // or whatever extension you want it to be
QString full_filename = folder + file + extension;
In order not to mess with appending string after the extension, just separate it into another QString and concatenate those 3 elements as above (folder + file + extension).
if __name__ == '__main__':
website_path = GetValidDirectory("Enter the path to the website : ")
websitelink_list = [] #List of tuples containing the source link information
print(websitelink_list)
htmlfiles = [] #List of the html files we analyze on the site
for dirname, subdir_list, file_list in os.walk(website_path):
for file in file_list:
#Check the file extension. Only analyze files that are .html
filename, fileext = os.path.splitext(file)
if fileext == ".html":
relative_file = MakeFullPath(dirname, file)
full_file = os.path.realpath(relative_file)
htmlfiles.append( (full_file, relative_file) )
filelinks = FileLinkTuples(dirname, file)
print(filelinks)
websitelink_list.extend(filelinks)
#Files that do not have a link to them.
functions:
def GetValidDirectory(prompt : str) -> str:
""" Returns a valid directory entered from the user.
Arguments :
prompt : str - The text displayed to the user asking them to enter a directory.
Returns : String of a valid directory that the user entered.
Errors : Displays a warning if the user does not enter a valid directory.
"""
while True:
try:
str_prompt = input(prompt)
prompt_dir = os.path.realpath(str_prompt)
ch_dir = os.chdir(str_prompt)
except IOError:
print("Please enter a valid directory")
continue
return prompt_dir
def MakeFullPath(path : str, filename : str) -> str:
""" combines path and filename for a full filename. If path does not end in \\ then it appends it
Arguments :
path : str, the path to the file
filename : str, the name of the file.
Returns :
path concatenated with filename.
If path does not end with a backslash, then append one if path has data in it.
"""
no_data = []
if os.listdir(path) != no_data:
relative_file = os.path.join(path,filename)
return relative_file
def FileLinkTuples(path : str, filename : str) -> list:
"""Returns a tuple of links from the file
Arguments :
path : str - The path to the filename. Might be relative path.
filename : str - The name of the html file to open and analyze.
Returns : list of tuples.
Each tuple has the 4 values.
HTMLFile - HTML file and path to the source file the link was found in.
fulllinkpath - Full path to the link on the system. Not a relative path.
linkpath - Path and name to the link specified. Relative address.
file exists - Boolean indicating if the file at the full link path exists.
Example
[ (('sample\\index.html', 'C:\\Website Analysis\\downloads.html', 'downloads.html', True)
]
"""
filelink_list = []
a = path.split('\\')
b = os.path.join(a[-1],filename)
c = os.path.realpath(filename)
if os.path.isfile(filename) == "True":
filelink_list.append((b,c,filename,"True"))
return filelink_list
Can someone please analyze my codes and tell me why the typles of (full_file,relative_file) and filelinks are not appending to the empty lists in the main program?
For this assignment, i was given a Unittest. The functions passed the test, but i don't know why the lists in the main program are not updating?
When i print the websitelink_list and htmlfiles, they are both empty.
What am i doing wrong with the def FileLinkTuples? particularly the
if os.path.isfile(filename) == "True":
filelink_list.append((b,c,filename,"True"))
Thanks
As far as I can tell, your code does produce nonempty results for htmlfiles at least. The main problem that I see is this:
if os.path.isfile(filename) == "True":
The function returns a Boolean, not a string, so you should check against the Boolean value True, or even omit it altogether:
if os.path.isfile(filename):
After fixing that, you should expect something in websitelink_list as well, provided your directory does in fact contain *.html files.
Now, if you are not seeing anything in htmlfiles at all (even if the directory does contain *.html files) then it must be something else that you're not showing here, since it appears to work correctly on my computer.