0
1
00:00:00,890 --> 00:00:01,190
All right.
1

2
00:00:01,220 --> 00:00:03,730
So this just one last thing left to do.
2

3
00:00:03,840 --> 00:00:09,540
If we were baking a cake, we wouldn't need to tidy up and wash everything and make sure that we're leaving
3

4
00:00:09,540 --> 00:00:13,230
the place as brand spanking clean as we found it.
4

5
00:00:13,320 --> 00:00:19,960
And in our case, we need to tidy up our code so that if we come back to it in a month or in a year or
5

6
00:00:19,960 --> 00:00:24,990
if somebody else were to collaborate with us on this project that they actually understand what's going
6

7
00:00:24,990 --> 00:00:28,460
on and it's not a whole jumble of mess.
7

8
00:00:28,500 --> 00:00:34,330
So the first thing that we should try to eliminate are places where we have a lot of hard coding.
8

9
00:00:34,680 --> 00:00:36,960
So one of the most obvious ones is this
9

10
00:00:36,990 --> 00:00:40,730
count number here, because why would it be?
10

11
00:00:40,740 --> 00:00:48,060
Because safe in the future, we decided to upgrade our Twitter API membership to their premier or enterprise
11

12
00:00:48,330 --> 00:00:55,380
versions and we stopped paying them so that we can get more tweets back in the same query, say, a thousand tweets
12

13
00:00:55,380 --> 00:00:56,910
or 10,000 tweets.
13

14
00:00:56,910 --> 00:00:59,320
Then we don't want to be digging through this count
14

15
00:00:59,340 --> 00:01:05,010
and also here in the for loop changing it or forgetting to change it which is even worse because we'll
15

16
00:01:05,010 --> 00:01:07,740
end up with bug that we don't know the reason for.
16

17
00:01:07,770 --> 00:01:14,400
So let's make sure that we change this into a constant up here so that when we decide to update that,
17

18
00:01:14,490 --> 00:01:15,840
we can easily find it.
18

19
00:01:15,990 --> 00:01:27,210
So let's call it something like tweetCount and let's set it to 100, and we can replace it
19

20
00:01:27,230 --> 00:01:32,380
now over here, and also inside our for loop.
20

21
00:01:32,420 --> 00:01:32,660
All right.
21

22
00:01:32,690 --> 00:01:38,830
So that's one thing checked off, removing some hardcoding.
22

23
00:01:38,860 --> 00:01:45,310
Now, the next thing that we need to do is to make some methods and split up the functionality of our code
23

24
00:01:45,640 --> 00:01:52,690
so that it's not all inside our IBAction because having this large a chunk of code, and especially if
24

25
00:01:52,690 --> 00:01:57,400
we're going to add to it, is not great when it comes to debugging.
25

26
00:01:57,490 --> 00:02:02,850
So let's go ahead and move some of this code into some distinct functions.
26

27
00:02:03,430 --> 00:02:13,710
So a function that we might have is something like fetchTweets, and another one that we might have is
27

28
00:02:13,740 --> 00:02:15,360
makePrediction.
28

29
00:02:18,150 --> 00:02:21,930
And finally, we might have one that simply updates the UI,
29

30
00:02:24,910 --> 00:02:30,680
so that in the future if we were to have any problems with fetchingTweets, for example, we weren't getting
30

31
00:02:30,710 --> 00:02:37,460
any tweets back from Twitter, then we would know to look inside here and look for the method that fetches
31

32
00:02:37,460 --> 00:02:38,090
our tweets.
32

33
00:02:38,630 --> 00:02:43,690
And if we had problems with making the prediction, then equally, we can navigate to this method.
33

34
00:02:43,790 --> 00:02:46,450
And this just makes our code so much more manageable
34

35
00:02:46,490 --> 00:02:53,090
and a lot more modular. So let's move the part that fetches our tweets which currently it's kind of all
35

36
00:02:53,090 --> 00:02:55,010
entangled with the predictions.
36

37
00:02:55,010 --> 00:03:00,540
So I'm going to take everything inside our IBAction here and I'm just going to cut it and I'm going
37

38
00:03:00,540 --> 00:03:03,920
to paste it into our function fetchTweets.
38

39
00:03:03,920 --> 00:03:10,010
Now, be sure to remember to actually call fetchTweets, so that when the user presses the predict button,
39

40
00:03:10,310 --> 00:03:13,610
it actually goes to this function.
40

41
00:03:13,640 --> 00:03:17,930
Now, inside this function, the parts that make the prediction,
41

42
00:03:17,930 --> 00:03:24,050
I'm going to take away and put it into the makePrediction function.
42

43
00:03:24,050 --> 00:03:30,380
So I'm going to take this entire "do catch" block, so everything that's involved in making the prediction
43

44
00:03:30,890 --> 00:03:37,520
and place it inside the function, that is our makePrediction function.
44

45
00:03:37,520 --> 00:03:46,400
So, now our fetchTweets function only has enough functionality to search Twitter and make the request
45

46
00:03:46,400 --> 00:03:53,570
to fetchTweets from the Twitter API. And in our makePrediction function, we're able to do all of the
46

47
00:03:53,570 --> 00:03:55,700
rest which needs further splitting up.
47

48
00:03:56,180 --> 00:04:02,930
But before we do that, we have one problem where it says, "Use of unresolved identifier 'tweets.'"
48

49
00:04:02,930 --> 00:04:11,000
And that's because when that code was over here, we had our tweets right up here which we appended to
49

50
00:04:11,120 --> 00:04:12,890
inside our for loop.
50

51
00:04:13,250 --> 00:04:19,160
But now what we have to do is we need to call our makePrediction here,
51

52
00:04:19,160 --> 00:04:27,770
and so that it triggers this method, and we're going to pass in this tweet array. So this makePrediction
52

