1
00:00:05,280 --> 00:00:07,920
At the end of the Program Flow 
Control in Python section, 

2
00:00:07,920 --> 00:00:10,560
we finished with a challenge to 
create a simple menu program. 

3
00:00:11,280 --> 00:00:16,640
I called my program summarychallenge.py. If you've 
been experimenting with the code – and I hope you 

4
00:00:16,640 --> 00:00:21,142
have – you can download summarychallenge.txt 
from the resources for this video. 

5
00:00:21,360 --> 00:00:26,400
Pause the video, while you copy the text, 
and paste it into a new Python file. 

6
00:00:26,400 --> 00:00:33,920
I've called my file summarychallenge.py
Ok, I've got summarychallenge.py open in IntelliJ. 

7
00:00:33,920 --> 00:00:38,377
Before we continue, have a look 
at how simple this code is. 

8
00:00:39,120 --> 00:00:41,920
That code is very basic, but 
you probably struggled a bit 

9
00:00:41,920 --> 00:00:46,283
with the challenge, at the time.
Now you can understand it easily. 

10
00:00:46,400 --> 00:00:50,320
You've come a long way since we 
wrote that code, a few sections ago. 

11
00:00:50,320 --> 00:00:53,600
When you find yourself struggling and are 
getting frustrated, or thinking that you'll 

12
00:00:53,600 --> 00:00:57,520
never get the hang of this, take a break.
Have a look at some of the earlier 

13
00:00:57,520 --> 00:01:00,720
examples that we wrote.
Reviewing the earlier code, 

14
00:01:00,720 --> 00:01:06,087
which you probably also struggled with at the 
time, will show that you are learning a lot. 

15
00:01:07,840 --> 00:01:10,978
It's easy to lose sight of 
that, when you're stuck. 

16
00:01:10,978 --> 00:01:15,280
Focus on how far you've come, and 
you'll get the confidence to continue. 

17
00:01:15,280 --> 00:01:20,960
Alright, pep talk over .
Back in IntelliJ, quite a few students 

18
00:01:20,960 --> 00:01:26,320
spotted a problem with this code. Let's have a 
look at what the problem is, then we'll fix it. 

19
00:01:26,320 --> 00:01:31,192
Run the program,
and we get the menu displayed. 

20
00:01:31,440 --> 00:01:37,687
The program seems to work. When I enter 4, the 
program correctly tells me that I chose option 4. 

21
00:01:37,920 --> 00:01:41,520
The problem's with line 3 of the 
code. That's supposed to restrict 

22
00:01:41,520 --> 00:01:46,400
the input to one of the digits 1 to 5.
It works, as long as we only enter a single 

23
00:01:46,400 --> 00:01:51,920
character. If I enter 8, for example, 
the program doesn't print the choice. 

24
00:01:51,920 --> 00:01:56,800
It just displays the menu again.
"8" isn't in the string "12345", 

25
00:01:56,800 --> 00:02:02,560
and the condition on line 3 is False.
That's also working fine. Where there's a problem, 

26
00:02:02,560 --> 00:02:08,720
is if the user enters something like "123".
The program prints "You chose 123", 

27
00:02:08,720 --> 00:02:14,640
which isn't what we want.
The string "123" is in the string "12345", 

28
00:02:14,640 --> 00:02:19,440
so the condition evaluates to True.
In Python, the empty string is considered 

29
00:02:19,440 --> 00:02:25,040
to be in any other string. That means we also 
get the wrong result, when I just press ENTER. 

30
00:02:25,040 --> 00:02:28,160
We get "You chose ", with 
an empty string after it. 

31
00:02:28,160 --> 00:02:31,600
With what we knew at the time, 
this was the best we could do. 

32
00:02:31,600 --> 00:02:37,360
As I said, we've come a long way since then. 
We can now do better, and fix this bug. 

33
00:02:37,360 --> 00:02:40,080
If we check that the input is 
in a list instead of a string, 

34
00:02:40,080 --> 00:02:49,840
the bug goes away. I'll enter 0 first, 
to stop the program, then change line 3:

35
00:03:00,400 --> 00:03:01,920
If you're not sure what I've done there, 

36
00:03:01,920 --> 00:03:06,800
keep watching. I'll review what the 
list function is doing, in a moment. 

37
00:03:06,800 --> 00:03:11,709
Run the program again, and test that it 
now only allows the values we expect. 

38
00:03:12,800 --> 00:03:16,261
Entering 4 works, and the 
program prints the choice. 

39
00:03:16,320 --> 00:03:22,065
8 also works. The options are printed 
again, by the code on lines 6 to 12. 

40
00:03:22,065 --> 00:03:27,825
The problem was with longer sequences, 
so I'll enter "123" again. This time, 

41
00:03:27,825 --> 00:03:33,243
the program doesn't incorrectly identify that as a 
valid choice – we just get the menu printed again. 

42
00:03:33,243 --> 00:03:37,294
An empty string also isn't in the list 
– pressing ENTER prints the menu out. 

43
00:03:37,360 --> 00:03:43,200
Enter zero to terminate the program.
Ok, that's fixed the bug. The program 

