0

I have a script that emails me links to me.

The problem is the links arent included, instead I get:

<function <lambda> at 0x7f75b5fb4a60>

My script looks like:

from bs4 import BeautifulSoup
import re
import requests

ex_webdev_js_by_city = [
'http://boston.website.org/search/web',
]

ex_web_j_keywords = [['one'],['coool', 'person']]
ex_web_j_keywords = sum(ex_web_j_keywords, [])

ex_js = []

for webdev_j_for_a_city in ex_webdev_js_by_city:
    webdev_j = requests.get(webdev_j_for_a_city)
    soup = BeautifulSoup(webdev_j.text, "lxml")
    for j_keyword in ex_web_j_keywords:
        for a in soup.find_all('a', class_="result-title hdrlnk", text=re.compile(j_keyword,re.IGNORECASE)):
            #print(a.get('href'))
            ex_js.append(a.get('href'))

if ex_js:
   #email them to myself!
   import smtplib, socket
   TO = '[email protected]'

   try:
       server = smtplib.SMTP('smtp.gmail.com', 587)
       server.starttls()
       TEXT = lambda: print(('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js))
       #Gmail Sign In
       gmail_sender = 'myemail'
       gmail_passwd = 'mypass'
       server.login(gmail_sender, gmail_passwd)
       msg = str(TEXT)
       server.sendmail(gmail_sender, gmail_sender, msg)
       print('Sent you some links!')
       server.quit()
   except socket.error as e:
       print ('error sending mail, error was {}'.format(e))

The error is occuring on this line (I believe):

lambda: print(('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js))

It appears its printing out the object details in the email to me, and not the value.

Thus, what am i possibly doing wrong here?

2
  • 1
    First of all, the value is None since you "return" a print statement and secondly, why do you use lambda? Commented Jan 27, 2017 at 20:54
  • The lambda function isn't doing anything because it is never called. Commented Jan 27, 2017 at 21:01

2 Answers 2

4

I don't know why you use print or lambda anyway. If you simply wrote:

msg = ('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js)

and drop the:

msg = str(TEXT)

it should probably work.

So the try block should read:

server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
msg = ('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js)
#Gmail Sign In
gmail_sender = 'myemail'
gmail_passwd = 'mypass'
server.login(gmail_sender, gmail_passwd)
# msg = str(TEXT) !!commented out!! (only to make it explicit)
server.sendmail(gmail_sender, gmail_sender, msg)
print('Sent you some links!')
server.quit()

I think however that you do not really understand what lambda and print are supposed to do. print is used to write data to the standard output channel, but you want to write it into an email, so you do not need to print it locally, you need somehow to store your message in memory.

Finally lambda:... is used to create an anonymous function, if you do not feed it any arguments, its usage is usually to postpone execution (for instance to achieve laziness). But here you actually need the message, so again no need to use this construct.

Sign up to request clarification or add additional context in comments.

4 Comments

I think you mean to comment out msg=str(TEXT) ?
@Jshee: comment out or remove. Indeed, my bad... Sorry.
This is really helpful. So, to use format() i dont need to call a function like print() before?
@Jshee: no format is a function defined on a string (as you can see here), print has nothing to do with that. When you use it, you only feed the output of .format to print.
1

When you say

TEXT = lambda: print(('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js))

Yo are simply creating lambda function , it is not executed yet . In order to execute you need to specifically invoke it by calling TEXT()

In order to fix your problem change to

TEXT = lambda: ('Latest js from site:\n\n{}'*len(ex_js)).format(*ex_js)

And msg = str(TEXT())

2 Comments

You don't use return in lambda functions; the result of the expression is returned implicitly. And yeah, a lambda isn't needed at all in this case anyway.
@WillemVanOnsem I was trying to answer the original question. Not trying to questioning his code. And you are absolutely correct, this scenario we don't need lambda

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.