How to extract a variable from function in python 2.7 - python-2.7

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

Properly handling Escape Characters in Boto3

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.

Intellij file template: how to set file name dynamically

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?

why is the assignment of instance variables to local variables is need in crystal?

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.

Setting the name of a text file to a variable in qt

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).

Appending tuple to an empty list

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.