11# flake8: NOQA E501
22import ast
3+ from random import choice ,randint
34from string import ascii_uppercase
45from typing import List
5- from random import choice ,randint
66
7- from main .text import ExerciseStep ,Page ,MessageStep ,Disallowed ,VerbatimStep , Step
7+ from main .text import ExerciseStep ,Page ,MessageStep ,Disallowed ,VerbatimStep
88
99
1010def generate_board (board_type ):
1111winning = choice ([True ,False ])
12- size = randint (3 ,10 )
12+ size = randint (3 ,9 )
1313char1 = choice (ascii_uppercase )
1414char2 = choice (ascii_uppercase )
1515chars = [char1 ,char2 ,' ' ]
@@ -907,13 +907,13 @@ def generate_inputs(cls):
907907You are already about halfway done with the project. Keep going!
908908 """
909909
910- class Types (Page ):
911910
911+ class Types (Page ):
912912class five_different_types (VerbatimStep ):
913913"""
914- So far we have been working with various kinds of data: strings, lists, numbers and most recently booleans.
915- Python will recognize and treat different values such as `'Hello World'` and `23` differently.
916- We cansee how Python recognizes these values. There is a command `type`that reveals it :
914+ So far we've seen various kinds of data: strings, lists, numbers and booleans.
915+ These are called *types*. Every value has a type which affects how it behaves
916+ and canbe revealed with the `type`function :
917917
918918 __copyable__
919919 __program_indented__
@@ -929,17 +929,19 @@ def program(self):
929929class check_type_manually (VerbatimStep ):
930930"""
931931Python reports first that `type('Hello World')` is `<class 'str'>`. Don't worry about `class` for now.
932- Python is telling us that the type of a string is `str`, which is short for *string*.
932+ `str` is short for *string*.
933933
934- Then `True` is `bool` (short for *boolean*) and `[1, 2, 3]` has type `list`.
934+ Then `True` isa `bool` (short for *boolean*) and `[1, 2, 3]` has type `list`.
935935
936936Note that there are two types for numbers:
937937
938938- `int`, short for 'integer', is for whole numbers, meaning no fractions or decimal points.
939939- `float`, short for 'floating point number', is for numbers with a decimal point and maybe a fractional part
940940
941- In most cases you don't have to worry about the difference, as you can mix the two when doing maths.
942- Let us verify one of these in the shell:
941+ In most cases you don't have to worry about the different types of number, as you can mix the two when doing maths.
942+
943+ Types are values which can be used in various ways, just like other values.
944+ For example, try this in the shell:
943945
944946__program_indented__
945947 """
@@ -950,8 +952,10 @@ class check_type_manually(VerbatimStep):
950952
951953class different_types_look_same (VerbatimStep ):
952954"""
953- Sometimes different types can look the same when printed, even though they are different when evaluated:
955+ Values with different types are usually quite different from each other, but they can look the same when printed,
956+ which can be confusing. Try this:
954957
958+ __copyable__
955959 __program_indented__
956960
957961(You can use `print(repr(123))` and `print(repr('123'))` to tell the difference. What's `repr`? Google it!)
@@ -964,9 +968,12 @@ def program(self):
964968
965969class plus_has_two_meanings (VerbatimStep ):
966970"""
967- Operators such as `+` have different meanings for `str` and `int`:
971+ Different types have different methods and support different operators.
972+ The same method or operator can also mean different things.
973+ For example, see how `+` has different meanings for `str` and `int`:
968974
969- __program_indented__
975+ __copyable__
976+ __program_indented__
970977 """
971978
972979predicted_output_choices = [
@@ -988,7 +995,8 @@ class less_than_has_two_meanings(VerbatimStep):
988995Python automatically figures out the meaning of `+` from the types of the inputs.
989996Similarly `<` acts differently on two strings and two integers:
990997
991- __program_indented__
998+ __copyable__
999+ __program_indented__
9921000 """
9931001
9941002predicted_output_choices = [
@@ -1004,11 +1012,14 @@ def program(self):
10041012
10051013class less_than_sorting_strings (VerbatimStep ):
10061014"""
1007- So `<` acts as the usual" less than" between two integers, because `13` is less than `120`,
1008- but it acts as the dictionary ordering between two strings: `13` is alphabetically after `120`.
1009- Let's see this in more detail. `<` is used by default in the list function `sorted`:
1015+ So `<` acts as the usual' less than' between two integers, because `13` is less than `120`,
1016+ but it acts as the dictionary ordering between two strings: `13` is' alphabetically' after `120`
1017+ because `3` comes after `2`.
10101018
1011- __program_indented__
1019+ See what difference this makes when sorting a list:
1020+
1021+ __copyable__
1022+ __program_indented__
10121023 """
10131024
10141025predicted_output_choices = [
@@ -1044,10 +1055,6 @@ def check(self):
10441055
10451056class fixing_type_errors_with_conversion (ExerciseStep ):
10461057"""
1047- ***Using `+` between a `str` and an `int` is an error!***
1048-
1049- TypeError: unsupported operand type(s) for +: 'int' and 'str'
1050-
10511058Using a string instead of an integer in `range` like `range('5')`,
10521059or in list subscripting like `list['3']` will also lead to an error.
10531060
@@ -1061,7 +1068,7 @@ class fixing_type_errors_with_conversion(ExerciseStep):
10611068 __copyable__
10621069 number = '3'
10631070 for i in range(number):
1064- print('Starting... ' +( i + 1) )
1071+ print('Starting... ' + i + 1)
10651072 print('Go!')
10661073
10671074The correct program should print:
@@ -1077,7 +1084,9 @@ class fixing_type_errors_with_conversion(ExerciseStep):
10771084
10781085hints = """
10791086At what points is this code broken?
1080- Use the type functions on the broken variables to convert the wrong types to the correct ones!
1087+ There are values that need to be converted to a different type.
1088+ Specifically there's a `str` that needs to be converted to an `int`.
1089+ And an `int` that needs to be converted to a `str`.
10811090 """
10821091
10831092tests = [
@@ -1098,6 +1107,8 @@ class fixing_type_errors_with_conversion(ExerciseStep):
10981107 """ ),
10991108 ]
11001109
1110+ disallowed = Disallowed (ast .JoinedStr ,label = "f-strings" )
1111+
11011112def solution (self ,number :str ):
11021113for i in range (int (number )):
11031114print ('Starting... ' + str (i + 1 ))
@@ -1184,6 +1195,11 @@ def generate_inputs(cls):
11841195 ]
11851196
11861197final_text = """
1187- You learned about types in Python and how to avoid common type problems by converting types.
1198+ Excellent!
1199+
1200+ By the way, when you need to concatenate strings and numbers, remember that you can also
1201+ use f-strings. They often look nicer.
1202+
1203+ You've learned about types in Python and how to avoid common errors by converting types.
11881204Keep going with the rest of the project!
11891205 """