1
00:00:00,350 --> 00:00:08,000
Okay, we have some more code to go. We
have defined the view, the search, and the add

2
00:00:08,000 --> 00:00:13,410
buttons, so now we have the delete,
the update, and the close button, and I would

3
00:00:13,410 --> 00:00:17,609
like to continue with the delete button
because the delete button is easier to

4
00:00:17,609 --> 00:00:29,279
implement than the update button, so let me
call the interface again. And again think

5
00:00:29,279 --> 00:00:34,440
about the user, and what will user might
expect is they may want to delete

6
00:00:34,440 --> 00:00:39,930
one of the rows. Let's say this row.
So they expect to select this row,

7
00:00:39,930 --> 00:00:43,530
and then they press the delete
selected button

8
00:00:43,530 --> 00:00:49,530
and this row will disappear from the
database, and they may also want to when they

9
00:00:49,530 --> 00:00:56,460
select row they may also want to see
the data in these entries. And we will

10
00:00:56,460 --> 00:01:00,510
take care of that too, so we will fill
these entries with the corresponding

11
00:01:00,510 --> 00:01:06,510
values when the user clicks one of the
rows here. Alright, that makes sense I

12
00:01:06,510 --> 00:01:14,430
believe. And now let's look at the delete
function in the backend script, so what

13
00:01:14,430 --> 00:01:21,210
delete does is it expects for an ID,
the ID of the row, and then this SQL

14
00:01:21,210 --> 00:01:27,479
statement then looks for this ID and
deletes the entire row of the book table

15
00:01:27,479 --> 00:01:35,159
where the ID is equal to this given ID
here, so what we need to do is when the

16
00:01:35,159 --> 00:01:40,170
user selects one of the rows in the
list box, we need to grab the ID of that

17
00:01:40,170 --> 00:01:46,820
row and then that send back ID to the delete
function over the backend script.

18
00:01:46,820 --> 00:01:55,350
And then the delete function takes care
of the row. Oh good, and again in this

19
00:01:55,350 --> 00:02:01,340
case you do also want to append some
sort of delete command function to the,

20
00:02:01,340 --> 00:02:06,840
here, to the delete button, but in this
case I would actually like to do

21
00:02:06,840 --> 00:02:12,569
a button-up approach, so let's first think
of how we're going to get the row

22
00:02:12,569 --> 00:02:19,469
selected by the user.
So let's think about that first, and you

23
00:02:19,469 --> 00:02:24,739
don't know probably, but there is a method
called bind of the tkinter library and

24
00:02:24,739 --> 00:02:32,730
bind is used to bind a function
to a widget event. So let me write the bind

25
00:02:32,730 --> 00:02:36,810
method, so that you understand things
better, so we all we are binding a method

26
00:02:36,810 --> 00:02:43,409
here to the list box widget, so it makes
sense to write that method after way we

27
00:02:43,409 --> 00:02:50,099
have defined the list widget, so we
define this widget here and we configure

28
00:02:50,099 --> 00:02:57,060
it and then list1 dot bind and
the bind method that takes two arguments.

29
00:02:57,060 --> 00:03:01,799
So it takes the event type and
also it takes the function that you want

30
00:03:01,799 --> 00:03:08,909
to bind to the event type. And the event
type here actually goes inside these

31
00:03:08,909 --> 00:03:18,540
characters and it's called ListboxSelect.
And then you want to specify a function

32
00:03:18,540 --> 00:03:24,780
here that returns a list object
with the selection, so something like this.

33
00:03:24,780 --> 00:03:32,479
Actually we will expect a tuple in
this case, a tuple with the ID, the title,

34
00:03:32,479 --> 00:03:39,349
the author, and the year, and the ISBN
number, so let's call that function

35
00:03:39,349 --> 00:03:50,790
get selected row. Okay, and then we go
ahead and define that function.

36
00:03:50,790 --> 00:03:59,489
Let's define it in the very beginning here.
So def get selected row and this function now

