1
00:00:00,150 --> 00:00:08,850
In this video, I'm going to write a script which reads a CSV file where we have this different email

2
00:00:08,850 --> 00:00:09,930
records and

3
00:00:12,750 --> 00:00:21,420
the script sends an email to each of these records, and the email contains a text file as an attachment,

4
00:00:21,420 --> 00:00:23,290
and in that text file

5
00:00:23,310 --> 00:00:32,759
Python also will write the amount that someone so that's contacted that person has to pay.

6
00:00:33,720 --> 00:00:36,870
So that number is going to be written inside the text file.

7
00:00:38,860 --> 00:00:42,760
And sent out to each of those contacts.

8
00:00:43,120 --> 00:00:44,080
So that's the idea.

9
00:00:45,920 --> 00:00:58,160
For that, I'm going to fork this last repl and change the name slightly, maybe modified, modified

10
00:00:58,160 --> 00:00:58,850
attachment.

11
00:00:59,900 --> 00:01:05,420
So we are modifying the attachment this time, which is different from what we did last time, last

12
00:01:05,420 --> 00:01:09,470
time we just sent out a text file as it was.

13
00:01:09,950 --> 00:01:13,280
So let's check the data source if they are OK.

14
00:01:13,310 --> 00:01:18,660
So contacts.csv. I think these email addresses were temporary.

15
00:01:18,680 --> 00:01:21,920
So I'm just going to delete them and just keep one contact here.

16
00:01:21,930 --> 00:01:22,970
That's that's enough.

17
00:01:23,300 --> 00:01:25,150
So for file path?

18
00:01:25,370 --> 00:01:28,160
What do we choose to have this time?

19
00:01:28,490 --> 00:01:37,590
I think it makes more sense that the file path should be generated automatically, dynamically by Python.

20
00:01:37,610 --> 00:01:44,330
It doesn't make sense to have multiple contacts here and to have that file name for each contact.

21
00:01:44,330 --> 00:01:45,470
So different file names.

22
00:01:45,680 --> 00:01:46,910
It's not practical.

23
00:01:47,510 --> 00:01:56,300
So what I think is that we delete that field from csv, right? Like that, and we have only name, email,

24
00:01:56,300 --> 00:01:56,870
amount.

25
00:01:57,260 --> 00:02:03,680
So Ardit, gmail.com the address, up to here and the amount, that.

26
00:02:04,520 --> 00:02:12,290
And then as the name of the text file, we use the name of the person so Ardit in this case.

27
00:02:13,160 --> 00:02:14,900
So Ardit.txt.

28
00:02:15,290 --> 00:02:16,220
That's what I'm thinking.

29
00:02:16,220 --> 00:02:20,000
You could find different solutions, but this is good enough, I think.

30
00:02:20,870 --> 00:02:27,170
So we generate that and we attach that file, so we do the import here, the sender is static.

31
00:02:27,440 --> 00:02:30,770
We are not having different senders, that's the sender.

32
00:02:31,100 --> 00:02:34,370
It happens to be the same as the receiver, but it doesn't matter.

33
00:02:34,730 --> 00:02:35,930
We log in here.

34
00:02:36,170 --> 00:02:36,950
Let me expand

35
00:02:36,950 --> 00:02:39,860
the code, we log in.

36
00:02:40,860 --> 00:02:44,180
We open the pandas data frame.

37
00:02:44,270 --> 00:02:51,330
So we open the csv as a pandas dataframe, and we iterate over the rows of the dataframe

38
00:02:51,330 --> 00:02:51,990
table.

39
00:02:52,200 --> 00:02:52,620
So,

40
00:02:53,900 --> 00:03:01,190
once we iterate through a row, let's say we are in this one here, Ardit with this email address,

41
00:03:01,640 --> 00:03:07,500
the first thing we want to do is, of course, to generate that attachment, to make the attachment

42
00:03:07,560 --> 00:03:08,010
ready.

43
00:03:08,390 --> 00:03:09,650
That makes sense to me.

44
00:03:09,890 --> 00:03:18,650
And what I'm going to do is that since this script is expanding, it makes sense to use functional programming now,

45
00:03:19,490 --> 00:03:21,320
not procedural programming.

46
00:03:21,320 --> 00:03:21,540
So.

47
00:03:21,590 --> 00:03:29,300
So far, this is sort of procedural programming because we writes the script line by line, we do something,

48
00:03:29,300 --> 00:03:31,040
we do something else and so on, so forth.

49
00:03:32,090 --> 00:03:38,960
Using that logic with procedural programming, we would add here something like with open and generate,

50
00:03:38,960 --> 00:03:42,230
set a file name and so on.

51
00:03:43,250 --> 00:03:45,560
So things go line by line.

52
00:03:45,560 --> 00:03:53,810
But what I'm thinking is to put things in blocks of code, which I what I mean by that is to put things

53
00:03:53,810 --> 00:04:02,600
in functions, to separate them in functions and a functions should do one thing and do it well.

54
00:04:03,320 --> 00:04:06,860
So this function would be, for example, generate file,

