In this video, I'm going to write a script which reads a CSV file where we have this different email
records and
the script sends an email to each of these records, and the email contains a text file as an attachment,
and in that text file
Python also will write the amount that someone so that's contacted that person has to pay.
So that number is going to be written inside the text file.
And sent out to each of those contacts.
So that's the idea.
For that, I'm going to fork this last repl and change the name slightly, maybe modified, modified
attachment.
So we are modifying the attachment this time, which is different from what we did last time, last
time we just sent out a text file as it was.
So let's check the data source if they are OK.
So contacts.csv. I think these email addresses were temporary.
So I'm just going to delete them and just keep one contact here.
That's that's enough.
So for file path?
What do we choose to have this time?
I think it makes more sense that the file path should be generated automatically, dynamically by Python.
It doesn't make sense to have multiple contacts here and to have that file name for each contact.
So different file names.
It's not practical.
So what I think is that we delete that field from csv, right? Like that, and we have only name, email,
amount.
So Ardit, gmail.com the address, up to here and the amount, that.
And then as the name of the text file, we use the name of the person so Ardit in this case.
So Ardit.txt.
That's what I'm thinking.
You could find different solutions, but this is good enough, I think.
So we generate that and we attach that file, so we do the import here, the sender is static.
We are not having different senders, that's the sender.
It happens to be the same as the receiver, but it doesn't matter.
We log in here.
Let me expand
the code, we log in.
We open the pandas data frame.
So we open the csv as a pandas dataframe, and we iterate over the rows of the dataframe
table.
So,
once we iterate through a row, let's say we are in this one here, Ardit with this email address,
the first thing we want to do is, of course, to generate that attachment, to make the attachment
ready.
That makes sense to me.
And what I'm going to do is that since this script is expanding, it makes sense to use functional programming now,
not procedural programming.
So.
So far, this is sort of procedural programming because we writes the script line by line, we do something,
we do something else and so on, so forth.
Using that logic with procedural programming, we would add here something like with open and generate,
set a file name and so on.
So things go line by line.
But what I'm thinking is to put things in blocks of code, which I what I mean by that is to put things
in functions, to separate them in functions and a functions should do one thing and do it well.
So this function would be, for example, generate file,
or generate attachment, generate file is good enough, so the function will get some inputs and
it will produce some output, the outputs will be the text file and the input is.
So what changes in between these text files?
So we have one text file for Ardit.
We've gone have...
We're going to have something for John and so on.
What's going to change is the file name and the content of a text file as well.
So this too we use as arguments and then inside here we write the code that generates a text file.
So with open, that's how we generate text files in Python with open file name.
That's the name of the file we open as W, which means in write mode as file.
So that's the file object. In that file object
we want to write. To write? What do we want to write? The contents.
So that variable, that is the file name, that is the contents of that file with that file name.
So we iterate and then we generate the text file, how we do that is by just calling that function generate
file, which expects two arguments, the file name,
So what is the file name?
We said that should be name.
So that one.
Right?
And as content that should be amount.
So the field amount, we might get some issues with this.
But let's leave it like that.
We run it and we see what errors we get, and what output we get and how we can change that outputs.
I think the rest of the code is fine.
So the receiver email is raw email that one, and the subject is that, the content is that.
So the name goes there, the amount also could be included in the email, besides being included in
the attachment and row file path.
So this now is the file path of the attachment, which is the same as this, actually.
So since we are doing this multiple times, so row name here, row name there
it makes sense to put it in a variable name, row, name, right?
And then this variable, I can copy that.
Paste it in here.
We do the same for amount amount equal to row
amount.
And so this becomes amount.
Right?
These variables.
And then here we just say name.
Name, amount,
so we don't have to access that at least multiple times, this list accessing operation here.
Well, it's a data frame series, actually.
Row is a data frame service, but that's even worse because a series is even slower.
Accessing a series, a data frame series is even slower than accessing a list, so it makes sense to
have that only once.
And so here then we say name for the file path.
Yeah, we can keep it like that for now.
And send, yeah.
This also becomes the receiver
email variable, right? This one in here, that one, which I would also like to organize it better
among the variable declarations in here.
So we declare variables, we call the function.
We declare the subject, the contents, and we send out the email.
That's it.
And run.
And we have the first error here, type arguments, write arguments must be a string in line 13,
which is this one in here?
So content is an int, as the error is suggesting. It is an int because content is coming from the
line 20, so line 20 here, amount. Amount is supplied to contents here and content supplies
this write function and amount is generated here, so row amount itself is an integer.
It's 22.
So when we do row amount, the pandas dataframe gives us an integer.
It doesn't give us a string.
We have to convert into a string in here, str_content.
Let's try it again now, but I'm going to have another error if I try because I haven't included a password
key for my Gmail login credentials.
So, passwords and this has to be the app passwords of your Gmail.
So it's an app password.
If you don't have an app password, go to your Gmail, to the app password sections in the settings
and generate an app, and then you get the password, and paste it to you and press that secret.
Now I can run this.
Email sent, let's check.
So this one here.
Hey, Ardit, you have to pay 22, Bill is attached. This is the attachment, let's open it.
Hmm.
So, I see a problem here.
I mean, it opens, the file opens, and we see 22, but my computer didn't recognize the
file, so it was a bit unsure.
What to use to open is because we didn't specify an extension.
So where do we add the dot txt extension?
Should we add it to the function?
So should we do something like f and placeholder?
Perhaps like that dot txt?
Should we construct the file name in here?
I don't think this is a good idea because a function should be decoupled from other roles.
So the function has one role.
It's a role is to generate a file, given a file name, so the file name should come as complete.
So, for example, ardit.txt.
Therefore, I think we should be looking somewhere else should we add it here?
X and so? Dot txt just like we were doing in here.
I don't think that's a good idea either, because name is being used in the contents of the email body.
So if we did that, if we added an extension here, this would say "Hey, ardit.txt
you have to pay this amount".
So that doesn't make sense either, therefore.
So I think the best thing to do here is to create a file name, which should be name plus txt the string.
So Ardit plus dot txt creates the file name and then we use that file name in here, filename.
So we give the path in the contents.
And also we have to use this in here also so generate file using that file name.
That one.
Right?
So generate file supplies this file name in this here.
So this first and that takes it's in here, right?
So that should do it.
So let's run email sent.
Let's see here.
Hey, Ardit you have to pay $22. Bill is attached and Ardit.txt.
Yeah, we can see the text file 22 is here and everything is working fine.
So that's the code for this exercise.
Thank you, and I'll talk to you later.