37
00:03:59,489 --> 00:04:04,859
because we have bind it to an event,
to a widget event, this function gets

38
00:04:04,859 --> 00:04:09,449
a special parameter called event, and the
event parameter holds the information

39
00:04:09,449 --> 00:04:16,470
about the type of the event.
So Python knows that when you pass these

40
00:04:16,470 --> 00:04:25,380
to the bind method it expects the
function to have this event parameter.

41
00:04:25,380 --> 00:04:30,750
Then, so again this function will return the
tuple, the selected tuple, but first of

42
00:04:30,750 --> 00:04:36,390
all the way this works is that we
first need to get the index of the list

43
00:04:36,390 --> 00:04:41,460
from the list box. You know the list may have
let's say 10 rows and the first row

44
00:04:41,460 --> 00:04:48,570
will have an index of 0, the second an index
of 1 and so on up to 9 if we have 10 rows.

45
00:04:48,570 --> 00:04:56,850
So to get the index of the selected
row of the list box we refer to the listbox,

46
00:04:56,850 --> 00:05:05,040
and then to the cur selection method
of the list box, all right, and I

47
00:05:05,040 --> 00:05:11,490
would actually like to just make a
a temporary return of the index here so that

48
00:05:11,490 --> 00:05:18,350
you see what this object is, and how it
looks like. So let's hope this will work!

49
00:05:18,350 --> 00:05:28,220
It should work.
Python frontend, yeah and so view all.

50
00:05:28,220 --> 00:05:34,440
Actually we should have printed out
the index here. We are just returning it,

51
00:05:34,440 --> 00:05:45,440
so print index and let's try this out again.
So I expect to print other index here.

52
00:05:45,440 --> 00:05:54,560
Yeah, so this is the index of the
selected row, so this is row 1, sorry 0

53
00:05:54,560 --> 00:06:04,919
with index 0, 1, 2 and so on. However as you
see this is not a plain normal, this is

54
00:06:04,919 --> 00:06:11,400
actually a tuple, a tuple with one item.
So what we need to do is a very simple

55
00:06:11,400 --> 00:06:18,810
trick, and we just grab the item with
index 0 of the tuple which is number 2

56
00:06:18,810 --> 00:06:22,400
in this case,
0 in this case, and so on and then we

57
00:06:22,400 --> 00:06:32,319
might try this again. View all.
And now we get single numbers. Great, so

58
00:06:32,319 --> 00:06:36,819
we're very close but not there yet
because we need to get the actual tuple

59
00:06:36,819 --> 00:06:42,219
with all the values of the row and to
get that you need to apply another

60
00:06:42,219 --> 00:06:49,659
method called get, so let's say
a selected tuple, so the actual tuple

61
00:06:49,659 --> 00:06:55,270
that we want, the actual row
that we want is equal to list1 dot get

62
00:06:55,270 --> 00:07:03,009
index, so you can read it like this.
From the listbox get the tuple

63
00:07:03,009 --> 00:07:14,909
with index x and then we can try this
out so what are we getting here?

64
00:07:14,909 --> 00:07:21,310
Don't get confused with this row, this
is being printed out because in the

65
00:07:21,310 --> 00:07:27,129
backend script we actually have a search
function being printed out, so this is

66
00:07:27,129 --> 00:07:31,659
printing the output of the search
function, so this function is saying give

67
00:07:31,659 --> 00:07:38,680
me the row with John Smith as author
name, and next time this will not be

68
00:07:38,680 --> 00:07:47,770
executed, so back. What we want to do is
select a row and we get the row printed

69
00:07:47,770 --> 00:07:57,310
out there as a tuple, so that is great.
So what's next? Well next is we need to pass

70
00:07:57,310 --> 00:08:04,409
the ID of the selected tuple to the
delete function of the backend script.

71
00:08:04,409 --> 00:08:17,949
we go to the delete selected button.
Command equals delete command. That's how