44
00:03:43,200 --> 00:03:47,920
can now reliably check if an option is valid.
I used a list there, because you already know 

45
00:03:47,920 --> 00:03:53,680
about lists. You're only just learning about sets, 
and I didn't want to jump straight in with a set. 

46
00:03:53,680 --> 00:03:58,400
But a set is more appropriate here. We'll get 
it working, then I'll explain why a set is more 

47
00:03:58,400 --> 00:04:04,458
efficient than a list or tuple, when using in.
I'll change list to set, on line 3:

48
00:04:15,440 --> 00:04:20,000
I'll quickly test that, to make sure it works. 

49
00:04:22,400 --> 00:04:27,280
Option 1 is correctly identified as valid, 
and the program prints "You chose 1". 

50
00:04:27,280 --> 00:04:30,654
The same for the other options, 2 to 5. 

51
00:04:31,600 --> 00:04:39,400
Invalid input such as 8 causes the menu to 
be printed again. So does "123" and "345" . 

52
00:04:40,640 --> 00:04:44,102
ENTER also does the right 
thing – we get the menu again. 

53
00:04:44,102 --> 00:04:49,760
0 quits, so that's still working too.
Alright, let's review what we've done there. 

54
00:04:49,760 --> 00:04:54,560
Back in the Lists, Tuples and Ranges section, we 
saw that the list function can be used to create 

55
00:04:54,560 --> 00:04:58,792
a list, from any iterable type.
I'll review that now. 

56
00:04:58,880 --> 00:05:03,447
From the Tools menu, choose 
Python or Debug console.  

57
00:05:05,360 --> 00:05:10,596
We're going to type a few short snippets of code, 
and we don't need to create a new file for this. 

58
00:05:10,596 --> 00:05:13,760
There's no need for you to do this, 
but I'm going to use the cog icon, 

59
00:05:13,760 --> 00:05:18,960
and change the View Mode to Float. That's just to 
keep the Console window clear of the subtitles, 

60
00:05:18,960 --> 00:05:22,909
on the video.
In the console, type:

61
00:05:30,000 --> 00:05:31,360
and press ENTER. 

62
00:05:31,360 --> 00:05:35,869
We get a list containing 5 
strings — the characters '1' to '5'. 

63
00:05:35,869 --> 00:05:41,542
The set function does the same thing. It 
creates a set from any iterable. Enter: 

64
00:05:49,360 --> 00:05:55,280
The output, this time, is a set – notice the 
curly braces, instead of square brackets. 

65
00:05:55,280 --> 00:05:59,200
The items have probably appeared 
in a random order, as well. 

66
00:05:59,200 --> 00:06:02,720
Alright, that's two more 
things we've learnt about sets. 

67
00:06:02,720 --> 00:06:06,240
First, you can use the set 
function to create a new set. 

68
00:06:06,240 --> 00:06:11,134
You pass any iterable object to it, and you'll get 
a set containing all the items in the iterable. 

69
00:06:11,134 --> 00:06:15,840
For example – and still working in the Python 
Console – we can create a set of even numbers, 

70
00:06:15,840 --> 00:06:20,698
by passing a range to the set function. 
I'll type the code to do that: 

71
00:06:31,200 --> 00:06:34,800
Press ENTER, and confirm that we get 
a set containing all the even numbers, 

72
00:06:34,800 --> 00:06:39,840
from 0 to 19. That means the largest 
number in the set will be 18. 

73
00:06:39,840 --> 00:06:45,120
The second thing is, how to test set 
membership. We do that using the in keyword. 

74
00:06:45,120 --> 00:06:49,701
It works the same way as it does for lists 
and strings, which we've seen before. 

75
00:06:49,760 --> 00:06:53,280
If the item is in the set, in evaluates to True. 

76
00:06:53,280 --> 00:06:58,720
Otherwise, in evaluates to False.
We used that – and I'll close the Python Console, 

77
00:06:58,720 --> 00:07:03,920
to go back to summarychallenge.py – on line 3.
Just to be clear what's happening there, 

78
00:07:03,920 --> 00:07:08,385
I'll comment out that line, 
and use a set literal instead: 

79
00:07:28,960 --> 00:07:32,560
That does the same thing.
If the user's choice is in the set, 

80
00:07:32,560 --> 00:07:38,960
the condition evaluates to True. If it's not 
in the set, the condition evaluates to False. 

81
00:07:38,960 --> 00:07:43,600
On line 3, which is now commented out, we used 
the set function to create a set containing 

82
00:07:43,600 --> 00:07:48,080
the valid characters we'd accept.
On line 4, we use a set literal to 

83
00:07:48,080 --> 00:07:53,440
create a set containing the same characters.
In both cases, we check if the user's choice is 

84
00:07:53,440 --> 00:07:58,480
in the set, and only print the message if it is.
I still haven't explained why a set can give 

85
00:07:58,480 --> 00:08:01,760
better performance – although you might 
have guessed, when we talked about 

86
00:08:01,760 --> 00:08:09,040
accessing keys in a dictionary, earlier.
We'll look at that, in the next video.

