Python Script to search for a file - python

i was going through one of the python scripts that Searches for Files and lists their permissions. Im still a learner in python, and while studying this code, i encountered the following questions:
In the lines below, what is the implication of the line "mode=stat.SIMODE(os.lstat(file)[stat.ST_MODE])" ?
what is the value returned to "mode" ? and how does it function in providing information of the permissions? Would be grateful if someone could explain this.
Also, I need to understand how the nested for loops within this segment work with respect to getting the desired output of diplaying the filenames and associated permissions ?
And what is the significance of "level" here ?
Would be very grateful, if anyone could answer the above questions and give any relevant guidance. Thanks in advance.
The entire code is :
import stat, sys, os, string, commands
try:
#run a 'find' command and assign results to a variable
pattern = raw_input("Enter the file pattern to search for:\n")
commandString = "find " + pattern
commandOutput = commands.getoutput(commandString)
findResults = string.split(commandOutput, "\n")
#output find results, along with permissions
print "Files:"
print commandOutput
print "================================"
for file in findResults:
mode=stat.S_IMODE(os.lstat(file)[stat.ST_MODE])
print "\nPermissions for file ", file, ":"
for level in "USR", "GRP", "OTH":
for perm in "R", "W", "X":
if mode & getattr(stat,"S_I"+perm+level):
print level, " has ", perm, " permission"
else:
print level, " does NOT have ", perm, " permission"
except:
print "There was a problem - check the message above"