72
00:08:17,949 --> 00:08:27,940
I'm gonna call the script, and that
should be oh here. Def delete command.

73
00:08:27,940 --> 00:08:39,310
And what we have here is backend dot
delete, and again the delete method gets

74
00:08:39,310 --> 00:08:47,050
as argument the ID, so we have a tuple
called get selected row, so we need to

75
00:08:47,050 --> 00:08:53,770
return, return the selected tuple so if
we call the function now get selected row.

76
00:08:53,770 --> 00:09:06,270
Selected row, and we need the item
with index 0 from the get selected row.

77
00:09:06,270 --> 00:09:17,500
So save the script. And we got an error
at line 24. I don't have the colon here.

78
00:09:17,500 --> 00:09:29,830
Try out again. View and let's try to delete
"The Moon", delete and Python is saying that

79
00:09:29,830 --> 00:09:35,260
get selected row is missing one
required positional argument and that's

80
00:09:35,260 --> 00:09:43,360
the event argument, and so python is right
because here we have an event parameter,

81
00:09:43,360 --> 00:09:49,150
so we need to pass that as an argument.
But here we are calling the function

82
00:09:49,150 --> 00:09:54,640
without any argument, so we're getting an
error, on the other and we cannot remove

83
00:09:54,640 --> 00:10:03,040
this event because this function is also
being executed by the bind method so in

84
00:10:03,040 --> 00:10:09,550
that case the hero of the day here would
be a global variable, so you might

85
00:10:09,550 --> 00:10:14,620
already know that local variables like
the selected tuple is a local

86
00:10:14,620 --> 00:10:21,570
variable because it's defined inside
a function, so if you print this tuple

87
00:10:21,570 --> 00:10:27,850
outside the function select a tuple, you'll
get an error because Python will say

88
00:10:27,850 --> 00:10:34,180
sorry I don't recognize this. This is an
undefined object because local variables

89
00:10:34,180 --> 00:10:40,730
make sense only inside the function, so in
that case we can use global variables,

90
00:10:40,730 --> 00:10:47,740
and the way to create a global variable
is by using the global keyword and then

91
00:10:47,980 --> 00:10:54,560
declaring the name of the variable that
you want to create, so in that case if

92
00:10:54,560 --> 00:10:59,870
you print out the selected tuple outside
the function, you'll get the value of the

93
00:10:59,870 --> 00:11:05,170
selected tuple, and the value of the
selected tuple in this case it would be

94
00:11:05,170 --> 00:11:12,139
the tuple with the values of the row.
So in that case we don't need to return the

95
00:11:12,139 --> 00:11:16,970
selected tuple because we can simply
point to the selected tuple variable in

96
00:11:16,970 --> 00:11:25,579
that case, and we need to fix our delete
function here. So we want selected tuple.

97
00:11:25,579 --> 00:11:34,670
And we want the item with index 0 from
the selected tuple, so let's execute again.

98
00:11:34,670 --> 00:11:46,490
View all and let's delete "The Moon".
Delete selected, view all and "The Moon"

99
00:11:46,490 --> 00:11:55,310
is gone, so it seems to be working.
Now I'd also want to fill the entries

100
00:11:55,310 --> 00:12:03,410
with a selected tuple or row if you like.
So we need to use the insert function

101
00:12:03,410 --> 00:12:09,410
of the entry widget, and we could actually
write those methods inside the get selected

102
00:12:09,410 --> 00:12:14,660
row function because you know when
the user clicks one of the rows, when they

103
00:12:14,660 --> 00:12:19,040
select one of the rows we immediately
want to fill those entries with values.

104
00:12:19,040 --> 00:12:24,500
And the first would be the title
and we want to make sure the entry is

105
00:12:24,500 --> 00:12:29,810
empty, so delete 0 to end, delete
everything from the entry if there is

106
00:12:29,810 --> 00:12:39,620
something, and then e1 insert. So what we
want to insert in the author entry?