53
00:04:27,830 --> 00:04:32,750
is going to take a single parameter and I'm going to call it with tweets.
53

54
00:04:32,750 --> 00:04:37,970
So this is going to be of type TweetSentimentClassifierInput array.
54

55
00:04:38,360 --> 00:04:43,400
And when we call the method, we're going to use the external parameter. And inside the function, we're
55

56
00:04:43,400 --> 00:04:46,250
still going to use the same parameter called tweets,
56

57
00:04:46,310 --> 00:04:48,460
so that gets put over here.
57

58
00:04:48,470 --> 00:04:51,700
Now, when we call this method, we, of course, now have to use "with."
58

59
00:04:52,400 --> 00:04:59,660
And the thing that it is expecting is of type TweetSentimentClassifierInput array which is, of course,
59

60
00:04:59,840 --> 00:05:00,560
our tweets
60

61
00:05:03,840 --> 00:05:04,260
All right.
61

62
00:05:04,290 --> 00:05:05,650
So that's fixed, that part.
62

63
00:05:06,180 --> 00:05:13,050
Now, the next thing we need to do is once we've gotten our sentimentScore, we need to update the UI, and
63

64
00:05:13,110 --> 00:05:16,710
all of that is inside this section here.
64

65
00:05:16,770 --> 00:05:24,780
And so let's go ahead and cut that and paste it into our updateUI method, so that we know the part, so
65

66
00:05:24,780 --> 00:05:29,870
that it's separated from the functionality of making predictions.
66

67
00:05:29,880 --> 00:05:31,430
Now, we have another problem here,
67

68
00:05:31,470 --> 00:05:39,540
namely that the sentimentScore doesn't exist outside of the scope of makePrediction because we created
68

69
00:05:39,540 --> 00:05:40,980
it in here.
69

70
00:05:40,980 --> 00:05:46,320
Now, one of the ways of solving this, that we've done previously when we had less experience with Swift,
70

71
00:05:46,680 --> 00:05:49,640
is to simply make this a global variable
71

72
00:05:49,680 --> 00:05:56,320
and while that's very, very easy to do. Having a global variable comes with some of its own problems.
72

73
00:05:56,340 --> 00:06:01,000
For example, if you have a global variable inside your class ViewController,
73

74
00:06:01,170 --> 00:06:07,620
If I create a new object of ViewController, I can affect the value of that global variable.
74

75
00:06:07,620 --> 00:06:12,750
Now, if I have it as a local variable that's only available inside this method,
75

76
00:06:12,750 --> 00:06:17,600
I won't be able to accidentally mess with this value from other classes,
76

77
00:06:17,640 --> 00:06:22,770
and this is an important distinction between global and local variables.
77

78
00:06:22,770 --> 00:06:28,800
Now,if you want to read more about when you should use global and when you should use local variables,
78

79
00:06:29,400 --> 00:06:34,650
in the resources list for this lesson, I've included a link so that you can do some further background
79

80
00:06:34,650 --> 00:06:36,730
reading on this topic.
80

81
00:06:36,780 --> 00:06:42,750
Now, over here, we have to solve the short-term problem of how do we use this local variable 
81

82
00:06:42,750 --> 00:06:43,620
sentimentScore.
82

83
00:06:43,740 --> 00:06:51,120
Well, at the point when we need to call our update UI function which is hereafter the for loop, we're
83

84
00:06:51,120 --> 00:06:57,240
going to call updateUI and we're going to pass in our sentiment score.
84

85
00:06:57,240 --> 00:06:59,910
And that means, of course, we need to update this method,
85

86
00:07:02,650 --> 00:07:10,780
so that it takes a sentimentScore as an integer, and our errors should now go away, because we are calling
86

87
00:07:10,780 --> 00:07:18,280
the method update UI passing in the latest sentimentScore that's tallied up from all 100 tweets, and
87

88
00:07:18,280 --> 00:07:23,490
then that gets passed into this method and gets used in the "if" statement.
88

89
00:07:23,530 --> 00:07:30,160
Now, we just have one error left which is that makePrediction is a method call that we're making inside
89

90
00:07:30,370 --> 00:07:31,570
a closure.
90

91
00:07:31,570 --> 00:07:39,820
So we have to change this to have the "self" marker in front, so that we know explicitly that it's a method
91

92
00:07:39,880 --> 00:07:44,190
in the current class. And now, there you have it.
92

93
00:07:44,580 --> 00:07:52,590
Here's our refactored code eliminating global variables, eliminating any hardcoding, and splitting
93

94
00:07:52,590 --> 00:08:00,300
off our functionality into distinct modules making our code much easier to maintain and to understand
94

95
00:08:00,600 --> 00:08:04,460
when we come back to it or when we collaborate with other people.
95

96
00:08:04,470 --> 00:08:10,470
So, of course, there are further ways of simplifying or shortening the code, but there's always a sweet
96

97
00:08:10,470 --> 00:08:14,180
spot between clarity of code and the length of code.
97

98
00:08:14,190 --> 00:08:21,270
So, personally, I feel like this is acceptable. But if you wish to do further refactoring, then feel free
98

99
00:08:21,390 --> 00:08:29,100
to keep going. Or if you want to add more features to this app and make it even more interesting using
99

100
00:08:29,190 --> 00:08:36,010
your imagination, then I really look forward to all of your creation and seeing them in the Q & A section.
100

101
00:08:36,030 --> 00:08:39,740
Be sure to show off anything fantastic that you've come up with.
101

102
00:08:40,470 --> 00:08:43,060
So that's all from me for this module.
102

103
00:08:43,170 --> 00:08:49,040
I hope to see you in the next module where I'll be back with more project and more challenges.
103

104
00:08:49,350 --> 00:08:50,100
So see you there.
