Can't see anything printed - python

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)

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.

error using list.append() when print works fine

I'm trying to make a simple web scraper that will send me an e-mail about deals posted on a website's page. I am using beautifulsoup in order to scrape the info into a list called "list". I can get the output to look they way I want it using a print command, but when I try to use the same loops to append the strings into a list I get the following error
> ----- Post with most thanks ------ Traceback (most recent call last):
> ----- Trending Hot Deals ------ File "C:/Users/Geoff/PycharmProjects/web_scraping/Historian_file.py", line
> 45, in <module>
> ----- Popular Threads ------
> print "\n".join(msg)
> ----- New Posts ------ TypeError: sequence item 0: expected string, NoneType found
>
> Process finished with exit code 1
here is the code, the commented out parts don't work, the print commands do.
def title(number):
if number == 1:
print "----- Post with most thanks ------"
elif number == 2:
print "----- Trending Hot Deals ------"
elif number == 3:
print "----- Popular Threads ------"
else:
print "----- New Posts ------"
msg = []
x = 1
for i in list:
print title(x)
#msg.append(title(x))
x = x+1
for j in i:
l = j.encode_contents()
print l
#msg.append(l)
#print "\n".join(msg)
I appreciate any help on this.
Thanks
Change print statement on return in the title function.
def title(number):
if number == 1:
return "----- Post with most thanks ------"
elif number == 2:
return "----- Trending Hot Deals ------"
elif number == 3:
return "----- Popular Threads ------"
else:
return "----- New Posts ------"
Remember that every function without return statement always returns None.
Moved to an answer, because people are shorting you on valid information.
Yes you need to return data from the function, rather than printing it. So change print to return, and you will be set (as long as you return strings, or sanitize your data)
This is a good lesson on debugging code. Your stack trace says the issue, but your title ignores it as do some of the others. .join() expects string types, so that is where this is causing you issue.
To debug strange issues, you will want to pay more attention to the stacktrace, which was a little cluttered by the prints (don't worry - all of us have ignored this data before).
None is a valid type that can be in a list. As a result, calling mylist.append(Foo()) when Foo returns nothing, appends None to your list. It's completely valid.
Your actual issue, however, is when you try to call .join(ListWithNotStringsInIt). Read that as: I gave .join() list of items, at least one of them was not a string, nor could it be implicitly cast to a string (str()).
How should you solve that to avoid issues in the future? Sanitize your data.
List comprehension is a pretty good way to do this, though - it should be completely unnecessary if you are handling your data responsibly:
'\n'.join([str(x) for x in my_list])
Python expects that you as a programmer are wise about how you can use it. As a result, you get lots of rope to hang yourself with (such as seeing errors like this).
List comprehension should not be required here, and if you are responsible at using your list correctly, it is completely unnecessary. But it's a way to check what you are getting, especially when there are exceptions thrown and you're debugging the issue.
Your title function doesn't return anything, so when you try to append the result of calling the function, you're not actually appending the result from title. Instead, you are appending None. To fix this, you need to return them, instead of simply printing them.

Renaming fails for duplicated objects

I am making a renaming script, but I am getting in a bit of trouble with my
Seach and Replace function.
Actually, the function works as long as there are no duplication of the same
object in the hierarchy. For example, as depicted in the attachment, locator1
and locator2 are created from scratch, whereas locator3 is a duplication from
locator2
If I were to display them in their short name, it is as follows:
locator1
locator2
locator2|locator3
So as mentioned, when I tried to replace the word 'locator' to 'Point', the
renaming works for locator 1 and 2, but when it comes to locator3, I got the
error RuntimeError: No object matches name
As such, I was wondering if there is a better way for me to recode, cause in
cases like in Modelling, where artists duplicates the object over and over again
or using of instances..
I know that this fails is due to the short name in itself but is it possible to bypass it?
def searchReplace(self):
wordSearch = str(self.searchTxt.text())
wordReplace = str(self.replaceTxt.text())
objCnt = cmds.ls(sl=True, sn=True)
if len(objCnt) == 0:
self.searchTxt.clear()
self.replaceTxt.clear()
cmds.warning('Nothing is selected')
else:
for wordString in sorted(objCnt):
if wordSearch in wordString:
newWordString = wordString.replace(wordSearch, wordReplace)
cmds.rename(wordString, newWordString)
self.searchTxt.clear()
self.replaceTxt.clear()
print '%s' %wordString + " has changed to : " + "%s" %newWordString
This is a tricky problem, but the solution is actually really simple!
When you sort objCnt, you're doing it lexicographically:
for wordString in sorted(objCnt):
This means that locator2 comes before locator2|locator3. On its own that should be fine, but...
When locator2 is renamed, the path to locator3 has also changed, so accessing it fails.
The trick is to reverse the sort so longer objects come first. That way the children always get renamed before their parents
for wordString in sorted(objCnt, reverse=True):
For this to work, you also need to make sure your ls gives you long names, be adding the long=True argument

Display an error message when argument not there

I have a directory where csv files are located. The code reads the files and creates histograms based on the data in the files.
I have made this a command prompt code where I can enter the arguments and the code will look through the csv files to see if the arguments I listed are there. I am trying to make it so that an error message comes up when I misspell a command. The following code works if the first argument is spelled correctly and the second is not, but does not display an error message if the first is misspelled and the second is correct. What's wrong?
Example: python untitled14.py "Folder" Are Perimeter DOES NOT DISPLAY ERROR MESSAGE FOR ARE
BUT python untitled14.py "Folder" Perimeter Are DOES DISPLAY ERROR FOR ARE
for x in arguments:
found_match = False
for column in df:
os.chdir(directory)
if x.endswith(column):
found_match = True
#histogram code
continue
else:
pass
if found_match==False:
print files+" " + x + " does not exist"
You have unnecessary things (and some other questionable things) in your loop logic. For example, the three lines continue; else: pass do literal nothing.
The best thing to do would be to refactor your code to call a function that would return True if all the arguments validated. You didn't provide enough code for that, so I would clean the whole thing up with:
for x in arguments:
for column in df:
os.chdir(directory)
if x.endswith(column):
#histogram code
break
else:
print "{0} {1} does not exist".format(files,x)
break #or not, depending on what you want to do
This takes advantage of the somewhat rarely-used for/else to do something if the for loop did not break - which, in your case, is an error.
If you want to really make this re-usable, you should raise an Exception instead of just printing on an error.

Python Script to search for a file

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.

Categories

Resources