107
00:12:39,620 --> 00:12:50,000
Well that would be the selected tuple
with the index of 1, so the ID has an index

108
00:12:50,000 --> 00:12:59,480
of 0, the title has an index of 1.
And this would be the same for the other

109
00:12:59,480 --> 00:13:15,860
entries as well, so we have e1, e2, e3, and e4.
And then here we want to grab the author name.

110
00:13:15,860 --> 00:13:26,060
Here we want the year, and the
ISBN number in here. Great, so I hope this

111
00:13:26,060 --> 00:13:32,840
will work. It should work, so view all
select something and insert method

112
00:13:32,840 --> 00:13:39,530
is missing one required argument.
I think I forgot to put where I want to

113
00:13:39,530 --> 00:13:56,990
insert the new values, so we need to end
here, here, here and here. So let's see

114
00:13:56,990 --> 00:14:06,620
again. View all, and now it seems to be
working, so "Trees and Grass", Ben Sand

115
00:14:06,620 --> 00:14:15,910
and so on, and let me try to delete this.
Delete, view all, and the entry is gone.

116
00:14:15,910 --> 00:14:22,400
Great, so now let's go ahead without wasting
any time. Let's go ahead and implement

117
00:14:22,400 --> 00:14:28,220
the update function so back to our backend
script. The update function gets an ID,

118
00:14:28,220 --> 00:14:34,880
and title, author, year, and ISBN.
So unlike the delete function which only

119
00:14:34,880 --> 00:14:43,850
got one item. This gets four items, five
items actually, so in the delete command

120
00:14:43,850 --> 00:14:51,080
function we pass the selected tuple
with an index of 0. Now the update

121
00:14:51,080 --> 00:14:59,540
function will be similar, similar structure
but then we will have multiple

122
00:14:59,540 --> 00:15:06,590
arguments here, so we have ID title,
author, year and ISBN, so selected tuple

123
00:15:06,590 --> 00:15:14,960
with an index of one. Selected tuple with
an index of two. Selected tuple with an

124
00:15:14,960 --> 00:15:27,650
index of three, and selected tuple with
an index of 4, and then we need to add

125
00:15:27,650 --> 00:15:42,200
that function to the update button.
So update command, alright, and I forgot to

126
00:15:42,200 --> 00:15:55,279
change this. Update command. This should
work, so let's see. I've forgotten to pass

127
00:15:55,279 --> 00:16:07,010
the name of the parameter here.
So command equals update command, save and

128
00:16:07,010 --> 00:16:20,050
execute again and view all. Let's try to
update this row, so let's say nine, and

129
00:16:20,050 --> 00:16:28,640
you press update selected and yet
another error. Don't get scared about

130
00:16:28,640 --> 00:16:32,930
errors, the more errors you see, the more
familiar you will become with Python.

131
00:16:32,930 --> 00:16:39,650
It's important to focus on the error to see
what line you're getting the error and try

132
00:16:39,650 --> 00:16:43,850
to understand what type of the error, and the
message you're getting. So in this case

133
00:16:43,850 --> 00:16:49,790
this say delete takes one positional
argument, but five were given.

134
00:16:49,790 --> 00:16:54,980
We didn't execute a delete function here.
we executed the update button which gets

135
00:16:54,980 --> 00:17:05,050
an update command function, and you go to
the update command, so the update command.

136
00:17:05,050 --> 00:17:10,880
Backend delete. That's why we are
getting this error, the update command

137
00:17:10,880 --> 00:17:16,250
is actually executing the delete
method of the backend script, so we want

138
00:17:16,250 --> 00:17:20,110
update instead of delete.
And save the script and execute again.

139
00:17:26,600 --> 00:17:36,809
View all. I want to really update this
number here, so 9 update selected, view all.

140
00:17:36,809 --> 00:17:44,159
And it's not working, and in this case
we're not even getting an error here so