The interactive Python interpreter shell is a good place to play around with snippets of Python code in order to understand them. For instance, to get the mode thing in your script:
>>> import os, stat
>>> os.lstat("path/to/some/file")
posix.stat_result(st_mode=33188, st_ino=834121L, st_dev=2049L, ...
>>> stat.ST_MODE
0
>>> os.lstat("path/to/some/file")[0]
33188
>>> stat.S_IMODE(33188)
420
Now you know the values, check the Python docs to get their meaning.
In a similar way you could try to answer the other questions yourself.
UPDATE:
The value of mode is a bitwise OR combination of different mode flags. The nested loop "manually" builds the names of these flags, uses getattr to get their values and then checks if mode includes these values.

Related

Python-How to execute code and store into variable?

So I have been struggling with this issue for what seems like forever now (I'm pretty new to Python). I am using Python 3.7 (need it to be 3.7 due to variations in the versions of packages I am using for the project) to develop an AI chatbot system that can converse with you based on your text input. The program reads the contents of a series of .yml files when it starts. In one of the .yml files I am developing a syntax for when the first 5 characters match a ^###^ pattern, it will instead execute the code and return the result of that execution rather than just output text back to the user. For example:
Normal Conversation:
- - What is AI?
- Artificial Intelligence is the branch of engineering and science devoted to constructing machines that think.
Service/Code-based conversation:
- - Say hello to me
- ^###^print("HELLO")
The idea is that when you ask it to say hello to you, the ^##^print("HELLO") string will be retrieved from the .yml file, the first 5 characters of the response will be removed, the response will be sent to a separate function in the python code where it will run the code and store the result into a variable which will be returned from the function into a variable that will give the nice, clean result of HELLO to the user. I realize that this may be a bit hard to follow, but I will straighten up my code and condense everything once I have this whole error resolved. As a side note: Oracle is just what I am calling the project. I'm not trying to weave Java into this whole mess.
THE PROBLEM is that it does not store the result of the code being run/executed/evaluated into the variable like it should.
My code:
def executecode(input):
print("The code to be executed is: ",input)
#note: the input may occasionally have single quotes and/or double quotes in the input string
result = eval("{}".format(input))
print ("The result of the code eval: ", result)
test = eval("2+2")
test
print(test)
return result
#app.route("/get")
def get_bot_response():
userText = request.args.get('msg')
print("Oracle INTERPRETED input: ", userText)
ChatbotResponse = str(english_bot.get_response(userText))
print("CHATBOT RESPONSE VARIABLE: ", ChatbotResponse)
#The interpreted string was a request due to the ^###^ pattern in front of the response in the custom .yml file
if ChatbotResponse[:5] == '^###^':
print("---SERVICE REQUEST---")
print(executecode(ChatbotResponse[5:]))
interpreter_response = executecode(ChatbotResponse[5:])
print("Oracle RESPONDED with: ", interpreter_response)
else:
print("Oracle RESPONDED with: ", ChatbotResponse)
return ChatbotResponse
When I run this code, this is the output:
Oracle INTERPRETED input: How much RAM do you have?
CHATBOT RESPONSE VARIABLE: ^###^print("HELLO")
---SERVICE REQUEST---
The code to be executed is: print("HELLO")
HELLO
The result of the code eval: None
4
None
The code to be executed is: print("HELLO")
HELLO
The result of the code eval: None
4
Oracle RESPONDED with: None
Output on the website interface
Essentially, need it to say HELLO for the "The result of the code eval:" output. This should get it to where the chatbot responds with HELLO in the web interface, which is the end goal here. It seems as if it IS executing the code due to the HELLO's after the "The code to be executed is:" output text. It's just not storing it into a variable like I need it to.
I have tried eval, exec, ast.literal_eval(), converting the input to string with str(), changing up the single and double quotes, putting \ before pairs of quotes, and a few other things. Whenever I get it to where the program interprets "print("HELLO")" when it executes the code, it complains about the syntax. Also, from several days of looking online I have figured out that exec and eval aren't generally favored due to a bunch of issues, however I genuinely do not care about that at the moment because I am trying to make something that works before I make something that is good and works. I have a feeling the problem is something small and stupid like it always is, but I have no idea what it could be. :(
I used these 2 resources as the foundation for the whole chatbot project:
Text Guide
Youtube Guide
Also, I am sorry for the rather lengthy and descriptive question. It's rare that I have to ask a question of my own on stackoverflow because if I have a question, it usually already has a good answer. It feels like I've tried everything at this point. If you have a better suggestion of how to do this whole system or you think I should try approaching this another way, I'm open to ideas.
Thank you for any/all help. It is very much appreciated! :)
The issue is that python's print() doesn't have a return value, meaning it will always return None. eval simply evaluates some expression, and returns back the return value from that expression. Since print() returns None, an eval of some print statement will also return None.
>>> from_print = print('Hello')
Hello
>>> from_eval = eval("print('Hello')")
Hello
>>> from_print is from_eval is None
True
What you need is a io stream manager! Here is a possible solution that captures any io output and returns that if the expression evaluates to None.
from contextlib import redirect_stout, redirect_stderr
from io import StringIO
# NOTE: I use the arg name `code` since `input` is a python builtin
def executecodehelper(code):
# Capture all potential output from the code
stdout_io = StringIO()
stderr_io = StringIO()
with redirect_stdout(stdout_io), redirect_stderr(stderr_io):
# If `code` is already a string, this should work just fine without the need for formatting.
result = eval(code)
return result, stdout_io.getvalue(), stderr_io.getvalue()
def executecode(code):
result, std_out, std_err = executecodehelper(code)
if result is None:
# This code didn't return anything. Maybe it printed something?
if std_out:
return std_out.rstrip() # Deal with trailing whitespace
elif std_err:
return std_err.rstrip()
else:
# Nothing was printed AND the return value is None!
return None
else:
return result
As a final note, this approach is heavily linked to eval since eval can only evaluate a single statement. If you want to extend your bot to multiple line statements, you will need to use exec, which changes the logic. Here's a great resource detailing the differences between eval and exec: What's the difference between eval, exec, and compile?
It is easy just convert try to create a new list and add the the updated values of that variable to it, for example:
if you've a variable name myVar store the values or even the questions no matter.
1- First declare a new list in your code as below:
myList = []
2- If you've need to answer or display the value through myVar then you can do like below:
myList.append(myVar)
and this if you have like a generator for the values instead if you need the opposite which means the values are already stored then you will just update the second step to be like the following:
myList[0]='The first answer of the first question'
myList[1]='The second answer of the second question'
ans here all the values will be stored in your list and you can also do this in other way, for example using loops is will be much better if you have multiple values or answers.

Can't see anything printed

Could you help me to understand why can't have anything printed?
list = [1, 2,3,4, 5, 7, 9]
def test(list):
# Using for loop
for i in list:
d = i % 2
if d == 0:
print('odd')
save = i + " it's odd"
else:
print('even')
save= i + " it's even"
return save
print(save)
This should work for you, let me know if it doesn't. Here's a couple of pointers on your code above:
in the line save = i + " it's odd" and save= i + " it's even" you are trying to add a string and an int -- python doesn't really like this and will throw an error. But you can use .format method to insert values into a string. Here's a link with some examples https://www.geeksforgeeks.org/python-format-function/
The return will end your function. So the way you have it will only let the for loop get the first index in the list. (index 0). So for your purposes I would just go ahead and ditch the return call.
You call your list "list", which is intuitive-especially if you are just starting out. But python has built in functions that you can call on and one of them is list. It is a good idea to think of these as "reserved words" and to not use them as variable names. Try something like "lis" or "my_list" instead. Here is a link to some built in python functions that you will see a lot. https://docs.python.org/3/library/functions.html
Lastly, to get a function to run you must call it. You can see in the code below, at the very bottom that I have test(lis). This tells python to go ahead and run the function with the input we specify (in this case it is lis)
lis = [1, 2,3,4, 5, 7, 9]
def test(list_):
# edit 'def' requires tab indentation
# Using for loop
for i in list_:
if (i % 2) != 0:
save = ("{0} it's odd".format(i))
else:
save = ("{0} it's even".format(i))
print(save)
test(lis)
Brack, Thanks for your patience.
That has been said before, but, believe it or not, spyder doesn't complain. I will use as mentioned on geeksforgeeks.
Understood your explanation. I tried to do this way because I was following a peace of code to make some changes on it. To do that I was trying to understand it first.
Got it
4.That's another thing I can't see in that code.(it works because I use it).
The code I was trying to modify is this: https://gist.github.com/ericrobskyhuntley/0c293113aa75a254237c143e0cf962fa
And what I want is to include a way to save the processed records when it reaches , for example, multiples of 500.
It will avoid to lose work done if something goes wrong (like it did often)
Once again, thank you!
just I wanted to let you know that the answer you responded too is actually mine, not Moquin. Their name shows up on there too because they edited a spelling error. Also I am creating another answer here to respond to you because I am not yet able to respond in the comment section of other peoples questions. (That is reserved for individuals who have a reputation of 50 or higher on this site). If you liked my last answer, please consider accepting it as the answer by pressing the check mark.
To answer your other question regarding preserving your work, I would consider writing your output to a list. Before, we just printed it out, but if you write it to a list you can access it later in your code. Do so like this:
lis = [1, 2,3,4, 5, 7, 9]
empty_lis = []
def test(list_):
# edit 'def' requires tab indentation
# Using for loop
for i in list_:
if (i % 2) != 0:
empty_lis.append(save)
save = ("{0} it's odd".format(i))
else:
empty_lis.append(save)
save = ("{0} it's even".format(i))
print(empty_lis)
test(lis)
or additionally, you could consider creating a log file to keep track of output and where your script breaks. It will write to a .log file in whatever path you specify.
import logging
#create log
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s:%(levelname)s:%(message)s")
file_handler = logging.FileHandler(r'{insert path here}testlog.log')#iput file path in the curly
#braces and name the lof whatever you want. Just make sure it ends in .log
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
lis = [1, 2,3,4, 6, 7, 9]
empty_lis = []
def test(list_):
# edit 'def' requires tab indentation
# Using for loop
for i in list_:
try:
if (i % 2) != 0:
save = ("{0} it's odd".format(i))
empty_lis.append(save)
else:
save = ("{0} it's even".format(i))
empty_lis.append(save)
logger.info(" my list is{0}".format(empty_lis)) # this writes to your log
print(empty_lis)
except:
logger.exception("Did not work. See logs for details.")
test(lis)

Program doesn't append file using variables, but no error message appears

Using Python 3.4.2
I'm working on a quiz system using python. Though it hasn't been efficient, it has been working till now.
Currently, I have a certain user log in, take a quiz, and the results of the quiz get saved to a file for that users results. I tried adding in so that it also saves to a file specific to the subject being tested, but that's where the problem appears.
user_score = str(user_score)
user_score_percentage_str = str(user_score_percentage)
q = open('user '+(username)+' results.txt','a')
q.write(test_choice)
q.write('\n')
q.write(user_score+'/5')
q.write('\n')
q.write(user_score_percentage_str)
q.write('\n')
q.write(user_grade)
q.write('\n')
q.close()
fgh = open(test_choice+'results.txt' ,'a')
fgh.write(username)
fgh.write('\n')
fgh.write(user_score_percentage_str)
fgh.write('\n')
fgh.close
print("Your result is: ", user_score , "which is ", user_score_percentage,"%")
print("Meaning your grade is: ", user_grade)
Start()
Everything for q works (this saves to the results of the user)
However, once it comes to the fgh, the thing doesn't work at all. I receive no error message, however when I go the file, nothing ever appears.
The variables used in the fgh section:
test_choice this should work, since it worked for the q section
username, this should also work since it worked for the q section
user_score_percentage_str and this, once more, should work since it worked for the q section.
I receive no errors, and the code itself doesn't break as it then correctly goes on to print out the last lines and return to Start().
What I would have expected in the file is to be something like:
TestUsername123
80
But instead, the file in question remains blank, leading me to believe there must be something I'm missing regarding working the file.
(Note, I know this code is unefficient, but except this one part it all worked.)
Also, apologies if there's problem with my question layout, it's my first time asking a question.
And as MooingRawr kindly pointed out, it was indeed me being blind.
I forgot the () after the fgh.close.
Problem solved.

Python overwriting variable in script 1 with user input from script2

I've been struggling with this for several days now, and I cant find any answers that actually relate to what I'm trying to do, at least none that I can find.
I am trying to create a basic system for keeping track of my finances (i.e. cash, whats in the bank, etc). I have two scripts: display.py and edit.py.
The idea is that I can easily pull up display.py and see how much I have and where it is, and use edit.py to change the amounts shown in display.py, without having to open Vi or entering the numbers every time i run display.py.
In theory, edit.py would take user input, and then overwrite the value in display with that new input, so that display is independent of edit and saves those values
display.py:
cash1 = "5.14"
bank1 = "none"
print "you have", cash1, "in your pocket"
print ""
print ""you have", bank1, "in the bank"
and using this in edit.py
f = open("display.py", "r")
contents = f.readlines()
f.close()
cashinput1 = "cash1"
cashinput2 = raw_input("enter the new coin amount: ")
cashtransfer = ("=".join((cashinput1,cashinput2,)))
contents.insert(5, cashtransfer)
f = open("display.py", "w")
contents = "".join(contents)
f.write(contents)
f.close()
I know edit.py isn't very clean, but the problem is that it's adding the input to the end of a line, pushing it to the next one. The goal is overwrite cash1, not add another. I've tried simply importing, but that doesn't work as the changes aren't saved.
tl;dr How do I overwrite a variable in one script with user input from another script?
I'm using Python 2.7.12
thanks in advance.
EDIT: Sqlite3 looks designed for this type of thing, so this question is answered. Not sure how to close this without any answers though.
As I've been pointed toward Sqlite3, I will use that. Thanks again, question answered :)

How can I use Microsoft Word's spelling/grammar checker programmatically?

I want to process a medium to large number of text snippets using a spelling/grammar checker to get a rough approximation and ranking of their "quality." Speed is not really of concern either, so I think the easiest way is to write a script that passes off the snippets to Microsoft Word (2007) and runs its spelling and grammar checker on them.
Is there a way to do this from a script (specifically, Python)? What is a good resource for learning about controlling Word programmatically?
If not, I suppose I can try something from Open Source Grammar Checker (SO).
Update
In response to Chris' answer, is there at least a way to a) open a file (containing the snippet(s)), b) run a VBA script from inside Word that calls the spelling and grammar checker, and c) return some indication of the "score" of the snippet(s)?
Update 2
I've added an answer which seems to work, but if anyone has other suggestions I'll keep this question open for some time.
It took some digging, but I think I found a useful solution. Following the advice at http://www.nabble.com/Edit-a-Word-document-programmatically-td19974320.html I'm using the win32com module (if the SourceForge link doesn't work, according to this Stack Overflow answer you can use pip to get the module), which allows access to Word's COM objects. The following code demonstrates this nicely:
import win32com.client, os
wdDoNotSaveChanges = 0
path = os.path.abspath('snippet.txt')
snippet = 'Jon Skeet lieks ponies. I can haz reputashunz? '
snippet += 'This is a correct sentence.'
file = open(path, 'w')
file.write(snippet)
file.close()
app = win32com.client.gencache.EnsureDispatch('Word.Application')
doc = app.Documents.Open(path)
print "Grammar: %d" % (doc.GrammaticalErrors.Count,)
print "Spelling: %d" % (doc.SpellingErrors.Count,)
app.Quit(wdDoNotSaveChanges)
which produces
Grammar: 2
Spelling: 3
which match the results when invoking the check manually from Word.

Categories

Resources