38
38
class EmailAnalysis extends SignatureData {
39
39
#[InputField('content of email ' )]
40
40
public string $ text ;
41
-
42
41
#[OutputField('identify most relevant email topic: sales, support, other, spam ' )]
43
42
public string $ topic ;
44
-
45
43
#[OutputField('one word sentiment: positive, neutral, negative ' )]
46
44
public string $ sentiment ;
47
45
@@ -62,19 +60,14 @@ public function __construct(
62
60
class EmailStats extends SignatureData {
63
61
#[InputField('directory containing emails ' )]
64
62
public string $ directory ;
65
-
66
63
#[OutputField('number of emails ' )]
67
64
public int $ emails ;
68
-
69
65
#[OutputField('number of spam emails ' )]
70
66
public int $ spam ;
71
-
72
67
#[OutputField('average sentiment ratio ' )]
73
68
public float $ sentimentRatio ;
74
-
75
69
#[OutputField('spam ratio ' )]
76
70
public float $ spamRatio ;
77
-
78
71
#[OutputField('category counts ' )]
79
72
public CategoryCount $ categories ;
80
73
@@ -83,56 +76,56 @@ static public function for(string $directory) : static {
83
76
}
84
77
}
85
78
79
+ // MODULE DECLARATIONS ////////////////////////////////////////////////////////////////////
80
+
86
81
class ReadEmails extends Module {
87
82
public function __construct (
88
83
private array $ directoryContents = []
89
84
) {}
90
85
91
86
public function signature () : string |Signature {
92
- return 'directory -> emails ' ;
87
+ return 'directory -> emails : string[] ' ;
93
88
}
94
89
95
- public function forward (string $ directory ) : array {
90
+ protected function forward (string $ directory ) : array {
96
91
return $ this ->directoryContents [$ directory ];
97
92
}
98
93
}
99
94
100
95
class ParseEmail extends Module {
101
96
public function signature () : string |Signature {
102
- return 'email -> sender, body ' ;
97
+ return 'email -> sender, subject, body ' ;
103
98
}
104
99
105
100
protected function forward (string $ email ) : array {
106
101
$ parts = explode (', ' , $ email );
107
102
return [
108
103
'sender ' => trim (explode (': ' , $ parts [0 ])[1 ]),
109
- 'body ' => trim (explode (': ' , $ parts [1 ])[1 ]),
104
+ 'subject ' => trim (explode (': ' , $ parts [1 ])[1 ]),
105
+ 'body ' => trim (explode (': ' , $ parts [2 ])[1 ]),
110
106
];
111
107
}
112
108
}
113
109
114
110
class GetStats extends Module {
115
- private ReadEmails $ readEmails ;
116
- private ParseEmail $ parseEmail ;
117
- private Predict $ analyseEmail ;
118
-
119
- public function __construct (Instructor $ instructor , array $ directoryContents = []) {
120
- $ this ->readEmails = new ReadEmails ($ directoryContents );
121
- $ this ->parseEmail = new ParseEmail ();
122
- $ this ->analyseEmail = new Predict (signature: EmailAnalysis::class, instructor: $ instructor );
123
- }
111
+ public function __construct (
112
+ private ReadEmails $ readEmails ,
113
+ private ParseEmail $ parseEmail ,
114
+ private Predict $ analyseEmail ,
115
+ ) {}
124
116
125
117
public function signature () : string |Signature {
126
118
return EmailStats::class;
127
119
}
128
120
129
- public function forward (string $ directory ) : EmailStats {
121
+ protected function forward (string $ directory ) : EmailStats {
130
122
$ emails = $ this ->readEmails ->withArgs (directory: $ directory )->get ('emails ' );
131
123
$ aggregateSentiment = 0 ;
132
124
$ categories = new CategoryCount ;
133
125
foreach ($ emails as $ email ) {
134
126
$ parsedEmail = $ this ->parseEmail ->withArgs (email: $ email );
135
- $ emailAnalysis = $ this ->analyseEmail ->with (EmailAnalysis::for ($ parsedEmail ->get ('body ' )));
127
+ $ emailData = EmailAnalysis::for (text: $ parsedEmail ->get ('body ' ));
128
+ $ emailAnalysis = $ this ->analyseEmail ->with ($ emailData );
136
129
$ topic = $ emailAnalysis ->get ('topic ' );
137
130
$ sentiment = $ emailAnalysis ->get ('sentiment ' );
138
131
$ topic = (in_array ($ topic , ['sales ' , 'support ' , 'spam ' ])) ? $ topic : 'other ' ;
@@ -160,19 +153,26 @@ public function forward(string $directory) : EmailStats {
160
153
}
161
154
162
155
$ directoryContents ['inbox ' ] = [
163
- 'sender: [email protected] , body: I am happy about the discount you offered and accept contract renewal ' ,
164
- 'sender: xxx, body: Get Viagra and Ozempic for free ' ,
165
- 'sender: [email protected] , body: My internet connection keeps failing ' ,
166
- 'sender: [email protected] , body: How long do I have to wait for the pricing of custom support service?!? ' ,
167
- 'sender: [email protected] , body: 2 weeks of waiting and still no improvement of my connection ' ,
156
+ 'sender: [email protected] , subject: Offer, body: I am happy about the discount you offered and accept contract renewal ' ,
157
+ 'sender: xxx, subject: Free!!!, body: Get Ozempic for free ' ,
158
+ 'sender: [email protected] , subject: Problem, body: My internet connection keeps failing ' ,
159
+ 'sender: [email protected] , subject: Still no pricing, body: How long do I have to wait for the pricing of custom support service?!? ' ,
160
+ 'sender: [email protected] , subject: Slow connection, body: 2 weeks of waiting and still no improvement of my connection ' ,
168
161
];
169
162
163
+ // PREPARE DEPENDENCIES
164
+
170
165
$ instructor = (new Instructor );
171
- $ getStats = new GetStats ($ instructor , $ directoryContents );
166
+ $ readEmails = new ReadEmails ($ directoryContents );
167
+ $ parseEmail = new ParseEmail ();
168
+ $ analyseEmail = new Predict (signature: EmailAnalysis::class, instructor: $ instructor );
169
+ $ getStats = new GetStats ($ readEmails , $ parseEmail , $ analyseEmail );
170
+
171
+ // EXECUTE LANGUAGE PROGRAM
172
+
172
173
$ emailStats = $ getStats ->with (EmailStats::for ('inbox ' ));
173
174
174
175
echo "Results: \n" ;
175
176
dump ($ emailStats ->get ());
176
177
?>
177
178
```
178
-
0 commit comments