55
00:04:09,730 --> 00:04:16,779
or generate attachment, generate file is good enough, so the function will get some inputs and

56
00:04:16,779 --> 00:04:24,150
it will produce some output, the outputs will be the text file and the input is.

57
00:04:24,200 --> 00:04:29,110
So what changes in between these text files?

58
00:04:29,470 --> 00:04:31,480
So we have one text file for Ardit.

59
00:04:31,810 --> 00:04:32,800
We've gone have...

60
00:04:32,800 --> 00:04:36,570
We're going to have something for John and so on.

61
00:04:37,180 --> 00:04:43,360
What's going to change is the file name and the content of a text file as well.

62
00:04:44,020 --> 00:04:51,130
So this too we use as arguments and then inside here we write the code that generates a text file.

63
00:04:51,490 --> 00:04:57,430
So with open, that's how we generate text files in Python with open file name.

64
00:04:57,940 --> 00:05:07,050
That's the name of the file we open as W, which means in write mode as file.

65
00:05:07,060 --> 00:05:10,990
So that's the file object. In that file object

66
00:05:10,990 --> 00:05:16,480
we want to write. To write? What do we want to write? The contents.

67
00:05:17,440 --> 00:05:24,370
So that variable, that is the file name, that is the contents of that file with that file name.

68
00:05:25,660 --> 00:05:37,060
So we iterate and then we generate the text file, how we do that is by just calling that function generate

69
00:05:37,060 --> 00:05:40,930
file, which expects two arguments, the file name,

70
00:05:40,960 --> 00:05:42,670
So what is the file name?

71
00:05:42,940 --> 00:05:46,950
We said that should be name.

72
00:05:46,990 --> 00:05:49,570
So that one.

73
00:05:50,380 --> 00:05:50,660
Right?

74
00:05:51,460 --> 00:05:56,170
And as content that should be amount.

75
00:05:58,150 --> 00:06:02,740
So the field amount, we might get some issues with this.

76
00:06:03,610 --> 00:06:04,830
But let's leave it like that.

77
00:06:04,840 --> 00:06:11,440
We run it and we see what errors we get, and what output we get and how we can change that outputs.

78
00:06:11,830 --> 00:06:13,480
I think the rest of the code is fine.

79
00:06:13,660 --> 00:06:24,010
So the receiver email is raw email that one, and the subject is that, the content is that.

80
00:06:24,520 --> 00:06:32,080
So the name goes there, the amount also could be included in the email, besides being included in

81
00:06:32,080 --> 00:06:36,040
the attachment and row file path.

82
00:06:37,120 --> 00:06:44,350
So this now is the file path of the attachment, which is the same as this, actually.

83
00:06:45,010 --> 00:06:51,340
So since we are doing this multiple times, so row name here, row name there

84
00:06:51,550 --> 00:06:57,400
it makes sense to put it in a variable name, row, name, right?

85
00:06:57,940 --> 00:07:01,060
And then this variable, I can copy that.

86
00:07:01,390 --> 00:07:02,560
Paste it in here.

87
00:07:02,980 --> 00:07:08,470
We do the same for amount amount equal to row

88
00:07:11,000 --> 00:07:11,660
amount.

89
00:07:13,520 --> 00:07:17,540
And so this becomes amount.

90
00:07:18,740 --> 00:07:19,100
Right?

91
00:07:19,250 --> 00:07:20,120
These variables.

92
00:07:21,170 --> 00:07:25,610
And then here we just say name.

93
00:07:27,340 --> 00:07:29,710
Name, amount,

94
00:07:32,650 --> 00:07:38,500
so we don't have to access that at least multiple times, this list accessing operation here.

95
00:07:38,770 --> 00:07:41,440
Well, it's a data frame series, actually.

96
00:07:41,440 --> 00:07:47,740
Row is a data frame service, but that's even worse because a series is even slower.

97
00:07:48,220 --> 00:07:53,950
Accessing a series, a data frame series is even slower than accessing a list, so it makes sense to

98
00:07:53,950 --> 00:07:55,090
have that only once.

99
00:07:55,840 --> 00:08:01,390
And so here then we say name for the file path.

100
00:08:03,740 --> 00:08:05,510
Yeah, we can keep it like that for now.

101
00:08:06,580 --> 00:08:08,220
And send, yeah.

102
00:08:08,410 --> 00:08:11,830
This also becomes the receiver

103
00:08:14,410 --> 00:08:23,620
email variable, right? This one in here, that one, which I would also like to organize it better

104
00:08:23,950 --> 00:08:26,350
among the variable declarations in here.

105
00:08:28,240 --> 00:08:31,060
So we declare variables, we call the function.

106
00:08:31,750 --> 00:08:36,730
We declare the subject, the contents, and we send out the email.

107
00:08:37,750 --> 00:08:38,200
That's it.

108
00:08:39,590 --> 00:08:40,159
And run.

109
00:08:46,770 --> 00:08:55,560
And we have the first error here, type arguments, write arguments must be a string in line 13,