141
00:17:44,159 --> 00:17:52,919
you may feel lost at the moment, so what
you could do in this case is check what you

142
00:17:52,919 --> 00:18:01,519
are returning in your update command
function, so you know that you can

143
00:18:01,519 --> 00:18:06,450
isolate problems by using print
statements, so let's say you want to

144
00:18:06,450 --> 00:18:12,690
check what you are sending to the update
function. I know the problem here,

145
00:18:12,690 --> 00:18:19,940
but just to show you the way you can
troubleshoot things, so print out and

146
00:18:19,940 --> 00:18:28,470
execute this again. View all, get this
"Grasslands", update selected and you

147
00:18:28,470 --> 00:18:36,389
see that the tuple is being printed out
as it is, so this number is not changing.

148
00:18:36,389 --> 00:18:42,799
Actually I didn't change it, so let me
change this again. Let's say 24 and

149
00:18:42,799 --> 00:18:49,019
update selected and so you see that the
number 24 is not being printed out here,

150
00:18:49,019 --> 00:18:55,289
so that means we are sending to the
database this record again, so we're not

151
00:18:55,289 --> 00:19:01,080
sending the updated record. So why is that?
If you have already found it from

152
00:19:01,080 --> 00:19:05,450
earlier when I have an arrow this
function, that's very great.

153
00:19:05,450 --> 00:19:12,029
If you haven't well the reason is that
we are sending to the update method the

154
00:19:12,029 --> 00:19:17,519
selected tuple, and the selected tuple is
the one that the user has selected,

155
00:19:17,519 --> 00:19:22,980
so it's not the actual entry that the
user is sending to the update command,

156
00:19:22,980 --> 00:19:30,389
so in that case we actually want to send
out these values, so the current values

157
00:19:30,389 --> 00:19:37,830
of the entries,
so I'll copy this and paste it just here.

158
00:19:37,830 --> 00:19:44,820
Okay, and the first selected tuple is
the ID, so we want to keep the ID of

159
00:19:44,820 --> 00:19:52,230
the selected row because the user is
changing the other values, not the ID.

160
00:19:52,230 --> 00:20:03,970
And this looks fine, The bracket closes here.
Save so delete this one,

161
00:20:03,970 --> 00:20:11,669
save, execute again.
View all, go to this and let's say 3.

162
00:20:11,669 --> 00:20:20,740
Update selected, view all and 3 is there.
Delete, view all, it goes away.

163
00:20:20,740 --> 00:20:27,279
You can add it again because you have it
in your entries. Add entry and it was added

164
00:20:27,279 --> 00:20:35,409
again and you can see it here.
So everything is working great, and we

165
00:20:35,409 --> 00:20:39,460
want to close this program but the close
button is not working at the moment,

166
00:20:39,460 --> 00:20:45,490
so let's go ahead and implement
that as well, and that's very

167
00:20:45,490 --> 00:20:53,590
straightforward, you just go here and
command equals to. So you want to destroy

168
00:20:53,590 --> 00:20:59,490
the window, right? So window dot destroy.
That's it.

169
00:20:59,490 --> 00:21:08,500
Save the script, try it out. So all these
are working as usual. Close and the

170
00:21:08,500 --> 00:21:16,720
window closes, and you may also want to
put a title to your window, and you use the

171
00:21:16,720 --> 00:21:23,639
WM title method of the window object.
Title and let's say

172
00:21:25,330 --> 00:21:37,120
book store, and you should see
that name in the title bar, so finally

173
00:21:37,120 --> 00:21:42,129
we are done with this program, and I know
there might be things to improve and

174
00:21:42,129 --> 00:21:47,700
I would welcome any suggestions from you
so that we could improve the program.

175
00:21:47,700 --> 00:21:53,980
Programs have versions, so this is
version zero you could say, and I hope you

176
00:21:53,980 --> 00:21:58,200
found this very useful and learned a lot
from this, so I'll talk to you later.