110
00:08:55,560 --> 00:08:56,700
which is this one in here?

111
00:08:57,750 --> 00:09:07,440
So content is an int, as the error is suggesting. It is an int because content is coming from the

112
00:09:07,440 --> 00:09:20,340
line 20, so line 20 here, amount. Amount is supplied to contents here and content supplies

113
00:09:20,700 --> 00:09:30,090
this write function and amount is generated here, so row amount itself is an integer.

114
00:09:30,090 --> 00:09:31,050
It's 22.

115
00:09:31,650 --> 00:09:38,250
So when we do row amount, the pandas dataframe gives us an integer.

116
00:09:38,400 --> 00:09:40,300
It doesn't give us a string.

117
00:09:40,440 --> 00:09:45,570
We have to convert into a string in here, str_content.

118
00:09:48,760 --> 00:09:58,210
Let's try it again now, but I'm going to have another error if I try because I haven't included a password

119
00:09:59,260 --> 00:10:03,250
key for my Gmail login credentials.

120
00:10:03,610 --> 00:10:09,100
So, passwords and this has to be the app passwords of your Gmail.

121
00:10:09,250 --> 00:10:10,450
So it's an app password.

122
00:10:10,450 --> 00:10:15,700
If you don't have an app password, go to your Gmail, to the app password sections in the settings

123
00:10:15,700 --> 00:10:21,040
and generate an app, and then you get the password, and paste it to you and press that secret.

124
00:10:21,280 --> 00:10:22,330
Now I can run this.

125
00:10:23,760 --> 00:10:27,090
Email sent, let's check.

126
00:10:30,210 --> 00:10:31,830
So this one here.

127
00:10:32,160 --> 00:10:38,250
Hey, Ardit, you have to pay 22, Bill is attached. This is the attachment, let's open it.

128
00:10:39,210 --> 00:10:39,540
Hmm.

129
00:10:39,870 --> 00:10:41,510
So, I see a problem here.

130
00:10:41,520 --> 00:10:48,240
I mean, it opens, the file opens, and we see 22, but my computer didn't recognize the

131
00:10:48,240 --> 00:10:50,850
file, so it was a bit unsure.

132
00:10:50,850 --> 00:10:54,750
What to use to open is because we didn't specify an extension.

133
00:10:55,380 --> 00:10:59,370
So where do we add the dot txt extension?

134
00:11:00,060 --> 00:11:02,980
Should we add it to the function?

135
00:11:02,990 --> 00:11:07,770
So should we do something like f and placeholder?

136
00:11:07,770 --> 00:11:10,800
Perhaps like that dot txt?

137
00:11:11,550 --> 00:11:14,550
Should we construct the file name in here?

138
00:11:14,850 --> 00:11:21,840
I don't think this is a good idea because a function should be decoupled from other roles.

139
00:11:21,840 --> 00:11:23,940
So the function has one role.

140
00:11:24,330 --> 00:11:31,170
It's a role is to generate a file, given a file name, so the file name should come as complete.

141
00:11:31,860 --> 00:11:33,890
So, for example, ardit.txt.

142
00:11:34,620 --> 00:11:38,840
Therefore, I think we should be looking somewhere else should we add it here?

143
00:11:39,840 --> 00:11:43,770
X and so? Dot txt just like we were doing in here.

144
00:11:44,070 --> 00:11:51,180
I don't think that's a good idea either, because name is being used in the contents of the email body.

145
00:11:51,720 --> 00:11:58,470
So if we did that, if we added an extension here, this would say "Hey, ardit.txt

146
00:11:59,100 --> 00:12:00,630
you have to pay this amount".

147
00:12:00,990 --> 00:12:03,240
So that doesn't make sense either, therefore.

148
00:12:03,750 --> 00:12:16,290
So I think the best thing to do here is to create a file name, which should be name plus txt the string.

149
00:12:16,950 --> 00:12:30,300
So Ardit plus dot txt creates the file name and then we use that file name in here, filename.

150
00:12:30,660 --> 00:12:34,800
So we give the path in the contents.

151
00:12:35,640 --> 00:12:42,420
And also we have to use this in here also so generate file using that file name.

152
00:12:43,230 --> 00:12:43,710
That one.

153
00:12:44,760 --> 00:12:45,020
Right?

154
00:12:45,300 --> 00:12:50,550
So generate file supplies this file name in this here.

155
00:12:50,820 --> 00:12:54,460
So this first and that takes it's in here, right?

156
00:12:54,460 --> 00:12:55,360
So that should do it.

157
00:12:55,370 --> 00:12:57,720
So let's run email sent.

158
00:12:59,380 --> 00:13:00,730
Let's see here.

159
00:13:01,300 --> 00:13:05,680
Hey, Ardit you have to pay $22. Bill is attached and Ardit.txt.

160
00:13:06,130 --> 00:13:10,120
Yeah, we can see the text file 22 is here and everything is working fine.

161
00:13:10,930 --> 00:13:14,650
So that's the code for this exercise.

162
00:13:15,370 --> 00:13:17,020
Thank you, and I'll talk to you later.

