├── OOP_abstraction.py
├── OOP_encapsulation.py
├── OOP_inheritance.py
├── OOP_polymorphism.py
├── README.md
├── args_kwargs_exercises.js
├── forestfires.csv
├── led_board.py
├── list_dict_comprehension_exercises.md
├── nursery_v1.py
└── rural_fires.csv
/OOP_abstraction.py:
--------------------------------------------------------------------------------
1 | '''
2 | Use an abstract base class (ABC) from Python’s abc module.
3 | This will enforce that all subclasses of Tray must implement the report_status method.
4 | '''
5 |
6 | import sys
7 | from abc import ABC, abstractmethod
8 |
9 | class Tray(ABC):
10 | def __init__(self, species, number_of_plants):
11 | if int(number_of_plants) < 1:
12 | sys.exit('Number of plants has to be at least one')
13 | if type(species) != str:
14 | sys.exit('Species should be a string')
15 | self.species = species
16 | self.number_of_plants = number_of_plants
17 | self.is_usable = True
18 |
19 | def is_empty(self):
20 | return self.number_of_plants == 0
21 |
22 | # Abstract method that must be implemented by subclasses
23 | @abstractmethod
24 | def report_status(self):
25 | pass
26 |
27 | class SingleUseTray(Tray):
28 | def __init__(self, species, number_of_plants):
29 | super().__init__(species, number_of_plants)
30 |
31 | def remove_plants(self):
32 | if not self.is_usable:
33 | sys.exit('This tray cannot be used anymore')
34 | self.is_usable = False
35 | return [Plant(self.species) for _ in range(self.number_of_plants)]
36 |
37 | # Implementation of the abstract method
38 | def report_status(self):
39 | if not self.is_usable:
40 | return "This single-use tray has been used and is now empty."
41 | else:
42 | return f"This single-use tray contains {self.number_of_plants} {self.species} plants and is ready to use."
43 |
44 | class MultipleUseTray(Tray):
45 | def __init__(self, species, number_of_plants):
46 | super().__init__(species, number_of_plants)
47 | self.number_of_uses = 0
48 |
49 | def remove_plants(self, number):
50 | if number > self.number_of_plants:
51 | sys.exit(f'The tray only contains {self.number_of_plants} {self.species}')
52 | self.number_of_plants -= number
53 | return [Plant(self.species) for _ in range(number)]
54 |
55 | def add_seeds(self, number):
56 | if number > 0:
57 | self.number_of_plants += number
58 |
59 | # Implementation of the abstract method
60 | def report_status(self):
61 | if self.is_empty():
62 | return "This multiple-use tray is empty but can be refilled with seeds."
63 | else:
64 | return f"This multiple-use tray has {self.number_of_plants} {self.species} plants and is reusable."
65 |
66 | class Plant:
67 | def __init__(self, species):
68 | if type(species) != str:
69 | sys.exit('Species should be a string')
70 | self.species = species
71 |
72 | def __repr__(self):
73 | return f'{self.species}'
74 |
75 | # Create tray objects
76 | stray = SingleUseTray('Rose', 3)
77 | mtray = MultipleUseTray('Lily', 4)
78 |
79 | # Remove and add to the trays
80 | plants_from_stray = stray.remove_plants()
81 | mtray.add_seeds(2)
82 | plants_from_mtray = mtray.remove_plants(5)
83 |
84 | # Print tray status reports
85 | print(stray.report_status())
86 | print(mtray.report_status())
87 |
--------------------------------------------------------------------------------
/OOP_encapsulation.py:
--------------------------------------------------------------------------------
1 | class Tray:
2 | def __init__(self, seed_type, num_of_seeds):
3 | # Public attributes
4 | self.seed_type = seed_type
5 | self.num_of_seeds = num_of_seeds
6 |
7 | # Private attribute (encapsulation)
8 | self.__growth_stage = "Seed"
9 |
10 | # Public getter method to access the current growth stage
11 | def get_growth_stage(self):
12 | return self.__growth_stage
13 |
14 | # Public setter method to change the growth stage
15 | def set_growth_stage(self, stage):
16 | valid_stages = ["Seed", "Sprout", "Seedling", "Mature Plant"]
17 | if stage in valid_stages:
18 | self.__growth_stage = stage
19 | else:
20 | print(f"Invalid growth stage: {stage}")
21 |
22 | # Public method to simulate plant growth
23 | def grow_plants(self):
24 | if self.__growth_stage == "Seed":
25 | self.__growth_stage = "Sprout"
26 | elif self.__growth_stage == "Sprout":
27 | self.__growth_stage = "Seedling"
28 | elif self.__growth_stage == "Seedling":
29 | self.__growth_stage = "Mature Plant"
30 | else:
31 | print("Plants are already fully grown!")
32 |
33 | # Example usage
34 | tray = Tray("Tomato", 30)
35 | print("Seed Type:", tray.seed_type)
36 | print("Number of Seeds:", tray.num_of_seeds)
37 | print("Current Growth Stage:", tray.get_growth_stage())
38 |
39 | # Using the setter to update growth stage
40 | tray.set_growth_stage("Seedling")
41 | print("Growth Stage after setter:", tray.get_growth_stage())
42 |
43 | # Simulate plant growth
44 | tray.grow_plants()
45 | print("Growth Stage after growing:", tray.get_growth_stage())
46 |
--------------------------------------------------------------------------------
/OOP_inheritance.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | class Tray:
4 | def __init__(self,species,number_of_plants):
5 | if int(number_of_plants) < 1:
6 | sys.exit('Number of plants has to be at least one')
7 | if type(species)!=str:
8 | sys.exit('Species should be a string')
9 | self.species=species
10 | self.number_of_plants=number_of_plants
11 | self.is_usable=True
12 |
13 | def is_empty(self):
14 | return self.number_of_plants == 0
15 |
16 | def __repr__(self):
17 | return f'This tray has {self.number_of_plants} {self.species}'
18 |
19 | class SingleUseTray(Tray):
20 | def __init__(self,species,number_of_plants):
21 | super().__init__(species,number_of_plants)
22 |
23 | def remove_plants(self): # self refers to the object of the class
24 | if not self.is_usable:
25 | sys.exit('This tray cannot be used anymore')
26 | plants = [Plant(self.species) for _ in range(self.number_of_plants)]
27 | self.is_usable=False
28 | self.number_of_plants= 0
29 | return plants
30 |
31 | class MultipleUseTray(Tray):
32 | def __init__(self,species,number_of_plants):
33 | super().__init__(species,number_of_plants)
34 | self.number_of_uses=0
35 |
36 | def remove_plants(self, number): # self refers to the object of the class
37 | if number > self.number_of_plants:
38 | sys.exit(f'The tray only contains {self.number_of_plants} {self.species}')
39 | self.number_of_plants = self.number_of_plants-number
40 | return [Plant(self.species) for _ in range(number)]
41 |
42 | def add_seeds(self,number):
43 | if (number>0):
44 | self.number_of_plants += number
45 |
46 | class Plant:
47 | def __init__(self,species):
48 | if type(species)!=str:
49 | sys.exit('Species should be a string')
50 | self.species=species
51 |
52 | def __repr__(self):
53 | return f'{self.species}'
54 |
55 |
56 | # create tray objects
57 | stray=SingleUseTray('Rose',3)
58 | mtray=MultipleUseTray('Lily',4)
59 | # remove and add to the trays
60 | plants_from_stray=stray.remove_plants()
61 | mtray.add_seeds(2)
62 | plants_from_mtray=mtray.remove_plants(5)
63 | # print tray contents
64 | print(stray)
65 | print(mtray)
66 |
--------------------------------------------------------------------------------
/OOP_polymorphism.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | class Tray:
4 | def __init__(self,species,number_of_plants):
5 | if int(number_of_plants) < 1:
6 | sys.exit('Number of plants has to be at least one')
7 | if type(species)!=str:
8 | sys.exit('Species should be a string')
9 | self.species=species
10 | self.number_of_plants=number_of_plants
11 | self.is_usable=True
12 |
13 | def is_empty(self):
14 | return self.number_of_plants == 0
15 |
16 | def __repr__(self):
17 | return f'This tray has {self.number_of_plants} {self.species}'
18 |
19 | class SingleUseTray(Tray):
20 | def __init__(self,species,number_of_plants):
21 | super().__init__(species,number_of_plants)
22 |
23 | def remove_plants(self): # self refers to the object of the class
24 | if not self.is_usable:
25 | sys.exit('This tray cannot be used anymore')
26 | self.is_usable=False
27 | return [Plant(self.species) for _ in range(self.number_of_plants)]
28 |
29 | # example of polymorphism
30 | def __repr__(self):
31 | return f'This single use tray has {self.number_of_plants} {self.species}'
32 |
33 |
34 | class MultipleUseTray(Tray):
35 | def __init__(self,species,number_of_plants):
36 | super().__init__(species,number_of_plants)
37 | self.number_of_uses=0
38 |
39 | def remove_plants(self, number): # self refers to the object of the class
40 | if number > self.number_of_plants:
41 | sys.exit(f'The tray only contains {self.number_of_plants} {self.species}')
42 | self.number_of_plants = self.number_of_plants-number
43 | return [Plant(self.species) for _ in range(number)]
44 |
45 | def add_seeds(self,number):
46 | if (number>0):
47 | self.number_of_plants += number
48 |
49 | class Plant:
50 | def __init__(self,species):
51 | if type(species)!=str:
52 | sys.exit('Species should be a string')
53 | self.species=species
54 |
55 | def __repr__(self):
56 | return f'{self.species}'
57 |
58 |
59 | # create tray objects
60 | stray=SingleUseTray('Rose',3)
61 | mtray=MultipleUseTray('Lily',4)
62 | # remove and add to the trays
63 | plants_from_stray=stray.remove_plants()
64 | mtray.add_seeds(2)
65 | plants_from_mtray=mtray.remove_plants(5)
66 | # print tray contents
67 | print(stray)
68 | print(mtray)
69 |
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Introduction to Python 2024/2025
2 |
3 | Masters in Data Science applied to agricultural and food sciences, environment, and forestry engineering.
4 |
5 | Instructor: Manuel Campagnolo (mlc@isa.ulisboa.pt)
6 |
7 | Teaching assistant: Dominic Welsh (djwelsh@edu.ulisboa.pt)
8 |
9 |
10 |
11 |
12 | # Online resources for the course
13 |
14 |
15 |
16 | * **Required:** [CS50’s Introduction to Programming with Python](https://cs50.harvard.edu/python/2022): lectures (videos and notes), problems sets, shorts; The platform allows you to test your code at the [CS50 codespace](https://cs50.dev/) for the proposed problems (you need to have your own GitHub account to access the codespace).
17 | * Python Programming course at [PP.fi](https://programming-23.mooc.fi/): same features as CS50 but to test your solutions to problems you are required to pass previous tests
18 | * [Learn Python](https://v2.scrimba.com/learn-python-c03): lectures (videos) and interactive examples and exercises
19 | * [Introduction to Python (VScode)](https://vscodeedu.com/courses/intro-to-python): interactive lectures and exercises
20 | * Basic concepts and features of the Python language and system: [The Python Tutorial at python.org](https://docs.python.org/3/tutorial/index.html).
21 | * Fenix webpage for the course (https://fenix.isa.ulisboa.pt/courses/intpy-283463546571610)
22 | * Moodle (https://elearning.ulisboa.pt/course/view.php?id=9100)
23 |
24 |
25 |
26 |
27 |
28 | #### Comparison of CS50P and PP.fi
29 |
30 |
31 |
32 | | CS50P | Contents | PP.fi | Contents |
33 | | ----------- | ----------- |----------- | ----------- |
34 | | Lecture 0 | Creating Code with Python; Functions; Bugs; Strings and Parameters; Formatting Strings; More on Strings; Integers or int; Readability Wins; Float Basics; More on Floats; Def; Returning Values | Part 1 | Intro; I/O; More about variables; Arithmetic operations; Conditional statements |
35 | | Lecture 1 | Conditionals, if Statements, Control FlowModulo; Creating Our Own Parity Function; Pythonic; match | Part 2 | Programming terminology; More conditionals; Combining conditions; Simple loops |
36 | | Lecture 2 | Loops; While Loops; For Loops; Improving with User Input; More About Lists; Length; Dictionaries, More on code modularity | Part 3 | Loops with conditions; Working with strings; More loops; Defining functions |
37 | | | | Part 4 | The Visual Studio Code editor, Python interpreter and built-in debugging tool; More functions; Lists; Definite iteration; Print statement formatting; More strings and lists |
38 | | | | Part 5 | More lists; References; Dictionary; Tuple |
39 | | Lecture 3 | Exceptions, Runtime Errors, try, else, Creating a Function to Get an Integer, pass | Part 6 | Reading files; Writing files; Handling errors; Local and global variables |
40 | | Lecture 4 | Libraries, Random, Statistics, Command-Line Arguments, slice, Packages, APIs, Making Your Own Libraries| Part 7 | Modules; Randomness; Times and dates; Data processing; Creating your own modules; More Python features |
41 | | Lecture 5 | Unit Tests; assert; pytest; Testing Strings; Organizing Tests into Folders | | |
42 | | Lecture 6| File I/O; open; with; CSV; Binary Files and PIL | | |
43 | | Lecture 7 | Regular Expressions; Case Sensitivity; Cleaning Up User Input; Extracting User Input |||
44 | | Lecture 8 | Object-Oriented Programming; Classes; raise; Decorators; Class Methods; Static Methods; Inheritance; Inheritance and Exceptions; Operator Overloading| Part 8 | Objects and methods; Classes and objects; Defining classes; Defining methods; More examples of classes |
45 | | | | Part 9 | Objects and references; Objects as attributes; Encapsulation; Scope of methods; Class attributes; More examples with classes |
46 | | | | Part 10 | Class hierarchies; Access modifiers; Object oriented programming techniques; Developing a larger application |
47 | | Lecture 9 | set; Global Variables; Constants; Type Hints; Docstrings; argparse; Unpacking; args and kwargs; map; List Comprehensions; filter; Dictionary Comprehensions; enumerate; Generators and Iterators | Part 11 | List comprehensions; More comprehensions; Recursion; More recursion examples |
48 | | | | Part 12 | Functions as arguments; Generators; Functional programming; Regular expressions|
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | # Class 1 (September 13, 2024): data types, variables, functions
57 |
58 |
59 |
60 | 1. Install Python and VS code: https://code.visualstudio.com/docs/python/python-tutorial. Alternatively, you can code in the CS50 cloud environment (VScode). Two steps: 1. log in into your github account; 2. access your code space at https://cs50.dev/. This environment allows you to test automatically your scripts for the CS50 problem sets.
61 | 2. Some useful keyworks for the command line interface (CLI) in terminal:
62 | * `code filename.py` to create a new file
63 | * `ls` to list files in folder
64 | * `cp filename newfilename` to copy a file, e.g. `cp ..\hello.py farewell.py` (`..` represents parent folder)
65 | * `mv filename newfilename` to rename or move file, e.g. `my farewell.py goodbye.py` or `mv farewell.py ..` (move one folder up)
66 | * `rm filename` to delete (remove) file
67 | * `mkdir foldername` to create new folder
68 | * `cd foldername` change directory, e.g. `cd ..`
69 | * `rmdir foldername` to delete folder
70 | * `clear` to clear terminal window
71 | 3. The REPL (interactive Read -Eval-Print-Loop) environment: see https://realpython.com/interacting-with-python/
72 | 4. All values in Python have a **type**. The five basic types are: integer, float, string, Boolean, and None.
73 | * strings (`str`), variables, print (a function), parameters (e.g. `end=`), input, comments, formatted strings (`f"..."`), `.strip()`, `.title` (methods)
74 | * integers (`int`), operations for integers, casting (e.g. `str`to `int`)
75 | * floating point values (`float`), round, format floats (e.g. `f"{z:.2f}`)
76 | * `True`, `False`, `and`, `or`, `not`
77 | 5. Functions, `def`, `return`
78 | 6. Suggested problems: [CS50 Problem set 0](https://cs50.harvard.edu/python/2022/psets/0/)
79 |
80 |
81 |
82 |
83 |
84 |
85 | # Class 2 (September 20, 2024): conditionals, lists, dictionaries
86 |
87 |
88 |
89 | 1. Conditionals:
90 | - `if`, `elif`, `else`:
91 | ```
92 | if score >= 70:
93 | print("Grade: C to A")
94 | elif score >= 60:
95 | print("Grade: D")
96 | else:
97 | print("Grade: F")
98 | ```
99 | - `match`:
100 | ```
101 | match species:
102 | case 'versicolor':
103 | label=0
104 | case 'virginica'
105 | label=1
106 | case _:
107 | label=2
108 | ```
109 | 4. Pythonic coding: `def main()`, define other functions, call `main()`. The code must be modular.
110 | 5. While loops, for loops, `break`, `break` and `return`
111 | 6. Data type *list* `[]`: methods `append`, `extend`
112 | 7. Data type *dictionary* `{}`, `items()`, keys `.key()` and values `.values()`
113 | ```
114 | knights = {'gallahad': 'the pure', 'robin': 'the brave'}
115 | for k, v in knights.items():
116 | print(k, v)
117 | if 'gallahad' in knights:
118 | print('Go Gallahad')
119 | ```
120 | 9. Suggested problems: [CS50 Problem set 1 and 2](https://cs50.harvard.edu/python/2022/psets/). See the assignment on Moodle: problems [File extensions](https://cs50.harvard.edu/python/2022/psets/1/extensions/), [Coke machine](https://cs50.harvard.edu/python/2022/psets/2/coke/), [Plates](https://cs50.harvard.edu/python/2022/psets/2/plates/)
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | # Class 3 (September 27, 2024): exercises, best practices
129 |
130 |
131 |
132 | Exercises from [CS50 Problem set 0, 1 and 2](https://cs50.harvard.edu/python/2022/psets/).
133 |
134 |
135 |
136 |
137 |
138 |
139 | # Class 4 (October 4, 2024): handling exceptions
140 |
141 |
142 |
143 | Handling exceptions in Python: raising and catching exceptions.
144 |
145 | 1. Example from (https://cs50.harvard.edu/python/2022/shorts/handling_exceptions/). Exercise: adapt the proposed code to be more modular, where the main function is something like the one below:
146 |
147 | ```
148 | def main():
149 | spacecraft = input("Enter a spacecraft: ")
150 | au=get_au(spacecraft)
151 | m = convert(au)
152 | print(f"{m} m")
153 | ```
154 |
155 | 2. Exercises from [CS50 Problem set 3](https://cs50.harvard.edu/python/2022/psets/3/).
156 |
157 | For the *fuel gauge* problem (https://cs50.harvard.edu/python/2022/psets/3/fuel/), try to organize your code as follows. As suggested in *hints*, you should catch `ValueError` and `ZeroDivisionError` exceptions in your code. In the code below, the user is being asked for correct values for `x,y` until they satisfy the requirements: `x,y` must be inputted as a string `x/y`, `x` has to be less or equal to `y`, and `y` cannot be zero. The function `get_string_of_integers_X_less_than_Y` in the code below should take care of that.
158 |
159 | ```
160 | def main():
161 | # asks user for input until the input is as expected
162 | x,y=get_string_of_integers_X_less_than_Y()
163 | # compute percentage from two integers
164 | p=compute_percentage(x,y)
165 | # print output
166 | print_gauge(p)
167 | ```
168 |
169 | 3. A few examples of code that can be helpful to solve problems in problem set 3:
170 |
171 | Example of basic use of `try-except` to catch a `ValueError`:
172 | ```
173 | try:
174 | x = int(input("What's x?"))
175 | except ValueError:
176 | print("x is not an integer")
177 | else:
178 | print(f"x is {x}")
179 | ```
180 |
181 | Function for requesting an integer from the user until no exceptions are caught:
182 | ```
183 | def get_int():
184 | while True:
185 | try:
186 | x = int(input("What's x?"))
187 | except ValueError:
188 | print("x is not an integer")
189 | else:
190 | break
191 | return x
192 | ```
193 |
194 | We may want to exit the execution of our script if some exception is caught. This can be done with `sys.exit()`, which can also be used to print a message.
195 | ```
196 | import sys # import module
197 | try:
198 | x = int(input("What's x?"))
199 | except ValueError:
200 | sys.exit("x is not an integer")
201 | ```
202 |
203 | Example of code that catches `CRTL-C` or `CRTL-D`:
204 |
205 | ```
206 | while True:
207 | try:
208 | x=int(input())
209 | except ValueError:
210 | print('x is not integer')
211 | except KeyboardInterrupt: #CTRL-C
212 | print('\n KeyboardInterrupt')
213 | break
214 | except EOFError: # CTRL-D
215 | print('\n EOFError')
216 | break
217 | else:
218 | print(x)
219 | ```
220 |
221 | For a list of Python Built-in Exceptions, you can explore (https://www.w3schools.com/python/python_ref_exceptions.asp)
222 |
223 |
224 |
225 |
226 |
227 | # Class 5 (October 11, 2024): libraries, modules, APIs
228 |
229 |
230 |
231 | ### Modules
232 | You can store your own functions in modules (which are just python scripts) and `import` then into your main code. Let's imagine you created a file named `mymodule.py` in a given folder. In your main script, you can import the file if the folder belongs to list of folders the Python interpreter will look for. You can check that by running the following lines of codes in the Python interpreter:
233 | ```
234 | >>>import sys
235 | >>>sys.path
236 | ```
237 | If the folder where `mymodule.py` was created does not belong to that list, you can add it with `sys.path.append` which allows you to import your module. To that end, you can include the followings lines to your main script:
238 | ```
239 | import sys
240 | sys.path.append(r'path-to-folder') # folder where mymodule is
241 | import mymodule
242 | ```
243 | where `path-to-folder` is the path that you can easily copy in your IDE.
244 |
245 | If your module includes a function named, say, `get_integer`, you can then use the function in your main script either by calling `mymodule.get_integer()` or you can instead load the function with `from mymodule import get_integer` and then just call it with `get_integer()` in the main script as in the following script.
246 | ```
247 | import sys
248 | sys.path.append(r'/workspaces/8834091/modules') # where file mymodule.py is
249 | from mymodule import get_integer
250 | def main():
251 | x=get_integer()
252 | print(x)
253 | main()
254 | ```
255 | Contents of `mymodule.py`:
256 | ```
257 | import sys
258 | def get_integer() -> int:
259 | while True:
260 | try:
261 | return(int(input('type a number: ')))
262 | except ValueError:
263 | print('not an integer number: try again')
264 | except KeyboardInterrupt: #CTRL-C
265 | print('\n If you want to exit type CTRL-D')
266 | except EOFError: # CTRL-D
267 | sys.exit('\n exit as requested')
268 | ```
269 |
270 | Often, you import a module that is available at (https://pypi.org/project/pip/). Say you want to load the module `random` which provides a series of functions for sampling, shuffling, and extracting random numbers from a variety of probability distributions. If the module is not already available, you can typically load it in your terminal with
271 | ```
272 | $pip install random
273 | ```
274 | and then import it on your main script with `import random`. If you want to know which is the folder where the module is located, you can get that information with `random.__file__`.
275 |
276 | ### `sys.argv`
277 | Previously, we used module `sys`, in particular functions `sys.exit()` and `sys.path`. Another useful function is `sys.argv`, that allows you to have access to what the user typed in at the command line `$` as in
278 | ```
279 | import sys
280 | print(len(sys.argv)) # returns the number of words in the command line after $python
281 | print(sys.argv[1]) # returns the 2nd word, i.e., the first word after $python myscript.py
282 | ```
283 |
284 | For instance, the following script named `sum.py` prints the sum of two numbers that were specified in the command line with `$python sum.py 1.2 4.3`:
285 | ```
286 | import sys
287 | try:
288 | x,y = float(sys.argv[1]), float(sys.argv[2])
289 | print('the sum is',x+y)
290 | except IndexError:
291 | print('missing argument')
292 | except ValueError:
293 | print('The arguments are not numbers')
294 | ```
295 | ### APIs
296 | *Application program interfaces* allow you to communicate with a remote server. For instance, `requests` is a package that allows your program to behave as a web browser would. Consider the following script `myrequest.py` that allows you to explore the *itunes* database (https://performance-partners.apple.com/search-api):
297 | ```
298 | import requests
299 | import sys
300 | try:
301 | response = requests.get("https://itunes.apple.com/search?entity=song&limit=1&term=" + sys.argv[1])
302 | print(response.json())
303 | except IndexError:
304 | sys.exit('Missing argument')
305 | except requests.RequestException:
306 | sys.exit('Request failed')
307 | ```
308 | You can easily adapt that code to access a different database. For instance if you want to explore the GBIF database (https://data-blog.gbif.org/post/gbif-api-beginners-guide/), you can just replace the main line of code in `myrequest.py` with
309 | ```
310 | response=requests.get('https://api.gbif.org/v1/species/match?name='+ sys.argv[1])
311 | ```
312 | and execute it with, say, `$python myrequest.py Tracheophyta` in the terminal.
313 |
314 | There are many ways of running an API in Python. The following example shows how you can access satellite imagery through the *Google Earth Engine* API and compute the mean land surface temperature at some location from the MODIS11 product. To be able to use the API, you need to have a Google account, and an earth engine project associated to it.
315 | ```
316 | # pip install earthengine-api
317 | import ee
318 | # Trigger the authentication flow.
319 | ee.Authenticate()
320 | # Initialize the library.
321 | ee.Initialize(project='project-name') # e.g. 'ee-my-mlc-math-isa-utl'
322 | # Import the MODIS land surface temperature collection.
323 | lst = ee.ImageCollection('MODIS/006/MOD11A1')
324 | # Selection of appropriate bands and dates for LST.
325 | lst = lst.select('LST_Day_1km', 'QC_Day').filterDate('2020-01-01', '2024-01-01')
326 | # Define the urban location of interest as a point near Lyon, France.
327 | u_lon = 4.8148
328 | u_lat = 45.7758
329 | u_poi = ee.Geometry.Point(u_lon, u_lat)
330 | scale = 1000 # scale in meters
331 | # Calculate and print the mean value of the LST collection at the point.
332 | lst_urban_point = lst.mean().sample(u_poi, scale).first().get('LST_Day_1km').getInfo()
333 | print('Average daytime LST at urban point:', round(lst_urban_point*0.02 -273.15, 2), '°C')
334 | ```
335 |
336 | ### Problems
337 | Solve problems from CS50P [Problem_set_4](https://cs50.harvard.edu/python/2022/psets/4/). In particular, for problem *Bitcoin price index* organize your code so the main function is the following:
338 |
339 | ```
340 | def main():
341 | x=read_command_line_input()
342 | price=get_bitcoin_price()
343 | print(f"${x*price:,.4f}")
344 | ```
345 |
346 |
347 |
348 |
349 |
350 | # Class 6 (October 18, 2024): virtual environments; file I/O
351 |
352 |
353 |
354 | ### Virtual environments in Python
355 |
356 | A virtual environment (https://docs.python.org/3/library/venv.html) is:
357 | - Used to contain a specific Python interpreter and software libraries and binaries which are needed to support a project (library or application). These are by default isolated from software in other virtual environments and Python interpreters and libraries installed in the operating system.
358 | - Contained in a directory, conventionally named `.venv` or `venv` in the project directory, or under a container directory for lots of virtual environments.
359 | - Not checked into source control systems such as Git.
360 | - Considered as disposable – it should be simple to delete and recreate it from scratch. You don’t place any project code in the environment.
361 | - Not considered as movable or copyable – you just recreate the same environment in the target location.
362 |
363 | In your system you have the *base* environment by default, and you can create one or more *virtual environments*. Below, we describe how to create a virtual environment and how to activate it, so you commands in terminal are interpreted within that environment. That allows you to encapsulate in each virtual environment you create a given Python version, and a set of Python packages with their given versions. Your data and script files remain on the usual working folders: they should not be moved to the folders where the virtual environment files are stored.
364 |
365 | The following commands work in the [CS50 codespace](https://cs50.dev/) that runs Linux (check with `$cat /etc/os-release` in the terminal). Some need to be slightly adapted for Windows.
366 |
367 | Firstly, let's check what are the available packages and their versions in the base environment, and also let's get extra information about the package `requests` (e.g. dependencies):
368 |
369 | ```
370 | $ pip list
371 | $ pip show requests
372 | ```
373 |
374 | Next, let's create a virtual environment. One can first create (with `mkdir`) a folder called, say, `my_venvs` so all the virtual environments are created in that folder. This makes sense since virtual enrironment folders are created independently from the working folders that contain data and scripts. The virtual environment `myvenv` can then be created with:
375 | ```
376 | my_venvs/ $ python3 -m venv myvenv # creates environment called myvenv with Python 3
377 | ```
378 | In case one needs to delete the virtual environment, one just needs to delete the folder. This can be done with `$ sudo rm -rf myvenv` in the terminal (Linux). After the virtual environment has been created, one needs to activate it. In Linux, this is done by executing `activate` which lies in the `bin` folder of the virtual environment:
379 |
380 | ```
381 | my_venvs/ $ source myvenv/bin/activate # note that activate needs to be sourced
382 | ```
383 | As a result, the prompt shows `(myvenv) my_venvs/ $` which indicates that `myvenv` is now activated. One can check the Python version with `$python -V`. To de-activate a virtual environment, the command is `$ deactivate`. With the environment activated, let's try to install a few packages, specifying the versions. For instance, install the following packages.
384 |
385 | ```
386 | (myvenv) my_venvs/ $ pip install random11==0.0.1
387 | (myvenv) my_venvs/ $ pip install geopy==1.23.0
388 | (myvenv) my_venvs/ $ pip install requests==2.25.0
389 | ```
390 | Some of this packages depend on additional packages that are installed automatically. To list all instaled packages within the environment `myvenv` one can execute `(myvenv) $ pip list` as before. Compare the version of `requests` in `myvenv` with the version returned initially in the base environment: this one is 2.25.0 while the one in the base environment is more recent. One can also check where `requests` is installed in `myvenv` with the command `(myvenv) $ pip show requests`.
391 |
392 | Check the system path (where Python will look for installed packages) by executing `print(sys.path)`: one can do this from the terminal with the command
393 | ```
394 | (myvenv) my_venvs/ $ python -c 'import sys; print(sys.path)'
395 | ```
396 | Notice that the folder in `myvenv` where the virtual environment packages are installed is listed, but the path to where base packages are stored is not.
397 |
398 | If one wishes to share a virtual environment, the way to do that is to share a file (typically, `requirements.txt`) that allows a collaborator to re-create the environment. `requirements.txt` stores the information about the installed packages in a file in case one intends to share the environment (e.g. in GitHub). Towards that end, one needs to create `requirements.txt` with the packages names and versions, that can be used to create a clone of the environment on another machine. This is done, still within `myvenv` (i.e. with `myvenv` activated) with the following command:
399 | ```
400 | (myvenv) my_venvs/ $ pip freeze > requirements.txt
401 | ```
402 | Note that the file `requirements.txt` is created in the folder that contains `myvenv` and not within `myvenv` itself: this makes sense, since one does not want to store scripts or data within `myvenv` but just packages and the Python version. Since `requirements.txt` is now available, one can create a copy of `myvenv` called, say, `myvenv2`. Firstly, one needs to de-activate `myvenv`. Then, the commands to be executed in the terminal are:
403 | ```
404 | my_venvs/ $ python3 - m venv myvenv2 # create new virtual environment with the Python 3 interpreter called myvenv2
405 | my_venvs/ $ source myvenv2/bin/activate # activate myvenv2
406 | (myvenv2) my_venvs/ $ pip install -r requirements.txt # install packages and versions listed in requirements.txt
407 | ```
408 |
409 | Exercise: go back to `myvenv`, add package (say, `emoji==0.1.0`), re-build `requirements.txt`, and create new environment `myvenv3` and install the set of packages listed in the new `requirements.txt`.
410 |
411 | ### File I/O
412 |
413 | As discussed in (https://cs50.harvard.edu/python/2022/notes/6/) `open` is a functionality built into Python that allows you to open a file and utilize it in your program. The open function allows you to open a file such that you can read from it or write to it. The most basic way to use `open` allow us to enable file I/O with respect to a given file. In the example below, `w` is the argument value that indicates that the file is open in writing mode. The instruction `file.write(...)` will entirely rewrite the file, deleting the previous contents.
414 | ```
415 | name='Bob'
416 | file = open("names.txt", "w")
417 | file.write(name)
418 | file.close()
419 | ```
420 | As an alternative, if the goal is to add new contents to the file, which is appended to the existent content, then `w` should be replaced by `a` (append). Each call to `file.write(name)` will then add the value of `name` to the end of `file`.
421 |
422 | Instead of explicitly opening and closing a file, it's simpler to use the so-called *context manager* in Python, using the keyword `with`, which automatically closes the file:
423 | ```
424 | with open("names.txt", "w") as f:
425 | f.write(name)
426 | ```
427 | If one wishes to read from a file, then the file has to be opened in reading mode as in the following example. The method `readlines` reads all lines of the file, and stores them in a list, where each element of the list is the contents of the corresponding line.
428 | ```
429 | with open("names.txt", "r") as f:
430 | L=f.readlines(name)
431 | ```
432 | However, it is possible to read one line at the time:
433 | ```
434 | with open('myfile.txt','r') as f:
435 | N=0
436 | for line in f:
437 | N+=1
438 | print('number of lines', N)
439 | ```
440 | Aa an alternative, this can be done with method `readline`. This can be included in a loop to read the whole file. Notice that when the end of the file is reached, `readline` returns the empty string, and this can be easily tested with a condition.
441 |
442 | Reading a file in Python gives the flexibility of visiting any position in the file. The initial position is 0 by default but can be instantiated with `f.seek(n)`. Then, `f.read(10)` for instance reads *n* characters from that initial position. Method `f.tell()` returns the current position in the file.
443 |
444 | A file can be of type *text* (human-readable) or *binary*. Binary files like images for instance are read with `with open('myfile.txt','rb') as f`.
445 |
446 | Exercise: Consider the file downloaded from INE (the Portuguese Institute of Statistics) about causes of fires by geographical location [rural_fires.csv](rural_fires.csv). The source is INE: "Rural fires (No.) by Geographic localization (NUTS - 2013) and Cause of fire; Annual" for 2023. Write a script to read the file and exclude the lines which are not formated as a table (header lines). The formatted lines should be written into a new file, say (`table_rural_fires.csv`).
447 | ```
448 | with open('rural_fires.csv','rb') as f:
449 | with open('table_rural_fires.csv',"w") as fw:
450 | for line in f:
451 | if line[0] in ['1','2','3']: # or smth like line.startswith('1'):
452 | fw.write(line)
453 | ```
454 | Since the file contains non ASCII characters, one might want to try to decode those characters correctly. Note that Python provides methods `encode` and `decode` as in the example below.
455 | ```
456 | str_original = 'ção'
457 | bytes_encoded = str_original.encode(encoding='utf-8')
458 | print(type(bytes_encoded))
459 | str_decoded = bytes_encoded.decode()
460 | print(type(str_decoded))
461 | print('Encoded bytes =', bytes_encoded)
462 | print('Decoded String =', str_decoded)
463 | print('str_original equals str_decoded =', str_original == str_decoded)
464 | ```
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 | # Class 7 (October 25, 2024): tabular data; pandas
473 |
474 |
475 |
476 | ### Create a Pandas DataFrame from scratch
477 |
478 | Pandas dataframes have an intrinsic tabular structure represented by rows and columns where each row and column has a unique *label* (name) and *position* number inside the dataframe. The row labels, called dataframe index, can be integer numbers or string values, the column labels, called column names, are usually strings. Use the following script to create a dataframe with random values. Notice the terminology for rows (`index`) and columns (`columns`).
479 | ```
480 | import pandas as pd
481 | import numpy as np
482 | df = pd.DataFrame(np.random.randn(6, 4), index=list('abcdef'), columns=list('ABCD'))
483 | print(df)
484 | ```
485 | Exercices:
486 |
487 | 1. print the column names of `df` with `.columns`.
488 | 2. Create a `Series` that corresponds to column `A` with `['A']`
489 | 3. Create a new dataframe that corresponds to columns `A` and `C` with `[['A','C']]`.
490 |
491 | Notice that `.columns` returns a `pd.Index` object. This is to provide extra functionality and performance compared to lists. To extract a list of names, one can use `.columns.tolist()` or `.columns.values`.
492 |
493 | ### Reading a csv file, selecting columns by name, selecting rows by condition
494 |
495 | Consider the dataset that described 517 fires from the Montesinho natural park in Portugal. For each incident weekday, month, coordinates, and the burnt area are recorded, as well as several meteorological data such as rain, temperature, humidity, and wind (https://www.kaggle.com/datasets/vikasukani/forest-firearea-datasets). For reference, a copy of the file is available [forestfires.csv](forestfires.csv). The variables are:
496 |
497 | - X - x-axis spatial coordinate within the Montesinho park map: 1 to 9
498 | - Y - y-axis spatial coordinate within the Montesinho park map: 2 to 9
499 | - month - month of the year: "Jan" to "dec"
500 | - day - day of the week: "mon" to "sun"
501 | - FFMC - FFMC index from the FWI system: 18.7 to 96.20
502 | - DMC - DMC index from the FWI system: 1.1 to 291.3
503 | - DC - DC index from the FWI system: 7.9 to 860.6
504 | - ISI - ISI index from the FWI system: 0.0 to 56.10
505 | - temp - the temperature in Celsius degrees: 2.2 to 33.30
506 | - RH - relative humidity in %: 15.0 to 100
507 | - wind - wind speed in km/h: 0.40 to 9.40
508 | - rain - outside rain in mm/m2 : 0.0 to 6.4
509 | - area - the burned area of the forest (in ha): 0.00 to 1090.84
510 |
511 | The goal is to download the file and use package `Pandas` to explore it and solve the following tasks.
512 |
513 | 1. Read the file with `pd.read_csv` into a new object `fires`, and show the first 10 rows with `fires.head(10)`.
514 | 2. Create list of column names and determine column data types with attribute `.dtypes`.
515 | 3. Print a summary of the dataframe with `.info()`.
516 | 4. Create a `Series` with the temperature values for all 517 fires.
517 | 5. Create a `DataFrame` just with columns `month` and `day`.
518 | 6. Select fires for which the temperature is higher than 25 Celsius, and between 20 and 25 Celsius; note that each condition needs to be surrounded by `(...)` and can be connected with `&` or `|` or negated with `~`.
519 | 7. Select fires that occured on weekends; use the conditional function `.isin()`
520 | 8. Check if there are no `Null` values in the dataframe with `.notna()`. You can sum along columns with `.sum()`.
521 |
522 | ### Select rows and columns with loc (label-based indexing) and iloc (positional indexing)
523 |
524 | These are operators to select rows and columns from a dataframe. `loc` selects rows and columns using the row and column *names*. `iloc` uses the *positions* in the table. Notice that new values can be assigned to selections defined with `loc`and `iloc`.
525 |
526 | 1. Interpret the result of `fires.iloc[0:3,2:4]`
527 | 2. Use `loc` and `is.in()` to select fires from August and September and just FWI based variables values for those fires.
528 | 3. Use `iloc` to select the first 20 fires and just the FWI based variables values
529 |
530 | ### Combining positional and label-based indexing
531 |
532 | There are several possibilities to combine positional and label-based indexing:
533 |
534 | 1. (with `iloc`) Using `df.columns.get_loc()` which converts the name of one column into its position. Then `iloc` can be used to perform the selection. For multiple columns determined by a list of column names, one can use instead `df.columns.get_indexer()`. Example: Use `iloc` to select the first 20 fires and just the FWI based variables values, using the names rather than the positions of those variables. Solution: `FWI_positions=fires.columns.get_indexer(['FFMC','DMC','DC','ISI'])` and `
535 | fires.iloc[0:20,FWI_positions]`
536 | 2. (with `loc`) Using `df.index[]` to extract the index names. Then, `loc` can be used to perform the selection. Solution: `fires.loc[fires.index[0:20], ['FFMC', 'DMC', 'DC', 'ISI']]`.
537 |
538 | ### Exporting to file
539 |
540 | Exporting is done with operations named `.to_...` as listed in (https://pandas.pydata.org/docs/user_guide/io.html)
541 |
542 | 1. Export your file as an Excel spreadsheet with `.to_excel("filename.xlsx", sheetname="fires", index=False)`
543 | 2. Read an Excel spreadsheet with: `pd.read_excel("filename.xlsx", sheetname="fires", index=False)`
544 |
545 | ### Use generative AI to help with the following tasks
546 |
547 | 1. Create a dataframe `months_df` from a dictionary: for instance create a dictionary where keys are `jan`, `feb`, `mar`, for all 12 months, and the values are `January`, `February`, `March` and so on.
548 |
549 | ```
550 | month_data = {
551 | 'Month': [
552 | 'January', 'February', 'March', 'April', 'May', 'June',
553 | 'July', 'August', 'September', 'October', 'November', 'December'
554 | ],
555 | 'mth': [
556 | 'jan', 'feb', 'mar', 'apr', 'may', 'jun',
557 | 'jul', 'aug', 'sep', 'oct', 'nov', 'dec'
558 | ]
559 | }
560 | months_df = pd.DataFrame(month_data)
561 | ```
562 |
563 | 2. Merge with new dataframe to get a new variable that contains the full name of the month. See (https://pandas.pydata.org/docs/user_guide/merging.html)
564 |
565 | ```
566 | merged_df = pd.merge(fires, months_df, left_on='month', right_on='mth', how='left')
567 | merged_df.drop(columns='mth', inplace=True)
568 | ```
569 |
570 |
571 |
572 |
573 |
574 |
575 | # Class 8 (November 8, 2024): pandas (cont'd), jupyter notebooks
576 |
577 |
578 |
579 | Create a jupyter notebook for this class. If you're using your CS50 codespace, create a new file in the terminal with `$code mynotebook.ipynb` and follow the suggestions for jupyter notebooks in your codespace session.
580 |
581 | There are many available *cheatsheets* for Pandas that can help visualizing Pandas' functionalities. Since there are many possibilities, a single page cheatsheet is either too limited or too cryptic. This [12-page cheatsheet](https://www.webpages.uidaho.edu/~stevel/cheatsheets/Pandas%20DataFrame%20Notes_12pages.pdf) is pretty self-contained and includes several examples.
582 |
583 | ### Use generative AI to help with the following tasks
584 |
585 | 1. Reduce the `fires` dataframe with method `.groupby` to get just one row per month, and average temperature, average RH, and number of fires per month. The goal is to create a dataframe named `firesbymonth` with columns `avg_temp`, `avg_RH` and `fire_count`. See (https://pandas.pydata.org/docs/user_guide/groupby.html)
586 | 2. What is the effect of adding the method `.reset_index()` to the previous command?
587 | 3. Sort the dataframe `firesbymonth`, such that the 12 rows are ordered by month correctly: `jan`, `feb`, `mar`, and so on.
588 | 4. Create a new column called `conditions` in `firesbymonth` of type string that indicates if a month is `dry&hot`, `dry&cold`, `wet&hot` or `wet&cold`. Use the mean values of `avg_temp` and `avg_RH` to establish the appropriate thresholds. Use method `.apply` and define the function to apply with `lambda`.
589 | 5. Re-organize the information in `fires` into a two-way table that shows the total area of fires per day of the week and per month, where `NaN` are replaced by 0. Towards that end, explore the `.pivot_table` method.
590 |
591 |
592 |
593 |
594 |
595 |
596 | # Class 9 (November 15, 2024): OOP, classes, methods
597 |
598 |
599 |
600 | Suppose that one wants write a script in python using classes to monitor plants at a nursery. Initially plants grow from seeds in trays and one wants to keep track of the trays and number of plants per tray. All plants in a given tray are from the same species. Then, at some point, some plants are transferred from trays to individual pots (one plant per pot). At the end, pots are sold. One wants to track the number of plants of each species that are in the nursery.
601 |
602 | For this type of problem, one wants to mimic entities of the real world (plants, trays, pots, and the nursery) as objects in Python code. Object-oriented programming is an intuitive form of doing so. A class in Python is an object constructor, or a *blueprint* for creating objects.
603 |
604 | The simplest example of class, with very little functionality, is a class to store constant values, which are not supposed to change. When one calls the class `Constants` defined below, an instance of the class with the two properties `MAX_PLANTS_PER_TRAY` and `SALE_PRICE` is created.
605 | ```
606 | class Constants:
607 | MAX_PLANTS_PER_TRAY=50
608 | SALE_PRICE=10
609 |
610 | print(Constants.SALE_PRICE)
611 | ```
612 | However, in general we intent to call the class to create one instance (one object) of the class and set the properties of that object. To indicate the values of the instance properties we use the `__init__` method:
613 | ```
614 | class Plant:
615 | def __init__(self, species):
616 | self.species = species
617 |
618 | my_plant=Plant("Rose") # create instance where property `species` has value `Rose`
619 | print(my_plant.species)
620 | ```
621 | Alternatively, a class can be created with the `@dataclass` decorator, see (https://docs.python.org/3/library/dataclasses.html). In this case, the `__init__` method is set automatically.
622 | ```
623 | from dataclasses import dataclass
624 | @dataclass
625 | class Plant:
626 | species: str
627 | ```
628 | A class can have methods, which are functions defined for objects of the class. In the example below, `Tray` is a class with properties `species` and `number_of_plants`, and methods `remove_plants` and `is_empty`. The first has one argument which is the number of plants to remove from the tray; it returns a list of objects of the class `Plant` which correspond to the plants that were removed from the tray. The method `is_empty` doesn't have an argument and returns `True` or `False`.
629 | ```
630 | from dataclasses import dataclass
631 |
632 | @dataclass
633 | class Plant:
634 | species: str
635 |
636 | @dataclass
637 | class Tray:
638 | species: str
639 | number_of_plants: int
640 | def remove_plants(self, number): # self refers to the object of the class
641 | number=min(number,self.number_of_plants) #cannot remove more than available
642 | self.number_of_plants -= number
643 | return [Plant(self.species) for _ in range(number)] # returns list of instances of Plant
644 | def is_empty(self): # returns True of False
645 | return self.number_of_plants == 0
646 |
647 | tray=Tray('Lily', 28)
648 | plants=tray.remove_plants(10)
649 | if tray.is_empty():
650 | print('The tray is empty')
651 | else:
652 | print('There are still', tray.number_of_plants, tray.species, 'plants in the tray')
653 | first_plant=plants[0]
654 | print('The plant removed is', first_plant.species)
655 | ```
656 | The code for the full problem that envolves plants of several species, trays, pots and sales can be organized in the following manner:
657 | - Plant class: Simple class to represent a plant with a species.
658 | - Pot class: Holds one plant each.
659 | - Tray class: Holds plants of a single species and can remove plants.
660 | - Nursery class: Manages trays, pots, and keeps track of plant counts by species. It has methods like add_tray, transfer_to_pots, and sell_pot to handle operations for tracking and updating counts.
661 |
662 | ### Use generative AI to help with the following tasks
663 | 1. Create a script for the problem using the standard way of initializing classes with method `__init__`. Start with a simplified version of the problem where there are only trays and plants of distinct species in the nursery, which can be represented with 3 classes: `Plant`, `Tray` and `Nursery`. Trays can be created with a given number of plants of the same species, and plants can be removed from trays. The goal in this simplified version is to create the inventory that keeps track of the number of plants of each species that are in trays.
664 |
665 | One possible solution for this simplified problem that was generated by Chat GPT when asked not to use `@dataclass` is [nursery_v1.py](nursery_v1.py). Note that this code lacks the `__str__` or `__repr__` methods and therefore `print(nursery.trays)` returns a list of objects with their memory address.
666 |
667 | 2. Add a `__repr__` method similar to the one below to class `Tray` to redefine the output of `print(nursery.trays)` and make it more informative.
668 |
669 | ```
670 | def __repr__(self):
671 | return f"Tray(species={self.species}, count={self.count})"
672 | ```
673 |
674 | 4. Add to the previous script a class that represents pots and adapt your script accordingly. When plants are removed from trays, they are always placed in a pot (one plant per pot). The goal is that the inventory tracks the plants and the species in both trays and pots (instead of just in trays as in [nursery_v1.py](nursery_v1.py)).
675 |
676 | 5. Finally, consider that pots can be sold and therefore removed from the inventory.
677 |
678 | 6. Verify if your script removes trays that are empty from the inventory, and update it if it is not the case.
679 |
680 |
681 |
682 |
683 |
684 |
685 | # Class 10 (November 22, 2024): Basic concepts of OOP
686 |
687 |
688 |
689 |
690 |
691 | The four main concepts of Object-Oriented Programming (OOP) are *Encapsulation*, *Abstraction*, *Inheritance*, and *Polymorphism*. These concepts work together to create modular, scalable, and maintainable code in object-oriented programming.
692 |
693 | This is a central topic in computer science, and therefore you can find all kind of resources about it. Among them, you can find simple descriptions of those concepts, with examples, at the following links:
694 | 1. (https://www.programiz.com/python-programming/object-oriented-programming)
695 | 2. (https://www.freecodecamp.org/news/object-oriented-programming-in-python/)
696 | 3. (https://www.w3schools.com/python/python_inheritance.asp), (https://www.w3schools.com/python/python_polymorphism.asp)
697 |
698 | Building on the plant nursery example of last class, the following scripts illustrate the implementation of those concepts:
699 | - Encapsulation: [OOP_encapsulation.py](https://github.com/isa-ulisboa/greends-ipython/blob/main/OOP_encapsulation.py)
700 | - Inheritance: [OOP_inheritance.py](https://github.com/isa-ulisboa/greends-ipython/blob/main/OOP_inheritance.py)
701 | - Polymorphism: [OOP_polymorphism.py](https://github.com/isa-ulisboa/greends-ipython/blob/main/OOP_polymorphism.py)
702 | - Abstraction: [OOP_abstraction.py](https://github.com/isa-ulisboa/greends-ipython/blob/main/OOP_abstraction.py)
703 |
704 | The next assignment will be the *Cookie jar* problem described at (https://cs50.harvard.edu/python/2022/psets/8/jar/). You will need to create a script for the problem and test it with `check50 cs50/problems/2022/python/jar`.
705 |
706 |
707 |
708 |
709 |
710 |
711 | # Class 11 (November 29, 2024): Unit tests
712 |
713 |
714 |
715 | This topic corresponds to [Section 5](https://cs50.harvard.edu/python/2022/weeks/5/) of the CS50 course: you can find the necessary resources on that link. In particular, see the short [https://cs50.harvard.edu/python/2022/shorts/pytest/](https://cs50.harvard.edu/python/2022/shorts/pytest/).
716 |
717 | The idea is to create functions in Python (the names of those functions start with `test_`) that are used to test existing functions or classes in the script. To execute the test functions we call `pytest` in the terminal [https://docs.pytest.org/](https://docs.pytest.org/) instead of `python`:
718 |
719 | ```
720 | $ pytest - v # -v is optional for a more verbose output
721 | ```
722 | If no arguments are given, `pytest` will execute all functions which name starts with `test_` or end with `_test` in scripts in the current directory and all its subdirectories. However, `$pytest my_file.py` will only execute the tests within that file. Moreover, `$pytest my_directory` will only execute the tests defined in files located in that directory. There are further options to select the tests to be executed with `pytest`.
723 |
724 | ### Simple example of a class and tests for that class
725 |
726 | Consider you have two python modules: one with the definition of a class and the other that implement tests over that class.
727 | ```python
728 | # farm_carbon_footprint.py
729 |
730 | import math
731 |
732 | class Farm:
733 | def __init__(self, name, area_hectares):
734 | """Initialize the farm with a name and area in hectares."""
735 | self.name = name
736 | self.area_hectares = area_hectares
737 | self.activities = []
738 |
739 | def add_activity(self, activity, emissions_per_unit, units):
740 | """Add an activity with emissions in kg CO2e per unit and units."""
741 | self.activities.append((activity, emissions_per_unit, units))
742 |
743 | def total_emissions(self):
744 | """Calculate total carbon emissions from all activities."""
745 | return sum(emissions_per_unit * units for _, emissions_per_unit, units in self.activities)
746 |
747 | def emissions_per_hectare(self):
748 | """Calculate carbon emissions per hectare."""
749 | if self.area_hectares == 0:
750 | raise ValueError("Farm area cannot be zero.")
751 | return self.total_emissions() / self.area_hectares
752 |
753 | def radius_circle_with_farm_area(self):
754 | """ Calculate the radius (in meters) of a circle that has the same area as the farm"""
755 | return(math.sqrt(self.area_hectares/3.1459)*100)
756 | ```
757 | and
758 | ```python
759 | # test_farm_carbon_footprint.py
760 |
761 | import pytest
762 | from farm_carbon_footprint import Farm
763 |
764 | def test_add_activity():
765 | farm = Farm("Green Pastures", 10)
766 | farm.add_activity("Tractor Usage", 50, 5) # 50 kg CO2e per hour, 5 hours
767 | farm.add_activity("Fertilizer Use", 10, 20) # 10 kg CO2e per kg, 20 kg
768 | assert len(farm.activities) == 2
769 |
770 | def test_total_emissions():
771 | farm = Farm("Green Pastures", 10)
772 | farm.add_activity("Tractor Usage", 50, 5) # 50 kg CO2e per hour, 5 hours
773 | farm.add_activity("Fertilizer Use", 10, 20) # 10 kg CO2e per kg, 20 kg
774 | assert farm.total_emissions() == 450 # 250 + 200
775 |
776 | def test_emissions_per_hectare():
777 | farm = Farm("Green Pastures", 10)
778 | farm.add_activity("Tractor Usage", 50, 5) # 50 kg CO2e per hour, 5 hours
779 | farm.add_activity("Fertilizer Use", 10, 20) # 10 kg CO2e per kg, 20 kg
780 | assert farm.emissions_per_hectare() == 45 # 450 total / 10 hectares
781 |
782 | def test_emissions_per_hectare_zero_area():
783 | farm = Farm("Tiny Farm", 0)
784 | farm.add_activity("Tractor Usage", 50, 2) # 50 kg CO2e per hour, 2 hours
785 | with pytest.raises(ValueError, match="Farm area cannot be zero."): # optional: matches Value Error message in emissions_per_hectare()
786 | farm.emissions_per_hectare()
787 |
788 | def test_radius_of_circle_with_farm_area():
789 | farm = Farm("Circle Farm", 1)
790 | assert farm.radius_circle_with_farm_area() == pytest.approx(56.38, abs=0.1)
791 | farm = Farm("Circle Farm", 10)
792 | assert farm.radius_circle_with_farm_area() == pytest.approx(178.3, abs=0.01)
793 | ```
794 | Adapt the `Farm` class definition and `test_farm_carbon_footprint.py` in order to:
795 |
796 | 1. Add a method `.number_of_activities()` to class `Farm` that returns the number of activities. Check the correctness of that method with a new test in `test_farm_carbon_footprint.py`.
797 | 2. Adapt the `Farm`class so `ValueError` should be raised if the property `area_hectares` is negative when you try to create an instance of `Farm`. Check with a new test in `test_farm_carbon_footprint.py` that the behavior of the class is as expected when `area_hectares` is negative.
798 |
799 |
800 |
801 |
802 |
803 |
804 | # Class 12 (December 6, 2024): Lists and dictionaries: packing, args and kwargs, comprehension
805 |
806 |
807 |
808 | ## 1. The packing/unpacking operators * and **
809 |
810 | The packing/unpacking operators allows us to deal with structures of variable length. The example below illustrates *packing* several numbers into a list.
811 | ```python
812 | x=[1,2,3,4,5,6,7,8,9]
813 | a,*b,c=x # b is the list [2,3,4,5,6,7,8]
814 | print(a,b,c)
815 | ```
816 | The same operator can be used to unpack:
817 | ```python
818 | list1=[1,2,3]
819 | list2=[6,7,8]
820 | new_list=[*list1,4,5,*list2] # values are unpacked
821 | print(new_list)
822 | ```
823 | The * and ** operator are mostly used as arguments of functions that can accept a a variable number of arguments (like `print`): the operator * allows to pack all positional arguments into a *tuple* and the operator ** allows to pack all named arguments into a *dictionary*. In the example below, the variable `kwargs` refers to keyword arguments (i.e named arguments) . Note that one can have a combination of regular arguments, regular named arguments, *args, and **kwargs as arguments of a function, as long as keyword arguments follow positional arguments.
824 |
825 | ```python
826 | def pack(*args, **kwargs):
827 | return args,kwargs
828 |
829 | x,y=pack(1,2,10, num_years=10,rate=0.03)
830 |
831 | print('Positional arguments are packed into tuple',x)
832 | print('Named arguments are packed into dictionary',y)
833 | ```
834 |
835 | This can be used for instance to perform computations over a variable length sequence at in the following example.
836 | ```python
837 | # Compute accumulated interest on a sequence of borrowed amounts
838 | def main(*args, **kwargs):
839 | '''
840 | args is a tuple of amounts borrowed
841 | kwargs is a dictionary with keys num_years and rate
842 | '''
843 | S=add(args)
844 | # Call function debt with **kwargs or kwargs
845 | D=compute_debt(S,**kwargs) # D expects a number and two named arguments with names num_years and rate
846 | # same as:
847 | D=compute_debt(S,kwargs['num_years'],kwargs['rate'])
848 | # print results
849 | print('Borrowed:',S)
850 | print('Debt:',round(D,3))
851 |
852 | def add(values):
853 | s=0
854 | for x in values:
855 | s+=x
856 | return s
857 |
858 | def compute_debt(s,num_years,rate):
859 | for i in range(num_years):
860 | s+=s*rate
861 | return s
862 |
863 | if __name__=='__main__':
864 | main(1,2,10,5,4,num_years=10, rate=0.05)
865 | ```
866 |
867 | ### Exercise i) Summing Arguments with `*args`
868 | Write a function `sum_all` that takes any number of positional arguments and returns their sum.
869 |
870 | ```python
871 | def sum_all(*args):
872 | pass # Your code here
873 |
874 | # Example usage:
875 | print(sum_all(1, 2, 3)) # Output: 6
876 | print(sum_all(10, 20, 30, 5)) # Output: 65
877 | ```
878 |
879 | ### Exercise ii) Concatenate Strings with `*args`
880 | Create a function `concat_strings` that takes any number of string arguments using `*args` and concatenates them into a single string.
881 |
882 | ```python
883 | def concat_strings(*args):
884 | pass # Your code here
885 |
886 | # Example usage:
887 | print(concat_strings("Hello", " ", "world", "!")) # Output: "Hello world!"
888 | print(concat_strings("Python", " is", " fun!")) # Output: "Python is fun!"
889 | ```
890 |
891 | ### Exercise iii) Handling Default Keyword Arguments with `**kwargs`
892 | Write a function `greet` that accepts a keyword argument `name` (default value: `"Guest"`) and an optional keyword argument `greeting` (default value: `"Hello"`). Return the formatted greeting message.
893 |
894 | ```python
895 | def greet(**kwargs):
896 | pass # Your code here
897 |
898 | # Example usage:
899 | print(greet(name="Alice", greeting="Hi")) # Output: "Hi Alice"
900 | print(greet(name="Bob")) # Output: "Hello Bob"
901 | print(greet()) # Output: "Hello Guest"
902 | ```
903 |
904 | ### Exercise iv) Combine `*args` and `**kwargs`
905 | Write a function `describe_person` that takes positional arguments (`*args`) for hobbies and keyword arguments (`**kwargs`) for personal details (e.g., name, age). Return a formatted string describing the person.
906 |
907 | ```python
908 | def describe_person(*args, **kwargs):
909 | pass # Your code here
910 |
911 | # Example usage:
912 | print(describe_person("reading", "traveling", name="Alice", age=30))
913 | # Output: "Alice (30 years old) enjoys reading, traveling."
914 | ```
915 |
916 | ### Exercise v) Filter Keyword Arguments with `**kwargs`
917 | Create a function `filter_kwargs` that takes any number of keyword arguments and returns a new dictionary containing only those with values greater than 10.
918 |
919 | ```python
920 | def filter_kwargs(**kwargs):
921 | pass # Your code here
922 |
923 | # Example usage:
924 | print(filter_kwargs(a=5, b=15, c=20, d=3)) # Output: {'b': 15, 'c': 20}
925 | ```
926 |
927 | ## 2. List and dictionary comprehension, map and filter
928 |
929 | Suppose one wants to create a list with all the cubes of even numbers up to *N*. The following scripts show how this can be done with different operators that replace the traditional *loop* structure: *list comprehension*, `filter`, `map` and `lambda`
930 |
931 | Operator `map` applies a given function to each element of a list. Likewise, `filter` applies a boolean function to filter elements of a list. Both function can be executed in parallel over the elements of the list since each output is independent of the outputs for the remainder elements of the list.
932 |
933 | * With list comprehension:
934 | ```python
935 | def cube(x):
936 | return x*x*x
937 | L=[cube(x) for x in range(N) if x%2==0]
938 | ```
939 |
940 | * With `filter` to select even numbers and `map`to compute cubes:
941 | ```python
942 | def even(x):
943 | return x%2==0
944 | numbers=list(range(N))
945 | even_numbers=list(filter(even, numbers))
946 | cubes=list(map(cube,even_numbers))
947 | ```
948 |
949 | * Also with `filter` and `map` but defining implicitly the *cube* and *even* functions with `lambda` instead of `def`:
950 | ```python
951 | numbers=list(range(N))
952 | even_numbers=list(filter(lambda x: x%2==0, numbers))
953 | cubes=list(map(lambda x: x*x*x,even_numbers))
954 | ```
955 |
956 | * The most compact way of solving the problem involves `lambda` and list comprehension. In the example below, one needs to indicate that the $\lambda$ function has to be applied to the variable `x` in the list comprehension, using `(lambda x: x*x*x)(x)`. Otherwise, the output list would be a list of lambda functions.
957 |
958 | ```python
959 | cubes=[(lambda x: x*x*x)(x) for x in range(N) if x%2==0]
960 | ```
961 |
962 | ### Exercise i) Convert a For Loop to List Comprehension
963 | Convert the following for loop into a list comprehension:
964 |
965 | ```python
966 | result = []
967 | for x in range(10):
968 | result.append(x**2)
969 | # output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
970 | ```
971 |
972 | ### Exercise ii) Filter Numbers with List Comprehension
973 | Rewrite this code using a list comprehension:
974 |
975 | ```python
976 | result = []
977 | for x in range(20):
978 | if x % 2 == 0:
979 | result.append(x)
980 | # output: [0, 4, 16, 36, 64]
981 | ```
982 |
983 | ### Exercise iii) Dictionary Comprehension
984 | Convert the following code to a dictionary comprehension:
985 |
986 | ```python
987 | squares = {}
988 | for x in range(5):
989 | squares[x] = x**2
990 | # output: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
991 | ```
992 |
993 | ### Exercise iv) Nested Loops with List Comprehension
994 | Rewrite the nested loop as a list comprehension:
995 |
996 | ```python
997 | pairs = []
998 | for x in range(3):
999 | for y in range(2):
1000 | pairs.append((x, y))
1001 | # output: [(0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1)]
1002 | ```
1003 |
1004 | ### Exercise v) Conditional Dictionary Comprehension
1005 | Transform the following code into a dictionary comprehension with a condition:
1006 |
1007 | ```python
1008 | filtered_squares = {}
1009 | for x in range(10):
1010 | if x % 2 == 0:
1011 | filtered_squares[x] = x**2
1012 | # output: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
1013 | ```
1014 |
1015 | ### Exercise vi) Conditional Transformation in List Comprehension
1016 | Convert the following loop into a list comprehension that includes a conditional transformation:
1017 |
1018 | ```python
1019 | result = []
1020 | for x in range(15):
1021 | if x % 3 == 0:
1022 | result.append(x**2)
1023 | else:
1024 | result.append(x)
1025 | # output: [0, 1, 2, 9, 4, 5, 36, 7, 8, 81, 10, 11, 144, 13, 14]
1026 | ```
1027 |
1028 | ### Exercise vii) Dictionary Comprehension with String Keys
1029 | Transform the following loop into a dictionary comprehension, using strings as keys:
1030 |
1031 | ```python
1032 | word_lengths = {}
1033 | words = ["apple", "banana", "cherry", "date"]
1034 | for word in words:
1035 | word_lengths[word] = len(word)
1036 | # output: {'apple': 5, 'banana': 6, 'cherry': 6, 'date': 4}
1037 | ```
1038 |
1039 | ### Exercise viii) Flatten a Nested List with List Comprehension
1040 | Rewrite this code using a single list comprehension to flatten the nested list:
1041 |
1042 | ```python
1043 | nested_list = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
1044 | flattened = []
1045 | for sublist in nested_list:
1046 | for item in sublist:
1047 | flattened.append(item)
1048 | # output: [1, 2, 3, 4, 5, 6, 7, 8, 9]
1049 | ```
1050 |
1051 | ### Exercise ix) Conditional Dictionary Comprehension with Nested Loops
1052 | Convert the following nested loop into a dictionary comprehension with a condition:
1053 |
1054 | ```python
1055 | result = {}
1056 | for i in range(1,3):
1057 | for j in range(3, 6):
1058 | if j % i != 0:
1059 | result[(i, j)] = i + j
1060 | # {(2, 3): 5, (2, 5): 7}
1061 | ```
1062 |
1063 |
1064 | ### Exercise x) Filter and Transform Nested Dictionaries
1065 | Use a dictionary comprehension to filter and transform the following dictionary of dictionaries:
1066 |
1067 | ```python
1068 | data = {
1069 | "A": {"score": 90, "passed": True},
1070 | "B": {"score": 65, "passed": False},
1071 | "C": {"score": 75, "passed": True},
1072 | "D": {"score": 50, "passed": False},
1073 | }
1074 |
1075 | # Goal: Include only students who passed, and create a dictionary of their scores.
1076 | result = {}
1077 | for key, value in data.items():
1078 | if value["passed"]:
1079 | result[key] = value["score"]
1080 | # output: {'A': 90, 'C': 75}
1081 | ```
1082 |
1083 |
1084 |
1085 |
1086 |
1087 | # Class 13 (December 13, 2024): Introduction to IoT with Raspberry Pi
1088 |
1089 |
1090 |
1091 | In this class we use Python to control physical devices through GPIO (general-purpose input/output) ports on a Raspberry Pi microcomputer. We will rely on the `gpiozero` Python package [https://gpiozero.readthedocs.io/en/latest/recipes.html](https://gpiozero.readthedocs.io/en/latest/recipes.html).
1092 |
1093 | Topics of the class:
1094 | - Raspberry Pi (RPi) and PiOS (Linux)
1095 | - Retrive local address of the Raspberry Pi with `hostname -I`
1096 | - Accessing RPi remotely with `ssh` (secure shell)
1097 | - Connecting RPi to a breadboard using the *gpio* pins
1098 | - Using the *nano* text editor to create scripts
1099 | - Running scripts in RPi with `sudo python3 test.py`
1100 | - Implementing some basic recipes from `gpio zero` documentation that use the following physical devices: leds, buttons, and a line sensor
1101 |
1102 | ### Exercises with Raspberry Pi, breadboard, led, button and connection wires:
1103 |
1104 | 1. [Blink LED](https://gpiozero.readthedocs.io/en/latest/recipes.html#led)
1105 | 2. [Check if button is pressed](https://gpiozero.readthedocs.io/en/latest/recipes.html#button)
1106 | 3. [Button controlled LED](https://gpiozero.readthedocs.io/en/latest/recipes.html#button-controlled-led)
1107 |
1108 |
1109 |
1110 |
1111 |
1112 |
1113 | # Class 14 (December 20, 2024): Introduction to IoT with Raspberry Pi (cont'd)
1114 |
1115 |
1116 |
1117 | ### Exercises for led board with gpiozero (cont'd)
1118 | 1. [LED_board](https://gpiozero.readthedocs.io/en/latest/recipes.html#ledboard). Interpret the code and verify that it is behaving as expected.
1119 |
1120 | 2. Look at the [advanced recipes for LEDboard](https://gpiozero.readthedocs.io/en/latest/recipes_advanced.html#ledboard-advanced). Create a "pyramid" of lights 5-3-1-3-5, that turn on and off and pause 1 second. You can build a loop such that the pyramid runs only 4 times and the execution stops.
1121 |
1122 | 3. Adapt the code `LED_board.py` so if you execute `sudo python3 LED_morse.py some_word` the LEDs should turn on and off to encode the input word: a *dah* (-) has a duration of 2 seconds and a *dit* (.) has a duration of 1 second. After each letter, there should be a 3 second pause before the next letter. The example below should correspond to LEDs 1 and 2 being on for 3 seconds, then LEDs 1, 2 and 3 being on for 3 seconds, then LEDs 1 and 3 being on for 1 second while LED 2 is on for 3 seconds, and so on.
1123 |
1124 | ```
1125 | −− −−− ·−· ··· · −·−· −−− −·· ·
1126 | M O R S E C O D E
1127 | ```
1128 | ### Other sensors
1129 |
1130 | There are many hardware adapters that make it easier to connect sensors to a microcomputer. Here we look at the *Raspberry Pi hat* included in the [Grove_Base_Kit_for_Raspberry_Pi](https://wiki.seeedstudio.com/Grove_Base_Kit_for_Raspberry_Pi/). The [Grove Base Hat for Raspberry Pi](https://wiki.seeedstudio.com/Grove_Base_Hat_for_Raspberry_Pi/) provides Digital/Analog/I2C/PWM/UART [ports](https://wiki.seeedstudio.com/Grove_Base_Hat_for_Raspberry_Pi/#hardware-overview) to the RPi allowing it to be connected a large range of modules.
1131 |
1132 | The following code show how to access a [temperature and humidity sensor](https://www.seeedstudio.com/Grove-Temperature-Humidity-Sensor-DHT1-p-745.html) readings programmatically. The sensor is connected to digital port D5. This code also allows access to gpio pin 17 to power a LED.
1133 |
1134 | ```python
1135 | import time
1136 | from seeed_dht import DHT
1137 | from gpiozero import LED
1138 |
1139 | led=LED(17)
1140 | # Grove - Temperature&Humidity Sensor connected to port D5
1141 | sensor = DHT('11', 5)
1142 | while True:
1143 | humi, temp = sensor.read()
1144 | print('temperature {}C, humidity {}%'.format(temp, humi))
1145 | if humi > 85:
1146 | led.on()
1147 | else:
1148 | led.off()
1149 | time.sleep(0.5)
1150 | ```
1151 | ### Exercises
1152 |
1153 | 1. Adapt the code above such that the LED is on when the temperature is above 24 Celsius or below 20 and is off otherwise.
1154 | 2. Interpret the code below. Create a new script that combines the temperature/humidity sensor with the ultrasonic ranger sensor and the LED.
1155 |
1156 | ```python
1157 | import time
1158 | from grove.grove_ultrasonic_ranger import GroveUltrasonicRanger
1159 | from gpiozero import LED
1160 | led=LED(17)
1161 | # Grove - Ultrasonic Ranger connected to port D5
1162 | sensor = GroveUltrasonicRanger(5)
1163 | while True:
1164 | distance = sensor.get_distance()
1165 | print('{} cm'.format(distance))
1166 | if distance < 20:
1167 | led.on()
1168 | print('LED on')
1169 | time.sleep(0.5)
1170 | led.off()
1171 | print('LED off')
1172 | continue
1173 | time.sleep(1)
1174 | ```
1175 |
1176 |
1177 |
1178 |
1563 |
--------------------------------------------------------------------------------
/args_kwargs_exercises.js:
--------------------------------------------------------------------------------
1 | Here’s a list of 5 simple exercises to practice using `*args` and `**kwargs` in Python:
2 |
3 | ---
4 |
5 | ### **Exercise 1: Summing Arguments with `*args`**
6 | Write a function `sum_all` that takes any number of positional arguments and returns their sum.
7 |
8 | ```python
9 | def sum_all(*args):
10 | pass # Your code here
11 |
12 | # Example usage:
13 | print(sum_all(1, 2, 3)) # Output: 6
14 | print(sum_all(10, 20, 30, 5)) # Output: 65
15 | ```
16 |
17 | ---
18 |
19 | ### **Exercise 2: Concatenate Strings with `*args`**
20 | Create a function `concat_strings` that takes any number of string arguments using `*args` and concatenates them into a single string.
21 |
22 | ```python
23 | def concat_strings(*args):
24 | pass # Your code here
25 |
26 | # Example usage:
27 | print(concat_strings("Hello", " ", "world", "!")) # Output: "Hello world!"
28 | print(concat_strings("Python", " is", " fun!")) # Output: "Python is fun!"
29 | ```
30 |
31 | ---
32 |
33 | ### **Exercise 3: Handling Default Keyword Arguments with `**kwargs`**
34 | Write a function `greet` that accepts a keyword argument `name` (default value: `"Guest"`) and an optional keyword argument `greeting` (default value: `"Hello"`). Return the formatted greeting message.
35 |
36 | ```python
37 | def greet(**kwargs):
38 | pass # Your code here
39 |
40 | # Example usage:
41 | print(greet(name="Alice", greeting="Hi")) # Output: "Hi Alice"
42 | print(greet(name="Bob")) # Output: "Hello Bob"
43 | print(greet()) # Output: "Hello Guest"
44 | ```
45 |
46 | ---
47 |
48 | ### **Exercise 4: Combine `*args` and `**kwargs`**
49 | Write a function `describe_person` that takes positional arguments (`*args`) for hobbies and keyword arguments (`**kwargs`) for personal details (e.g., name, age). Return a formatted string describing the person.
50 |
51 | ```python
52 | def describe_person(*args, **kwargs):
53 | pass # Your code here
54 |
55 | # Example usage:
56 | print(describe_person("reading", "traveling", name="Alice", age=30))
57 | # Output: "Alice (30 years old) enjoys reading, traveling."
58 | ```
59 |
60 | ---
61 |
62 | ### **Exercise 5: Filter Keyword Arguments with `**kwargs`**
63 | Create a function `filter_kwargs` that takes any number of keyword arguments and returns a new dictionary containing only those with values greater than 10.
64 |
65 | ```python
66 | def filter_kwargs(**kwargs):
67 | pass # Your code here
68 |
69 | # Example usage:
70 | print(filter_kwargs(a=5, b=15, c=20, d=3)) # Output: {'b': 15, 'c': 20}
71 | ```
72 |
73 | ---
74 |
75 | These exercises progressively build skills in handling `*args` and `**kwargs`, covering positional and keyword arguments, defaults, and combining both!
76 |
--------------------------------------------------------------------------------
/forestfires.csv:
--------------------------------------------------------------------------------
1 | X,Y,month,day,FFMC,DMC,DC,ISI,temp,RH,wind,rain,area
2 | 7,5,mar,fri,86.2,26.2,94.3,5.1,8.2,51,6.7,0,0
3 | 7,4,oct,tue,90.6,35.4,669.1,6.7,18,33,0.9,0,0
4 | 7,4,oct,sat,90.6,43.7,686.9,6.7,14.6,33,1.3,0,0
5 | 8,6,mar,fri,91.7,33.3,77.5,9,8.3,97,4,0.2,0
6 | 8,6,mar,sun,89.3,51.3,102.2,9.6,11.4,99,1.8,0,0
7 | 8,6,aug,sun,92.3,85.3,488,14.7,22.2,29,5.4,0,0
8 | 8,6,aug,mon,92.3,88.9,495.6,8.5,24.1,27,3.1,0,0
9 | 8,6,aug,mon,91.5,145.4,608.2,10.7,8,86,2.2,0,0
10 | 8,6,sep,tue,91,129.5,692.6,7,13.1,63,5.4,0,0
11 | 7,5,sep,sat,92.5,88,698.6,7.1,22.8,40,4,0,0
12 | 7,5,sep,sat,92.5,88,698.6,7.1,17.8,51,7.2,0,0
13 | 7,5,sep,sat,92.8,73.2,713,22.6,19.3,38,4,0,0
14 | 6,5,aug,fri,63.5,70.8,665.3,0.8,17,72,6.7,0,0
15 | 6,5,sep,mon,90.9,126.5,686.5,7,21.3,42,2.2,0,0
16 | 6,5,sep,wed,92.9,133.3,699.6,9.2,26.4,21,4.5,0,0
17 | 6,5,sep,fri,93.3,141.2,713.9,13.9,22.9,44,5.4,0,0
18 | 5,5,mar,sat,91.7,35.8,80.8,7.8,15.1,27,5.4,0,0
19 | 8,5,oct,mon,84.9,32.8,664.2,3,16.7,47,4.9,0,0
20 | 6,4,mar,wed,89.2,27.9,70.8,6.3,15.9,35,4,0,0
21 | 6,4,apr,sat,86.3,27.4,97.1,5.1,9.3,44,4.5,0,0
22 | 6,4,sep,tue,91,129.5,692.6,7,18.3,40,2.7,0,0
23 | 5,4,sep,mon,91.8,78.5,724.3,9.2,19.1,38,2.7,0,0
24 | 7,4,jun,sun,94.3,96.3,200,56.1,21,44,4.5,0,0
25 | 7,4,aug,sat,90.2,110.9,537.4,6.2,19.5,43,5.8,0,0
26 | 7,4,aug,sat,93.5,139.4,594.2,20.3,23.7,32,5.8,0,0
27 | 7,4,aug,sun,91.4,142.4,601.4,10.6,16.3,60,5.4,0,0
28 | 7,4,sep,fri,92.4,117.9,668,12.2,19,34,5.8,0,0
29 | 7,4,sep,mon,90.9,126.5,686.5,7,19.4,48,1.3,0,0
30 | 6,3,sep,sat,93.4,145.4,721.4,8.1,30.2,24,2.7,0,0
31 | 6,3,sep,sun,93.5,149.3,728.6,8.1,22.8,39,3.6,0,0
32 | 6,3,sep,fri,94.3,85.1,692.3,15.9,25.4,24,3.6,0,0
33 | 6,3,sep,mon,88.6,91.8,709.9,7.1,11.2,78,7.6,0,0
34 | 6,3,sep,fri,88.6,69.7,706.8,5.8,20.6,37,1.8,0,0
35 | 6,3,sep,sun,91.7,75.6,718.3,7.8,17.7,39,3.6,0,0
36 | 6,3,sep,mon,91.8,78.5,724.3,9.2,21.2,32,2.7,0,0
37 | 6,3,sep,tue,90.3,80.7,730.2,6.3,18.2,62,4.5,0,0
38 | 6,3,oct,tue,90.6,35.4,669.1,6.7,21.7,24,4.5,0,0
39 | 7,4,oct,fri,90,41.5,682.6,8.7,11.3,60,5.4,0,0
40 | 7,3,oct,sat,90.6,43.7,686.9,6.7,17.8,27,4,0,0
41 | 4,4,mar,tue,88.1,25.7,67.6,3.8,14.1,43,2.7,0,0
42 | 4,4,jul,tue,79.5,60.6,366.7,1.5,23.3,37,3.1,0,0
43 | 4,4,aug,sat,90.2,96.9,624.2,8.9,18.4,42,6.7,0,0
44 | 4,4,aug,tue,94.8,108.3,647.1,17,16.6,54,5.4,0,0
45 | 4,4,sep,sat,92.5,88,698.6,7.1,19.6,48,2.7,0,0
46 | 4,4,sep,wed,90.1,82.9,735.7,6.2,12.9,74,4.9,0,0
47 | 5,6,sep,wed,94.3,85.1,692.3,15.9,25.9,24,4,0,0
48 | 5,6,sep,mon,90.9,126.5,686.5,7,14.7,70,3.6,0,0
49 | 6,6,jul,mon,94.2,62.3,442.9,11,23,36,3.1,0,0
50 | 4,4,mar,mon,87.2,23.9,64.7,4.1,11.8,35,1.8,0,0
51 | 4,4,mar,mon,87.6,52.2,103.8,5,11,46,5.8,0,0
52 | 4,4,sep,thu,92.9,137,706.4,9.2,20.8,17,1.3,0,0
53 | 4,3,aug,sun,90.2,99.6,631.2,6.3,21.5,34,2.2,0,0
54 | 4,3,aug,wed,92.1,111.2,654.1,9.6,20.4,42,4.9,0,0
55 | 4,3,aug,wed,92.1,111.2,654.1,9.6,20.4,42,4.9,0,0
56 | 4,3,aug,thu,91.7,114.3,661.3,6.3,17.6,45,3.6,0,0
57 | 4,3,sep,thu,92.9,137,706.4,9.2,27.7,24,2.2,0,0
58 | 4,3,sep,tue,90.3,80.7,730.2,6.3,17.8,63,4.9,0,0
59 | 4,3,oct,sun,92.6,46.5,691.8,8.8,13.8,50,2.7,0,0
60 | 2,2,feb,mon,84,9.3,34,2.1,13.9,40,5.4,0,0
61 | 2,2,feb,fri,86.6,13.2,43,5.3,12.3,51,0.9,0,0
62 | 2,2,mar,sun,89.3,51.3,102.2,9.6,11.5,39,5.8,0,0
63 | 2,2,mar,sun,89.3,51.3,102.2,9.6,5.5,59,6.3,0,0
64 | 2,2,aug,thu,93,75.3,466.6,7.7,18.8,35,4.9,0,0
65 | 2,2,aug,sun,90.2,99.6,631.2,6.3,20.8,33,2.7,0,0
66 | 2,2,aug,mon,91.1,103.2,638.8,5.8,23.1,31,3.1,0,0
67 | 2,2,aug,thu,91.7,114.3,661.3,6.3,18.6,44,4.5,0,0
68 | 2,2,sep,fri,92.4,117.9,668,12.2,23,37,4.5,0,0
69 | 2,2,sep,fri,92.4,117.9,668,12.2,19.6,33,5.4,0,0
70 | 2,2,sep,fri,92.4,117.9,668,12.2,19.6,33,6.3,0,0
71 | 4,5,mar,fri,91.7,33.3,77.5,9,17.2,26,4.5,0,0
72 | 4,5,mar,fri,91.2,48.3,97.8,12.5,15.8,27,7.6,0,0
73 | 4,5,sep,fri,94.3,85.1,692.3,15.9,17.7,37,3.6,0,0
74 | 5,4,mar,fri,91.7,33.3,77.5,9,15.6,25,6.3,0,0
75 | 5,4,aug,tue,88.8,147.3,614.5,9,17.3,43,4.5,0,0
76 | 5,4,sep,fri,93.3,141.2,713.9,13.9,27.6,30,1.3,0,0
77 | 9,9,feb,thu,84.2,6.8,26.6,7.7,6.7,79,3.1,0,0
78 | 9,9,feb,fri,86.6,13.2,43,5.3,15.7,43,3.1,0,0
79 | 1,3,mar,mon,87.6,52.2,103.8,5,8.3,72,3.1,0,0
80 | 1,2,aug,fri,90.1,108,529.8,12.5,14.7,66,2.7,0,0
81 | 1,2,aug,tue,91,121.2,561.6,7,21.6,19,6.7,0,0
82 | 1,2,aug,sun,91.4,142.4,601.4,10.6,19.5,39,6.3,0,0
83 | 1,2,aug,sun,90.2,99.6,631.2,6.3,17.9,44,2.2,0,0
84 | 1,2,aug,tue,94.8,108.3,647.1,17,18.6,51,4.5,0,0
85 | 1,2,aug,wed,92.1,111.2,654.1,9.6,16.6,47,0.9,0,0
86 | 1,2,aug,thu,91.7,114.3,661.3,6.3,20.2,45,3.6,0,0
87 | 1,2,sep,thu,92.9,137,706.4,9.2,21.5,15,0.9,0,0
88 | 1,2,sep,thu,92.9,137,706.4,9.2,25.4,27,2.2,0,0
89 | 1,2,sep,thu,92.9,137,706.4,9.2,22.4,34,2.2,0,0
90 | 1,2,sep,sun,93.5,149.3,728.6,8.1,25.3,36,3.6,0,0
91 | 6,5,mar,sat,91.7,35.8,80.8,7.8,17.4,25,4.9,0,0
92 | 6,5,aug,sat,90.2,96.9,624.2,8.9,14.7,59,5.8,0,0
93 | 8,6,mar,fri,91.7,35.8,80.8,7.8,17.4,24,5.4,0,0
94 | 8,6,aug,sun,92.3,85.3,488,14.7,20.8,32,6.3,0,0
95 | 8,6,aug,sun,91.4,142.4,601.4,10.6,18.2,43,4.9,0,0
96 | 8,6,aug,mon,91.1,103.2,638.8,5.8,23.4,22,2.7,0,0
97 | 4,4,sep,sun,89.7,90,704.4,4.8,17.8,64,1.3,0,0
98 | 3,4,feb,sat,83.9,8,30.2,2.6,12.7,48,1.8,0,0
99 | 3,4,mar,sat,69,2.4,15.5,0.7,17.4,24,5.4,0,0
100 | 3,4,aug,sun,91.4,142.4,601.4,10.6,11.6,87,4.5,0,0
101 | 3,4,aug,sun,91.4,142.4,601.4,10.6,19.8,39,5.4,0,0
102 | 3,4,aug,sun,91.4,142.4,601.4,10.6,19.8,39,5.4,0,0
103 | 3,4,aug,tue,88.8,147.3,614.5,9,14.4,66,5.4,0,0
104 | 2,4,aug,tue,94.8,108.3,647.1,17,20.1,40,4,0,0
105 | 2,4,sep,sat,92.5,121.1,674.4,8.6,24.1,29,4.5,0,0
106 | 2,4,jan,sat,82.1,3.7,9.3,2.9,5.3,78,3.1,0,0
107 | 4,5,mar,fri,85.9,19.5,57.3,2.8,12.7,52,6.3,0,0
108 | 4,5,mar,thu,91.4,30.7,74.3,7.5,18.2,29,3.1,0,0
109 | 4,5,aug,sun,90.2,99.6,631.2,6.3,21.4,33,3.1,0,0
110 | 4,5,sep,sat,92.5,88,698.6,7.1,20.3,45,3.1,0,0
111 | 4,5,sep,mon,88.6,91.8,709.9,7.1,17.4,56,5.4,0,0
112 | 4,4,mar,fri,85.9,19.5,57.3,2.8,13.7,43,5.8,0,0
113 | 3,4,mar,fri,91.7,33.3,77.5,9,18.8,18,4.5,0,0
114 | 3,4,sep,sun,89.7,90,704.4,4.8,22.8,39,3.6,0,0
115 | 3,4,sep,mon,91.8,78.5,724.3,9.2,18.9,35,2.7,0,0
116 | 3,4,mar,tue,88.1,25.7,67.6,3.8,15.8,27,7.6,0,0
117 | 3,5,mar,tue,88.1,25.7,67.6,3.8,15.5,27,6.3,0,0
118 | 3,4,mar,sat,91.7,35.8,80.8,7.8,11.6,30,6.3,0,0
119 | 3,4,mar,sat,91.7,35.8,80.8,7.8,15.2,27,4.9,0,0
120 | 3,4,mar,mon,90.1,39.7,86.6,6.2,10.6,30,4,0,0
121 | 3,4,aug,thu,93,75.3,466.6,7.7,19.6,36,3.1,0,0
122 | 3,4,aug,mon,91.5,145.4,608.2,10.7,10.3,74,2.2,0,0
123 | 3,4,aug,mon,91.5,145.4,608.2,10.7,17.1,43,5.4,0,0
124 | 3,4,sep,sun,92.4,124.1,680.7,8.5,22.5,42,5.4,0,0
125 | 3,4,sep,tue,84.4,73.4,671.9,3.2,17.9,45,3.1,0,0
126 | 3,4,sep,fri,94.3,85.1,692.3,15.9,19.8,50,5.4,0,0
127 | 3,4,oct,sun,92.6,46.5,691.8,8.8,20.6,24,5.4,0,0
128 | 3,5,mar,mon,87.6,52.2,103.8,5,9,49,2.2,0,0
129 | 3,5,sep,fri,93.5,149.3,728.6,8.1,17.2,43,3.1,0,0
130 | 3,5,oct,wed,91.4,37.9,673.8,5.2,15.9,46,3.6,0,0
131 | 2,5,oct,sun,92.6,46.5,691.8,8.8,15.4,35,0.9,0,0
132 | 4,6,feb,sat,68.2,21.5,87.2,0.8,15.4,40,2.7,0,0
133 | 4,6,mar,mon,87.2,23.9,64.7,4.1,14,39,3.1,0,0
134 | 4,6,mar,sun,89.3,51.3,102.2,9.6,10.6,46,4.9,0,0
135 | 4,6,sep,thu,93.7,80.9,685.2,17.9,17.6,42,3.1,0,0
136 | 3,5,mar,tue,88.1,25.7,67.6,3.8,14.9,38,2.7,0,0
137 | 3,5,aug,sat,93.5,139.4,594.2,20.3,17.6,52,5.8,0,0
138 | 3,6,sep,sun,92.4,124.1,680.7,8.5,17.2,58,1.3,0,0
139 | 3,6,sep,mon,90.9,126.5,686.5,7,15.6,66,3.1,0,0
140 | 9,9,jul,tue,85.8,48.3,313.4,3.9,18,42,2.7,0,0.36
141 | 1,4,sep,tue,91,129.5,692.6,7,21.7,38,2.2,0,0.43
142 | 2,5,sep,mon,90.9,126.5,686.5,7,21.9,39,1.8,0,0.47
143 | 1,2,aug,wed,95.5,99.9,513.3,13.2,23.3,31,4.5,0,0.55
144 | 8,6,aug,fri,90.1,108,529.8,12.5,21.2,51,8.9,0,0.61
145 | 1,2,jul,sat,90,51.3,296.3,8.7,16.6,53,5.4,0,0.71
146 | 2,5,aug,wed,95.5,99.9,513.3,13.2,23.8,32,5.4,0,0.77
147 | 6,5,aug,thu,95.2,131.7,578.8,10.4,27.4,22,4,0,0.9
148 | 5,4,mar,mon,90.1,39.7,86.6,6.2,13.2,40,5.4,0,0.95
149 | 8,3,sep,tue,84.4,73.4,671.9,3.2,24.2,28,3.6,0,0.96
150 | 2,2,aug,tue,94.8,108.3,647.1,17,17.4,43,6.7,0,1.07
151 | 8,6,sep,thu,93.7,80.9,685.2,17.9,23.7,25,4.5,0,1.12
152 | 6,5,jun,fri,92.5,56.4,433.3,7.1,23.2,39,5.4,0,1.19
153 | 9,9,jul,sun,90.1,68.6,355.2,7.2,24.8,29,2.2,0,1.36
154 | 3,4,jul,sat,90.1,51.2,424.1,6.2,24.6,43,1.8,0,1.43
155 | 5,4,sep,fri,94.3,85.1,692.3,15.9,20.1,47,4.9,0,1.46
156 | 1,5,sep,sat,93.4,145.4,721.4,8.1,29.6,27,2.7,0,1.46
157 | 7,4,aug,sun,94.8,108.3,647.1,17,16.4,47,1.3,0,1.56
158 | 2,4,sep,sat,93.4,145.4,721.4,8.1,28.6,27,2.2,0,1.61
159 | 2,2,aug,wed,92.1,111.2,654.1,9.6,18.4,45,3.6,0,1.63
160 | 2,4,aug,wed,92.1,111.2,654.1,9.6,20.5,35,4,0,1.64
161 | 7,4,sep,fri,92.4,117.9,668,12.2,19,34,5.8,0,1.69
162 | 7,4,mar,mon,90.1,39.7,86.6,6.2,16.1,29,3.1,0,1.75
163 | 6,4,aug,thu,95.2,131.7,578.8,10.4,20.3,41,4,0,1.9
164 | 6,3,mar,sat,90.6,50.1,100.4,7.8,15.2,31,8.5,0,1.94
165 | 8,6,sep,sat,92.5,121.1,674.4,8.6,17.8,56,1.8,0,1.95
166 | 8,5,sep,sun,89.7,90,704.4,4.8,17.8,67,2.2,0,2.01
167 | 6,5,mar,thu,84.9,18.2,55,3,5.3,70,4.5,0,2.14
168 | 6,5,aug,wed,92.1,111.2,654.1,9.6,16.6,47,0.9,0,2.29
169 | 6,5,aug,wed,96,127.1,570.5,16.5,23.4,33,4.5,0,2.51
170 | 6,5,mar,fri,91.2,48.3,97.8,12.5,14.6,26,9.4,0,2.53
171 | 8,6,aug,thu,95.2,131.7,578.8,10.4,20.7,45,2.2,0,2.55
172 | 5,4,sep,wed,92.9,133.3,699.6,9.2,21.9,35,1.8,0,2.57
173 | 8,6,aug,wed,85.6,90.4,609.6,6.6,17.4,50,4,0,2.69
174 | 7,4,aug,sun,91.4,142.4,601.4,10.6,20.1,39,5.4,0,2.74
175 | 4,4,sep,mon,90.9,126.5,686.5,7,17.7,39,2.2,0,3.07
176 | 1,4,aug,sat,90.2,96.9,624.2,8.9,14.2,53,1.8,0,3.5
177 | 1,4,aug,sat,90.2,96.9,624.2,8.9,20.3,39,4.9,0,4.53
178 | 6,5,apr,thu,81.5,9.1,55.2,2.7,5.8,54,5.8,0,4.61
179 | 2,5,aug,sun,90.2,99.6,631.2,6.3,19.2,44,2.7,0,4.69
180 | 2,5,sep,wed,90.1,82.9,735.7,6.2,18.3,45,2.2,0,4.88
181 | 8,6,aug,tue,88.8,147.3,614.5,9,14.4,66,5.4,0,5.23
182 | 1,3,sep,sun,92.4,124.1,680.7,8.5,23.9,32,6.7,0,5.33
183 | 8,6,oct,mon,84.9,32.8,664.2,3,19.1,32,4,0,5.44
184 | 5,4,feb,sun,86.8,15.6,48.3,3.9,12.4,53,2.2,0,6.38
185 | 7,4,oct,mon,91.7,48.5,696.1,11.1,16.8,45,4.5,0,6.83
186 | 8,6,aug,fri,93.9,135.7,586.7,15.1,20.8,34,4.9,0,6.96
187 | 2,5,sep,tue,91,129.5,692.6,7,17.6,46,3.1,0,7.04
188 | 8,6,mar,sun,89.3,51.3,102.2,9.6,11.5,39,5.8,0,7.19
189 | 1,5,sep,mon,90.9,126.5,686.5,7,21,42,2.2,0,7.3
190 | 6,4,mar,sat,90.8,41.9,89.4,7.9,13.3,42,0.9,0,7.4
191 | 7,4,mar,sun,90.7,44,92.4,5.5,11.5,60,4,0,8.24
192 | 6,5,mar,fri,91.2,48.3,97.8,12.5,11.7,33,4,0,8.31
193 | 2,5,aug,thu,95.2,131.7,578.8,10.4,24.2,28,2.7,0,8.68
194 | 2,2,aug,tue,94.8,108.3,647.1,17,24.6,22,4.5,0,8.71
195 | 4,5,sep,wed,92.9,133.3,699.6,9.2,24.3,25,4,0,9.41
196 | 2,2,aug,tue,94.8,108.3,647.1,17,24.6,22,4.5,0,10.01
197 | 2,5,aug,fri,93.9,135.7,586.7,15.1,23.5,36,5.4,0,10.02
198 | 6,5,apr,thu,81.5,9.1,55.2,2.7,5.8,54,5.8,0,10.93
199 | 4,5,sep,thu,92.9,137,706.4,9.2,21.5,15,0.9,0,11.06
200 | 3,4,sep,tue,91,129.5,692.6,7,13.9,59,6.3,0,11.24
201 | 2,4,sep,mon,63.5,70.8,665.3,0.8,22.6,38,3.6,0,11.32
202 | 1,5,sep,tue,91,129.5,692.6,7,21.6,33,2.2,0,11.53
203 | 6,5,mar,sun,90.1,37.6,83.7,7.2,12.4,54,3.6,0,12.1
204 | 7,4,feb,sun,83.9,8.7,32.1,2.1,8.8,68,2.2,0,13.05
205 | 8,6,oct,wed,91.4,37.9,673.8,5.2,20.2,37,2.7,0,13.7
206 | 5,6,mar,sat,90.6,50.1,100.4,7.8,15.1,64,4,0,13.99
207 | 4,5,sep,thu,92.9,137,706.4,9.2,22.1,34,1.8,0,14.57
208 | 2,2,aug,sat,93.5,139.4,594.2,20.3,22.9,31,7.2,0,15.45
209 | 7,5,sep,tue,91,129.5,692.6,7,20.7,37,2.2,0,17.2
210 | 6,5,sep,fri,92.4,117.9,668,12.2,19.6,33,6.3,0,19.23
211 | 8,3,sep,thu,93.7,80.9,685.2,17.9,23.2,26,4.9,0,23.41
212 | 4,4,oct,sat,90.6,43.7,686.9,6.7,18.4,25,3.1,0,24.23
213 | 7,4,aug,sat,93.5,139.4,594.2,20.3,5.1,96,5.8,0,26
214 | 7,4,sep,fri,94.3,85.1,692.3,15.9,20.1,47,4.9,0,26.13
215 | 7,3,mar,mon,87.6,52.2,103.8,5,11,46,5.8,0,27.35
216 | 4,4,mar,sat,91.7,35.8,80.8,7.8,17,27,4.9,0,28.66
217 | 4,4,mar,sat,91.7,35.8,80.8,7.8,17,27,4.9,0,28.66
218 | 4,4,sep,sun,92.4,124.1,680.7,8.5,16.9,60,1.3,0,29.48
219 | 1,3,sep,mon,88.6,91.8,709.9,7.1,12.4,73,6.3,0,30.32
220 | 4,5,sep,wed,92.9,133.3,699.6,9.2,19.4,19,1.3,0,31.72
221 | 6,5,mar,mon,90.1,39.7,86.6,6.2,15.2,27,3.1,0,31.86
222 | 8,6,aug,sun,90.2,99.6,631.2,6.3,16.2,59,3.1,0,32.07
223 | 3,4,sep,fri,93.3,141.2,713.9,13.9,18.6,49,3.6,0,35.88
224 | 4,3,mar,mon,87.6,52.2,103.8,5,11,46,5.8,0,36.85
225 | 2,2,jul,fri,88.3,150.3,309.9,6.8,13.4,79,3.6,0,37.02
226 | 7,4,sep,wed,90.1,82.9,735.7,6.2,15.4,57,4.5,0,37.71
227 | 4,4,sep,sun,93.5,149.3,728.6,8.1,22.9,39,4.9,0,48.55
228 | 7,5,oct,mon,91.7,48.5,696.1,11.1,16.1,44,4,0,49.37
229 | 8,6,aug,sat,92.2,81.8,480.8,11.9,20.1,34,4.5,0,58.3
230 | 4,6,sep,sun,93.5,149.3,728.6,8.1,28.3,26,3.1,0,64.1
231 | 8,6,aug,sat,92.2,81.8,480.8,11.9,16.4,43,4,0,71.3
232 | 4,4,sep,wed,92.9,133.3,699.6,9.2,26.4,21,4.5,0,88.49
233 | 1,5,sep,sun,93.5,149.3,728.6,8.1,27.8,27,3.1,0,95.18
234 | 6,4,sep,tue,91,129.5,692.6,7,18.7,43,2.7,0,103.39
235 | 9,4,sep,tue,84.4,73.4,671.9,3.2,24.3,36,3.1,0,105.66
236 | 4,5,sep,sat,92.5,121.1,674.4,8.6,17.7,25,3.1,0,154.88
237 | 8,6,aug,sun,91.4,142.4,601.4,10.6,19.6,41,5.8,0,196.48
238 | 2,2,sep,sat,92.5,121.1,674.4,8.6,18.2,46,1.8,0,200.94
239 | 1,2,sep,tue,91,129.5,692.6,7,18.8,40,2.2,0,212.88
240 | 6,5,sep,sat,92.5,121.1,674.4,8.6,25.1,27,4,0,1090.84
241 | 7,5,apr,sun,81.9,3,7.9,3.5,13.4,75,1.8,0,0
242 | 6,3,apr,wed,88,17.2,43.5,3.8,15.2,51,2.7,0,0
243 | 4,4,apr,fri,83,23.3,85.3,2.3,16.7,20,3.1,0,0
244 | 2,4,aug,sun,94.2,122.3,589.9,12.9,15.4,66,4,0,10.13
245 | 7,4,aug,sun,91.8,175.1,700.7,13.8,21.9,73,7.6,1,0
246 | 2,4,aug,sun,91.8,175.1,700.7,13.8,22.4,54,7.6,0,2.87
247 | 3,4,aug,sun,91.8,175.1,700.7,13.8,26.8,38,6.3,0,0.76
248 | 5,4,aug,sun,91.8,175.1,700.7,13.8,25.7,39,5.4,0,0.09
249 | 2,4,aug,wed,92.2,91.6,503.6,9.6,20.7,70,2.2,0,0.75
250 | 8,6,aug,wed,93.1,157.3,666.7,13.5,28.7,28,2.7,0,0
251 | 3,4,aug,wed,93.1,157.3,666.7,13.5,21.7,40,0.4,0,2.47
252 | 8,5,aug,wed,93.1,157.3,666.7,13.5,26.8,25,3.1,0,0.68
253 | 8,5,aug,wed,93.1,157.3,666.7,13.5,24,36,3.1,0,0.24
254 | 6,5,aug,wed,93.1,157.3,666.7,13.5,22.1,37,3.6,0,0.21
255 | 7,4,aug,thu,91.9,109.2,565.5,8,21.4,38,2.7,0,1.52
256 | 6,3,aug,thu,91.6,138.1,621.7,6.3,18.9,41,3.1,0,10.34
257 | 2,5,aug,thu,87.5,77,694.8,5,22.3,46,4,0,0
258 | 8,6,aug,sat,94.2,117.2,581.1,11,23.9,41,2.2,0,8.02
259 | 4,3,aug,sat,94.2,117.2,581.1,11,21.4,44,2.7,0,0.68
260 | 3,4,aug,sat,91.8,170.9,692.3,13.7,20.6,59,0.9,0,0
261 | 7,4,aug,sat,91.8,170.9,692.3,13.7,23.7,40,1.8,0,1.38
262 | 2,4,aug,mon,93.6,97.9,542,14.4,28.3,32,4,0,8.85
263 | 3,4,aug,fri,91.6,112.4,573,8.9,11.2,84,7.6,0,3.3
264 | 2,4,aug,fri,91.6,112.4,573,8.9,21.4,42,3.1,0,4.25
265 | 6,3,aug,fri,91.1,141.1,629.1,7.1,19.3,39,3.6,0,1.56
266 | 4,4,aug,fri,94.3,167.6,684.4,13,21.8,53,3.1,0,6.54
267 | 4,4,aug,tue,93.7,102.2,550.3,14.6,22.1,54,7.6,0,0.79
268 | 6,5,aug,tue,94.3,131.7,607.1,22.7,19.4,55,4,0,0.17
269 | 2,2,aug,tue,92.1,152.6,658.2,14.3,23.7,24,3.1,0,0
270 | 3,4,aug,tue,92.1,152.6,658.2,14.3,21,32,3.1,0,0
271 | 4,4,aug,tue,92.1,152.6,658.2,14.3,19.1,53,2.7,0,4.4
272 | 2,2,aug,tue,92.1,152.6,658.2,14.3,21.8,56,3.1,0,0.52
273 | 8,6,aug,tue,92.1,152.6,658.2,14.3,20.1,58,4.5,0,9.27
274 | 2,5,aug,tue,92.1,152.6,658.2,14.3,20.2,47,4,0,3.09
275 | 4,6,dec,sun,84.4,27.2,353.5,6.8,4.8,57,8.5,0,8.98
276 | 8,6,dec,wed,84,27.8,354.6,5.3,5.1,61,8,0,11.19
277 | 4,6,dec,thu,84.6,26.4,352,2,5.1,61,4.9,0,5.38
278 | 4,4,dec,mon,85.4,25.4,349.7,2.6,4.6,21,8.5,0,17.85
279 | 3,4,dec,mon,85.4,25.4,349.7,2.6,4.6,21,8.5,0,10.73
280 | 4,4,dec,mon,85.4,25.4,349.7,2.6,4.6,21,8.5,0,22.03
281 | 4,4,dec,mon,85.4,25.4,349.7,2.6,4.6,21,8.5,0,9.77
282 | 4,6,dec,fri,84.7,26.7,352.6,4.1,2.2,59,4.9,0,9.27
283 | 6,5,dec,tue,85.4,25.4,349.7,2.6,5.1,24,8.5,0,24.77
284 | 6,3,feb,sun,84.9,27.5,353.5,3.4,4.2,51,4,0,0
285 | 3,4,feb,wed,86.9,6.6,18.7,3.2,8.8,35,3.1,0,1.1
286 | 5,4,feb,fri,85.2,4.9,15.8,6.3,7.5,46,8,0,24.24
287 | 2,5,jul,sun,93.9,169.7,411.8,12.3,23.4,40,6.3,0,0
288 | 7,6,jul,wed,91.2,183.1,437.7,12.5,12.6,90,7.6,0.2,0
289 | 7,4,jul,sat,91.6,104.2,474.9,9,22.1,49,2.7,0,0
290 | 7,4,jul,sat,91.6,104.2,474.9,9,24.2,32,1.8,0,0
291 | 7,4,jul,sat,91.6,104.2,474.9,9,24.3,30,1.8,0,0
292 | 2,5,jul,sat,91.6,104.2,474.9,9,18.7,53,1.8,0,0
293 | 9,4,jul,sat,91.6,104.2,474.9,9,25.3,39,0.9,0,8
294 | 4,5,jul,fri,91.6,100.2,466.3,6.3,22.9,40,1.3,0,2.64
295 | 7,6,jul,tue,93.1,180.4,430.8,11,26.9,28,5.4,0,86.45
296 | 8,6,jul,tue,92.3,88.8,440.9,8.5,17.1,67,3.6,0,6.57
297 | 7,5,jun,sun,93.1,180.4,430.8,11,22.2,48,1.3,0,0
298 | 6,4,jun,sun,90.4,89.5,290.8,6.4,14.3,46,1.8,0,0.9
299 | 8,6,jun,sun,90.4,89.5,290.8,6.4,15.4,45,2.2,0,0
300 | 8,6,jun,wed,91.2,147.8,377.2,12.7,19.6,43,4.9,0,0
301 | 6,5,jun,sat,53.4,71,233.8,0.4,10.6,90,2.7,0,0
302 | 6,5,jun,mon,90.4,93.3,298.1,7.5,20.7,25,4.9,0,0
303 | 6,5,jun,mon,90.4,93.3,298.1,7.5,19.1,39,5.4,0,3.52
304 | 3,6,jun,fri,91.1,94.1,232.1,7.1,19.2,38,4.5,0,0
305 | 3,6,jun,fri,91.1,94.1,232.1,7.1,19.2,38,4.5,0,0
306 | 6,5,may,sat,85.1,28,113.8,3.5,11.3,94,4.9,0,0
307 | 1,4,sep,sun,89.6,84.1,714.3,5.7,19,52,2.2,0,0
308 | 7,4,sep,sun,89.6,84.1,714.3,5.7,17.1,53,5.4,0,0.41
309 | 3,4,sep,sun,89.6,84.1,714.3,5.7,23.8,35,3.6,0,5.18
310 | 2,4,sep,sun,92.4,105.8,758.1,9.9,16,45,1.8,0,0
311 | 2,4,sep,sun,92.4,105.8,758.1,9.9,24.9,27,2.2,0,0
312 | 7,4,sep,sun,92.4,105.8,758.1,9.9,25.3,27,2.7,0,0
313 | 6,3,sep,sun,92.4,105.8,758.1,9.9,24.8,28,1.8,0,14.29
314 | 2,4,sep,sun,50.4,46.2,706.6,0.4,12.2,78,6.3,0,0
315 | 6,5,sep,wed,92.6,115.4,777.1,8.8,24.3,27,4.9,0,0
316 | 4,4,sep,wed,92.6,115.4,777.1,8.8,19.7,41,1.8,0,1.58
317 | 3,4,sep,wed,91.2,134.7,817.5,7.2,18.5,30,2.7,0,0
318 | 4,5,sep,thu,92.4,96.2,739.4,8.6,18.6,24,5.8,0,0
319 | 4,4,sep,thu,92.4,96.2,739.4,8.6,19.2,24,4.9,0,3.78
320 | 6,5,sep,thu,92.8,119,783.5,7.5,21.6,27,2.2,0,0
321 | 5,4,sep,thu,92.8,119,783.5,7.5,21.6,28,6.3,0,4.41
322 | 6,3,sep,thu,92.8,119,783.5,7.5,18.9,34,7.2,0,34.36
323 | 1,4,sep,thu,92.8,119,783.5,7.5,16.8,28,4,0,7.21
324 | 6,5,sep,thu,92.8,119,783.5,7.5,16.8,28,4,0,1.01
325 | 3,5,sep,thu,90.7,136.9,822.8,6.8,12.9,39,2.7,0,2.18
326 | 6,5,sep,thu,88.1,53.3,726.9,5.4,13.7,56,1.8,0,4.42
327 | 1,4,sep,sat,92.2,102.3,751.5,8.4,24.2,27,3.1,0,0
328 | 5,4,sep,sat,92.2,102.3,751.5,8.4,24.1,27,3.1,0,0
329 | 6,5,sep,sat,92.2,102.3,751.5,8.4,21.2,32,2.2,0,0
330 | 6,5,sep,sat,92.2,102.3,751.5,8.4,19.7,35,1.8,0,0
331 | 4,3,sep,sat,92.2,102.3,751.5,8.4,23.5,27,4,0,3.33
332 | 3,3,sep,sat,92.2,102.3,751.5,8.4,24.2,27,3.1,0,6.58
333 | 7,4,sep,sat,91.2,124.4,795.3,8.5,21.5,28,4.5,0,15.64
334 | 4,4,sep,sat,91.2,124.4,795.3,8.5,17.1,41,2.2,0,11.22
335 | 1,4,sep,mon,92.1,87.7,721.1,9.5,18.1,54,3.1,0,2.13
336 | 2,3,sep,mon,91.6,108.4,764,6.2,18,51,5.4,0,0
337 | 4,3,sep,mon,91.6,108.4,764,6.2,9.8,86,1.8,0,0
338 | 7,4,sep,mon,91.6,108.4,764,6.2,19.3,44,2.2,0,0
339 | 6,3,sep,mon,91.6,108.4,764,6.2,23,34,2.2,0,56.04
340 | 8,6,sep,mon,91.6,108.4,764,6.2,22.7,35,2.2,0,7.48
341 | 2,4,sep,mon,91.6,108.4,764,6.2,20.4,41,1.8,0,1.47
342 | 2,5,sep,mon,91.6,108.4,764,6.2,19.3,44,2.2,0,3.93
343 | 8,6,sep,mon,91.9,111.7,770.3,6.5,15.7,51,2.2,0,0
344 | 6,3,sep,mon,91.5,130.1,807.1,7.5,20.6,37,1.8,0,0
345 | 8,6,sep,mon,91.5,130.1,807.1,7.5,15.9,51,4.5,0,2.18
346 | 6,3,sep,mon,91.5,130.1,807.1,7.5,12.2,66,4.9,0,6.1
347 | 2,2,sep,mon,91.5,130.1,807.1,7.5,16.8,43,3.1,0,5.83
348 | 1,4,sep,mon,91.5,130.1,807.1,7.5,21.3,35,2.2,0,28.19
349 | 5,4,sep,fri,92.1,99,745.3,9.6,10.1,75,3.6,0,0
350 | 3,4,sep,fri,92.1,99,745.3,9.6,17.4,57,4.5,0,0
351 | 5,4,sep,fri,92.1,99,745.3,9.6,12.8,64,3.6,0,1.64
352 | 5,4,sep,fri,92.1,99,745.3,9.6,10.1,75,3.6,0,3.71
353 | 4,4,sep,fri,92.1,99,745.3,9.6,15.4,53,6.3,0,7.31
354 | 7,4,sep,fri,92.1,99,745.3,9.6,20.6,43,3.6,0,2.03
355 | 7,4,sep,fri,92.1,99,745.3,9.6,19.8,47,2.7,0,1.72
356 | 7,4,sep,fri,92.1,99,745.3,9.6,18.7,50,2.2,0,5.97
357 | 4,4,sep,fri,92.1,99,745.3,9.6,20.8,35,4.9,0,13.06
358 | 4,4,sep,fri,92.1,99,745.3,9.6,20.8,35,4.9,0,1.26
359 | 6,3,sep,fri,92.5,122,789.7,10.2,15.9,55,3.6,0,0
360 | 6,3,sep,fri,92.5,122,789.7,10.2,19.7,39,2.7,0,0
361 | 1,4,sep,fri,92.5,122,789.7,10.2,21.1,39,2.2,0,8.12
362 | 6,5,sep,fri,92.5,122,789.7,10.2,18.4,42,2.2,0,1.09
363 | 4,3,sep,fri,92.5,122,789.7,10.2,17.3,45,4,0,3.94
364 | 7,4,sep,fri,88.2,55.2,732.3,11.6,15.2,64,3.1,0,0.52
365 | 4,3,sep,tue,91.9,111.7,770.3,6.5,15.9,53,2.2,0,2.93
366 | 6,5,sep,tue,91.9,111.7,770.3,6.5,21.1,35,2.7,0,5.65
367 | 6,5,sep,tue,91.9,111.7,770.3,6.5,19.6,45,3.1,0,20.03
368 | 4,5,sep,tue,91.1,132.3,812.1,12.5,15.9,38,5.4,0,1.75
369 | 4,5,sep,tue,91.1,132.3,812.1,12.5,16.4,27,3.6,0,0
370 | 6,5,sep,sat,91.2,94.3,744.4,8.4,16.8,47,4.9,0,12.64
371 | 4,5,sep,sun,91,276.3,825.1,7.1,13.8,77,7.6,0,0
372 | 7,4,sep,sun,91,276.3,825.1,7.1,13.8,77,7.6,0,11.06
373 | 3,4,jul,wed,91.9,133.6,520.5,8,14.2,58,4,0,0
374 | 4,5,aug,sun,92,203.2,664.5,8.1,10.4,75,0.9,0,0
375 | 5,4,aug,thu,94.8,222.4,698.6,13.9,20.3,42,2.7,0,0
376 | 6,5,sep,fri,90.3,290,855.3,7.4,10.3,78,4,0,18.3
377 | 6,5,sep,sat,91.2,94.3,744.4,8.4,15.4,57,4.9,0,39.35
378 | 8,6,aug,mon,92.1,207,672.6,8.2,21.1,54,2.2,0,0
379 | 2,2,aug,sat,93.7,231.1,715.1,8.4,21.9,42,2.2,0,174.63
380 | 6,5,mar,thu,90.9,18.9,30.6,8,8.7,51,5.8,0,0
381 | 4,5,jan,sun,18.7,1.1,171.4,0,5.2,100,0.9,0,0
382 | 5,4,jul,wed,93.7,101.3,458.8,11.9,19.3,39,7.2,0,7.73
383 | 8,6,aug,thu,90.7,194.1,643,6.8,16.2,63,2.7,0,16.33
384 | 8,6,aug,wed,95.2,217.7,690,18,28.2,29,1.8,0,5.86
385 | 9,6,aug,thu,91.6,248.4,753.8,6.3,20.5,58,2.7,0,42.87
386 | 8,4,aug,sat,91.6,273.8,819.1,7.7,21.3,44,4.5,0,12.18
387 | 2,4,aug,sun,91.6,181.3,613,7.6,20.9,50,2.2,0,16
388 | 3,4,sep,sun,90.5,96.7,750.5,11.4,20.6,55,5.4,0,24.59
389 | 5,5,mar,thu,90.9,18.9,30.6,8,11.6,48,5.4,0,0
390 | 6,4,aug,fri,94.8,227,706.7,12,23.3,34,3.1,0,28.74
391 | 7,4,aug,fri,94.8,227,706.7,12,23.3,34,3.1,0,0
392 | 7,4,feb,mon,84.7,9.5,58.3,4.1,7.5,71,6.3,0,9.96
393 | 8,6,sep,fri,91.1,91.3,738.1,7.2,20.7,46,2.7,0,30.18
394 | 1,3,sep,sun,91,276.3,825.1,7.1,21.9,43,4,0,70.76
395 | 2,4,mar,tue,93.4,15,25.6,11.4,15.2,19,7.6,0,0
396 | 6,5,feb,mon,84.1,4.6,46.7,2.2,5.3,68,1.8,0,0
397 | 4,5,feb,sun,85,9,56.9,3.5,10.1,62,1.8,0,51.78
398 | 4,3,sep,sun,90.5,96.7,750.5,11.4,20.4,55,4.9,0,3.64
399 | 5,6,aug,sun,91.6,181.3,613,7.6,24.3,33,3.6,0,3.63
400 | 1,2,aug,sat,93.7,231.1,715.1,8.4,25.9,32,3.1,0,0
401 | 9,5,jun,wed,93.3,49.5,297.7,14,28,34,4.5,0,0
402 | 9,5,jun,wed,93.3,49.5,297.7,14,28,34,4.5,0,8.16
403 | 3,4,sep,thu,91.1,88.2,731.7,8.3,22.8,46,4,0,4.95
404 | 9,9,aug,fri,94.8,227,706.7,12,25,36,4,0,0
405 | 8,6,aug,thu,90.7,194.1,643,6.8,21.3,41,3.6,0,0
406 | 2,4,sep,wed,87.9,84.8,725.1,3.7,21.8,34,2.2,0,6.04
407 | 2,2,aug,tue,94.6,212.1,680.9,9.5,27.9,27,2.2,0,0
408 | 6,5,sep,sat,87.1,291.3,860.6,4,17,67,4.9,0,3.95
409 | 4,5,feb,sat,84.7,8.2,55,2.9,14.2,46,4,0,0
410 | 4,3,sep,fri,90.3,290,855.3,7.4,19.9,44,3.1,0,7.8
411 | 1,4,jul,tue,92.3,96.2,450.2,12.1,23.4,31,5.4,0,0
412 | 6,3,feb,fri,84.1,7.3,52.8,2.7,14.7,42,2.7,0,0
413 | 7,4,feb,fri,84.6,3.2,43.6,3.3,8.2,53,9.4,0,4.62
414 | 9,4,jul,mon,92.3,92.1,442.1,9.8,22.8,27,4.5,0,1.63
415 | 7,5,aug,sat,93.7,231.1,715.1,8.4,26.4,33,3.6,0,0
416 | 5,4,aug,sun,93.6,235.1,723.1,10.1,24.1,50,4,0,0
417 | 8,6,aug,thu,94.8,222.4,698.6,13.9,27.5,27,4.9,0,746.28
418 | 6,3,jul,tue,92.7,164.1,575.8,8.9,26.3,39,3.1,0,7.02
419 | 6,5,mar,wed,93.4,17.3,28.3,9.9,13.8,24,5.8,0,0
420 | 2,4,aug,sun,92,203.2,664.5,8.1,24.9,42,5.4,0,2.44
421 | 2,5,aug,sun,91.6,181.3,613,7.6,24.8,36,4,0,3.05
422 | 8,8,aug,wed,91.7,191.4,635.9,7.8,26.2,36,4.5,0,185.76
423 | 2,4,aug,wed,95.2,217.7,690,18,30.8,19,4.5,0,0
424 | 8,6,jul,sun,88.9,263.1,795.9,5.2,29.3,27,3.6,0,6.3
425 | 1,3,sep,sat,91.2,94.3,744.4,8.4,22.3,48,4,0,0.72
426 | 8,6,aug,sat,93.7,231.1,715.1,8.4,26.9,31,3.6,0,4.96
427 | 2,2,aug,thu,91.6,248.4,753.8,6.3,20.4,56,2.2,0,0
428 | 8,6,aug,thu,91.6,248.4,753.8,6.3,20.4,56,2.2,0,0
429 | 2,4,aug,mon,92.1,207,672.6,8.2,27.9,33,2.2,0,2.35
430 | 1,3,aug,thu,94.8,222.4,698.6,13.9,26.2,34,5.8,0,0
431 | 3,4,aug,sun,91.6,181.3,613,7.6,24.6,44,4,0,3.2
432 | 7,4,sep,thu,89.7,287.2,849.3,6.8,19.4,45,3.6,0,0
433 | 1,3,aug,sat,92.1,178,605.3,9.6,23.3,40,4,0,6.36
434 | 8,6,aug,thu,94.8,222.4,698.6,13.9,23.9,38,6.7,0,0
435 | 2,4,aug,sun,93.6,235.1,723.1,10.1,20.9,66,4.9,0,15.34
436 | 1,4,aug,fri,90.6,269.8,811.2,5.5,22.2,45,3.6,0,0
437 | 2,5,jul,sat,90.8,84.7,376.6,5.6,23.8,51,1.8,0,0
438 | 8,6,aug,mon,92.1,207,672.6,8.2,26.8,35,1.3,0,0.54
439 | 8,6,aug,sat,89.4,253.6,768.4,9.7,14.2,73,2.7,0,0
440 | 2,5,aug,sat,93.7,231.1,715.1,8.4,23.6,53,4,0,6.43
441 | 1,3,sep,fri,91.1,91.3,738.1,7.2,19.1,46,2.2,0,0.33
442 | 5,4,sep,fri,90.3,290,855.3,7.4,16.2,58,3.6,0,0
443 | 8,6,aug,mon,92.1,207,672.6,8.2,25.5,29,1.8,0,1.23
444 | 6,5,apr,mon,87.9,24.9,41.6,3.7,10.9,64,3.1,0,3.35
445 | 1,2,jul,fri,90.7,80.9,368.3,16.8,14.8,78,8,0,0
446 | 2,5,sep,fri,90.3,290,855.3,7.4,16.2,58,3.6,0,9.96
447 | 5,5,aug,sun,94,47.9,100.7,10.7,17.3,80,4.5,0,0
448 | 6,5,aug,sun,92,203.2,664.5,8.1,19.1,70,2.2,0,0
449 | 3,4,mar,wed,93.4,17.3,28.3,9.9,8.9,35,8,0,0
450 | 7,4,sep,wed,89.7,284.9,844,10.1,10.5,77,4,0,0
451 | 7,4,aug,sun,91.6,181.3,613,7.6,19.3,61,4.9,0,0
452 | 4,5,aug,wed,95.2,217.7,690,18,23.4,49,5.4,0,6.43
453 | 1,4,aug,fri,90.5,196.8,649.9,16.3,11.8,88,4.9,0,9.71
454 | 7,4,aug,mon,91.5,238.2,730.6,7.5,17.7,65,4,0,0
455 | 4,5,aug,thu,89.4,266.2,803.3,5.6,17.4,54,3.1,0,0
456 | 3,4,aug,thu,91.6,248.4,753.8,6.3,16.8,56,3.1,0,0
457 | 3,4,jul,mon,94.6,160,567.2,16.7,17.9,48,2.7,0,0
458 | 2,4,aug,thu,91.6,248.4,753.8,6.3,16.6,59,2.7,0,0
459 | 1,4,aug,wed,91.7,191.4,635.9,7.8,19.9,50,4,0,82.75
460 | 8,6,aug,sat,93.7,231.1,715.1,8.4,18.9,64,4.9,0,3.32
461 | 7,4,aug,sat,91.6,273.8,819.1,7.7,15.5,72,8,0,1.94
462 | 2,5,aug,sat,93.7,231.1,715.1,8.4,18.9,64,4.9,0,0
463 | 8,6,aug,sat,93.7,231.1,715.1,8.4,18.9,64,4.9,0,0
464 | 1,4,sep,sun,91,276.3,825.1,7.1,14.5,76,7.6,0,3.71
465 | 6,5,feb,tue,75.1,4.4,16.2,1.9,4.6,82,6.3,0,5.39
466 | 6,4,feb,tue,75.1,4.4,16.2,1.9,5.1,77,5.4,0,2.14
467 | 2,2,feb,sat,79.5,3.6,15.3,1.8,4.6,59,0.9,0,6.84
468 | 6,5,mar,mon,87.2,15.1,36.9,7.1,10.2,45,5.8,0,3.18
469 | 3,4,mar,wed,90.2,18.5,41.1,7.3,11.2,41,5.4,0,5.55
470 | 6,5,mar,thu,91.3,20.6,43.5,8.5,13.3,27,3.6,0,6.61
471 | 6,3,apr,sun,91,14.6,25.6,12.3,13.7,33,9.4,0,61.13
472 | 5,4,apr,sun,91,14.6,25.6,12.3,17.6,27,5.8,0,0
473 | 4,3,may,fri,89.6,25.4,73.7,5.7,18,40,4,0,38.48
474 | 8,3,jun,mon,88.2,96.2,229,4.7,14.3,79,4,0,1.94
475 | 9,4,jun,sat,90.5,61.1,252.6,9.4,24.5,50,3.1,0,70.32
476 | 4,3,jun,thu,93,103.8,316.7,10.8,26.4,35,2.7,0,10.08
477 | 2,5,jun,thu,93.7,121.7,350.2,18,22.7,40,9.4,0,3.19
478 | 4,3,jul,thu,93.5,85.3,395,9.9,27.2,28,1.3,0,1.76
479 | 4,3,jul,sun,93.7,101.3,423.4,14.7,26.1,45,4,0,7.36
480 | 7,4,jul,sun,93.7,101.3,423.4,14.7,18.2,82,4.5,0,2.21
481 | 7,4,jul,mon,89.2,103.9,431.6,6.4,22.6,57,4.9,0,278.53
482 | 9,9,jul,thu,93.2,114.4,560,9.5,30.2,25,4.5,0,2.75
483 | 4,3,jul,thu,93.2,114.4,560,9.5,30.2,22,4.9,0,0
484 | 3,4,aug,sun,94.9,130.3,587.1,14.1,23.4,40,5.8,0,1.29
485 | 8,6,aug,sun,94.9,130.3,587.1,14.1,31,27,5.4,0,0
486 | 2,5,aug,sun,94.9,130.3,587.1,14.1,33.1,25,4,0,26.43
487 | 2,4,aug,mon,95,135.5,596.3,21.3,30.6,28,3.6,0,2.07
488 | 5,4,aug,tue,95.1,141.3,605.8,17.7,24.1,43,6.3,0,2
489 | 5,4,aug,tue,95.1,141.3,605.8,17.7,26.4,34,3.6,0,16.4
490 | 4,4,aug,tue,95.1,141.3,605.8,17.7,19.4,71,7.6,0,46.7
491 | 4,4,aug,wed,95.1,141.3,605.8,17.7,20.6,58,1.3,0,0
492 | 4,4,aug,wed,95.1,141.3,605.8,17.7,28.7,33,4,0,0
493 | 4,4,aug,thu,95.8,152,624.1,13.8,32.4,21,4.5,0,0
494 | 1,3,aug,fri,95.9,158,633.6,11.3,32.4,27,2.2,0,0
495 | 1,3,aug,fri,95.9,158,633.6,11.3,27.5,29,4.5,0,43.32
496 | 6,6,aug,sat,96,164,643,14,30.8,30,4.9,0,8.59
497 | 6,6,aug,mon,96.2,175.5,661.8,16.8,23.9,42,2.2,0,0
498 | 4,5,aug,mon,96.2,175.5,661.8,16.8,32.6,26,3.1,0,2.77
499 | 3,4,aug,tue,96.1,181.1,671.2,14.3,32.3,27,2.2,0,14.68
500 | 6,5,aug,tue,96.1,181.1,671.2,14.3,33.3,26,2.7,0,40.54
501 | 7,5,aug,tue,96.1,181.1,671.2,14.3,27.3,63,4.9,6.4,10.82
502 | 8,6,aug,tue,96.1,181.1,671.2,14.3,21.6,65,4.9,0.8,0
503 | 7,5,aug,tue,96.1,181.1,671.2,14.3,21.6,65,4.9,0.8,0
504 | 4,4,aug,tue,96.1,181.1,671.2,14.3,20.7,69,4.9,0.4,0
505 | 2,4,aug,wed,94.5,139.4,689.1,20,29.2,30,4.9,0,1.95
506 | 4,3,aug,wed,94.5,139.4,689.1,20,28.9,29,4.9,0,49.59
507 | 1,2,aug,thu,91,163.2,744.4,10.1,26.7,35,1.8,0,5.8
508 | 1,2,aug,fri,91,166.9,752.6,7.1,18.5,73,8.5,0,0
509 | 2,4,aug,fri,91,166.9,752.6,7.1,25.9,41,3.6,0,0
510 | 1,2,aug,fri,91,166.9,752.6,7.1,25.9,41,3.6,0,0
511 | 5,4,aug,fri,91,166.9,752.6,7.1,21.1,71,7.6,1.4,2.17
512 | 6,5,aug,fri,91,166.9,752.6,7.1,18.2,62,5.4,0,0.43
513 | 8,6,aug,sun,81.6,56.7,665.6,1.9,27.8,35,2.7,0,0
514 | 4,3,aug,sun,81.6,56.7,665.6,1.9,27.8,32,2.7,0,6.44
515 | 2,4,aug,sun,81.6,56.7,665.6,1.9,21.9,71,5.8,0,54.29
516 | 7,4,aug,sun,81.6,56.7,665.6,1.9,21.2,70,6.7,0,11.16
517 | 1,4,aug,sat,94.4,146,614.7,11.3,25.6,42,4,0,0
518 | 6,3,nov,tue,79.5,3,106.7,1.1,11.8,31,4.5,0,0
519 |
--------------------------------------------------------------------------------
/led_board.py:
--------------------------------------------------------------------------------
1 | from gpiozero import LEDBoard
2 | from time import sleep
3 | import sys
4 |
5 | # Define Morse code dictionary
6 | MORSE_CODE = {
7 | 'A': '.-', 'B': '-...', 'C': '-.-.', 'D': '-..', 'E': '.',
8 | 'F': '..-.', 'G': '--.', 'H': '....', 'I': '..', 'J': '.---',
9 | 'K': '-.-', 'L': '.-..', 'M': '--', 'N': '-.', 'O': '---',
10 | 'P': '.--.', 'Q': '--.-', 'R': '.-.', 'S': '...', 'T': '-',
11 | 'U': '..-', 'V': '...-', 'W': '.--', 'X': '-..-', 'Y': '-.--', 'Z': '--..',
12 | '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....',
13 | '6': '-....', '7': '--...', '8': '---..', '9': '----.', '0': '-----',
14 | ' ': ' '
15 | }
16 |
17 | def encode_to_leds(leds, word):
18 | word = word.upper()
19 | for char in word:
20 | if char not in MORSE_CODE:
21 | print(f"Warning: Character '{char}' is not valid Morse code. Skipping.")
22 | continue
23 |
24 | code = MORSE_CODE[char]
25 | # turn on
26 | for i, symbol in enumerate(code):
27 | if i >= len(leds):
28 | break
29 | if symbol == '-' or symbol == '.':
30 | leds[i].on()
31 | sleep(1)
32 |
33 | # turn off '.'
34 | for i, symbol in enumerate(code):
35 | if i >= len(leds):
36 | break
37 | if symbol == '.':
38 | leds[i].off()
39 | sleep(1)
40 |
41 | # turn off '-'
42 | for i, symbol in enumerate(code):
43 | if i >= len(leds):
44 | break
45 | leds[i].off()
46 |
47 | sleep(3)
48 |
49 | if __name__ == "__main__":
50 | if len(sys.argv) != 2:
51 | print("Usage: sudo python3 LEDboard.py ")
52 | sys.exit(1)
53 |
54 | input_word = sys.argv[1]
55 |
56 | # Initialize LEDBoard with 5 GPIO pins
57 | leds = LEDBoard(5, 6, 13, 19, 26)
58 |
59 |
60 | try:
61 | encode_to_leds(leds, input_word)
62 | except KeyboardInterrupt:
63 | pass
64 | finally:
65 | leds.off()
66 |
--------------------------------------------------------------------------------
/list_dict_comprehension_exercises.md:
--------------------------------------------------------------------------------
1 | Here are 5 simple exercises that focus on converting basic Python code into list or dictionary comprehensions:
2 |
3 | ---
4 |
5 | ### **Exercise 1: Convert a For Loop to List Comprehension**
6 | Convert the following for loop into a list comprehension:
7 |
8 | ```python
9 | result = []
10 | for x in range(10):
11 | result.append(x**2)
12 | ```
13 |
14 | ---
15 |
16 | ### **Exercise 2: Filter Numbers with List Comprehension**
17 | Rewrite this code using a list comprehension:
18 |
19 | ```python
20 | result = []
21 | for x in range(20):
22 | if x % 2 == 0:
23 | result.append(x)
24 | ```
25 |
26 | ---
27 |
28 | ### **Exercise 3: Dictionary Comprehension**
29 | Convert the following code to a dictionary comprehension:
30 |
31 | ```python
32 | squares = {}
33 | for x in range(5):
34 | squares[x] = x**2
35 | ```
36 |
37 | ---
38 |
39 | ### **Exercise 4: Nested Loops with List Comprehension**
40 | Rewrite the nested loop as a list comprehension:
41 |
42 | ```python
43 | pairs = []
44 | for x in range(3):
45 | for y in range(2):
46 | pairs.append((x, y))
47 | ```
48 |
49 | ---
50 |
51 | ### **Exercise 5: Conditional Dictionary Comprehension**
52 | Transform the following code into a dictionary comprehension with a condition:
53 |
54 | ```python
55 | filtered_squares = {}
56 | for x in range(10):
57 | if x % 2 == 0:
58 | filtered_squares[x] = x**2
59 | ```
60 |
61 | ---
62 |
63 | Certainly! Here's a set of slightly more challenging exercises involving list and dictionary comprehensions:
64 |
65 | ---
66 |
67 | ### **Exercise 1: Conditional Transformation in List Comprehension**
68 | Convert the following loop into a list comprehension that includes a conditional transformation:
69 |
70 | ```python
71 | result = []
72 | for x in range(15):
73 | if x % 3 == 0:
74 | result.append(x**2)
75 | else:
76 | result.append(x)
77 | ```
78 |
79 | ---
80 |
81 | ### **Exercise 2: Dictionary Comprehension with String Keys**
82 | Transform the following loop into a dictionary comprehension, using strings as keys:
83 |
84 | ```python
85 | word_lengths = {}
86 | words = ["apple", "banana", "cherry", "date"]
87 | for word in words:
88 | word_lengths[word] = len(word)
89 | ```
90 |
91 | ---
92 |
93 | ### **Exercise 3: Flatten a Nested List with List Comprehension**
94 | Rewrite this code using a single list comprehension to flatten the nested list:
95 |
96 | ```python
97 | nested_list = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
98 | flattened = []
99 | for sublist in nested_list:
100 | for item in sublist:
101 | flattened.append(item)
102 | ```
103 |
104 | ---
105 |
106 | ### **Exercise 4: Conditional Dictionary Comprehension with Nested Loops**
107 | Convert the following nested loop into a dictionary comprehension with a condition:
108 |
109 | ```python
110 | result = {}
111 | for i in range(3):
112 | for j in range(3, 6):
113 | if j % i != 0: # Avoid division by zero
114 | result[(i, j)] = i + j
115 | ```
116 |
117 | ---
118 |
119 | ### **Exercise 5: Filter and Transform Nested Dictionaries**
120 | Use a dictionary comprehension to filter and transform the following dictionary of dictionaries:
121 |
122 | ```python
123 | data = {
124 | "A": {"score": 90, "passed": True},
125 | "B": {"score": 65, "passed": False},
126 | "C": {"score": 75, "passed": True},
127 | "D": {"score": 50, "passed": False},
128 | }
129 |
130 | # Goal: Include only students who passed, and create a dictionary of their scores.
131 | result = {}
132 | for key, value in data.items():
133 | if value["passed"]:
134 | result[key] = value["score"]
135 | ```
136 |
137 | ---
138 |
139 | These exercises require a bit more thinking about conditions, transformations, and handling nested structures, but they're still approachable for intermediate learners!
140 |
--------------------------------------------------------------------------------
/nursery_v1.py:
--------------------------------------------------------------------------------
1 | class Plant:
2 | def __init__(self, species):
3 | self.species = species
4 |
5 | class Tray:
6 | def __init__(self, species, count):
7 | self.species = species
8 | self.count = count # Number of plants of the same species in the tray
9 |
10 | def add_plants(self, number):
11 | """Add plants to the tray."""
12 | self.count += number
13 |
14 | def remove_plants(self, number):
15 | """Remove plants from the tray. Returns the number removed."""
16 | if number > self.count:
17 | removed = self.count
18 | self.count = 0
19 | else:
20 | self.count -= number
21 | removed = number
22 | return removed
23 |
24 | def __repr__(self):
25 | return f"Tray(species={self.species}, count={self.count})"
26 |
27 | class Pot:
28 | def __init__(self, species):
29 | self.species = species
30 |
31 | class Nursery:
32 | def __init__(self):
33 | self.trays = [] # A list of trays in the nursery
34 | self.pots = [] # A list of pots in the nursery
35 | self.tray_inventory = {} # Dictionary to track inventory of each species in the nursery
36 | self.pot_inventory = {} # Dictionary to track inventory of each species in the nursery
37 |
38 | def add_tray(self, species, count):
39 | # Add a tray of a given species and count.
40 | tray = Tray(species, count)
41 | self.trays.append(tray)
42 | # Update the inventory
43 | if species in self.tray_inventory:
44 | self.tray_inventory[species] += count
45 | else:
46 | self.tray_inventory[species] = count
47 |
48 | def remove_plants_from_tray(self, species, count):
49 | # Remove plants of a given species from trays.
50 | removed_count = 0
51 | for tray in self.trays:
52 | if tray.species == species:
53 | number_removed = tray.remove_plants(count)
54 | removed_count += number_removed
55 | count -= number_removed
56 | if number_removed > count:
57 | break
58 | # Update the inventory
59 | if species in self.tray_inventory:
60 | self.tray_inventory[species] -= removed_count
61 | if self.tray_inventory[species] <= 0:
62 | del self.tray_inventory[species]
63 |
64 | def get_inventory(self):
65 | """Returns the current inventory of plants in the nursery."""
66 | return self.tray_inventory
67 |
68 | # Create a nursery
69 | nursery = Nursery()
70 |
71 | # Add trays to the nursery
72 | nursery.add_tray('Tomato', 20)
73 | nursery.add_tray('Cucumber', 15)
74 | nursery.add_tray('Tomato', 30)
75 |
76 | # View the nursery's inventory
77 | print(nursery.get_inventory()) # {'Tomato': 50, 'Cucumber': 15}
78 |
79 | # Remove some plants from a tray
80 | nursery.remove_plants_from_tray('Tomato', 40)
81 |
82 | # View updated inventory
83 | print(nursery.get_inventory()) # {'Tomato': 40, 'Cucumber': 15}
84 |
85 | # View the trays to see how many plants are left
86 | print(nursery.trays) # [Tray(species=Tomato, count=10), Tray(species=Cucumber, count=15), Tray(species=Tomato, count=30)]
87 |
--------------------------------------------------------------------------------
/rural_fires.csv:
--------------------------------------------------------------------------------
1 | Statistical table extracted on October 17, 2024 (23:02:41),,
2 | http://www.ine.pt,,,
3 | ,,,
4 | ,,,
5 | ,,,
6 | Geographic localization (NUTS - 2024);Rural fires (No.) by Geographic localization (NUTS - 2024) and Cause of fire - Annual;;;;;;;,,,
7 | ;Data reference period;;;;;;;,,,
8 | ;2023;;;;;;;,,,
9 | ;Cause of fire;;;;;;;,,,
10 | ;Total;Negligence;Intentional;Naturais;Re-ignition;Undetermined;Not investigated;,,,
11 | ;No. ;No. ;No. ;No. ;No. ;No. ;No. ;,,,
12 | PT: Portugal;7559 &;3046 &;1524 &;77 &;256 &;2393 &;263 &;,,,
13 | 1: Continente;7520 &;3040 &;1522 &;77 &;256 &;2362 &;263 &;,,,
14 | 11: Norte;3986 &;1480 &;707 &;25 &;189 &;1409 &;176 &;,,,
15 | 111: Alto Minho;629 &;370 &;219 &;0 &;26 &;14 &;0 &;,,,
16 | 1111601: Arcos de Valdevez;104 &;73 &;27 &;0 &;4 &;0 &;0 &;,,,
17 | 1111602: Caminha;17 &;10 &;6 &;0 &;1 &;0 &;0 &;,,,
18 | 1111603: Melga�o;25 &;24 &;0 &;0 &;1 &;0 &;0 &;,,,
19 | 1111604: Mon��o;35 &;25 &;9 &;0 &;1 &;0 &;0 &;,,,
20 | 1111605: Paredes de Coura;23 &;16 &;6 &;0 &;0 &;1 &;0 &;,,,
21 | 1111606: Ponte da Barca;215 &;92 &;110 &;0 &;13 &;0 &;0 &;,,,
22 | 1111607: Ponte de Lima;98 &;39 &;40 &;0 &;6 &;13 &;0 &;,,,
23 | 1111608: Valen�a;33 &;27 &;6 &;0 &;0 &;0 &;0 &;,,,
24 | 1111609: Viana do Castelo;72 &;57 &;15 &;0 &;0 &;0 &;0 &;,,,
25 | 1111610: Vila Nova de Cerveira;7 &;7 &;0 &;0 &;0 &;0 &;0 &;,,,
26 | 112: C�vado;252 &;120 &;70 &;1 &;15 &;45 &;1 &;,,,
27 | 1120301: Amares;12 &;4 &;5 &;0 &;0 &;2 &;1 &;,,,
28 | 1120302: Barcelos;58 &;19 &;15 &;1 &;5 &;18 &;0 &;,,,
29 | 1120303: Braga;35 &;11 &;9 &;0 &;6 &;9 &;0 &;,,,
30 | 1120306: Esposende;9 &;6 &;0 &;0 &;0 &;3 &;0 &;,,,
31 | 1120310: Terras de Bouro;36 &;27 &;6 &;0 &;2 &;1 &;0 &;,,,
32 | 1120313: Vila Verde;102 &;53 &;35 &;0 &;2 &;12 &;0 &;,,,
33 | 119: Ave;468 &;202 &;173 &;3 &;39 &;50 &;1 &;,,,
34 | 1190304: Cabeceiras de Basto;44 &;27 &;10 &;1 &;6 &;0 &;0 &;,,,
35 | 1190307: Fafe;116 &;42 &;63 &;0 &;11 &;0 &;0 &;,,,
36 | 1190308: Guimar�es;54 &;23 &;22 &;0 &;4 &;4 &;1 &;,,,
37 | 1191705: Mondim de Basto;14 &;9 &;2 &;2 &;1 &;0 &;0 &;,,,
38 | 1190309: P�voa de Lanhoso;73 &;54 &;5 &;0 &;8 &;6 &;0 &;,,,
39 | 1190311: Vieira do Minho;98 &;34 &;57 &;0 &;3 &;4 &;0 &;,,,
40 | 1190312: Vila Nova de Famalic�o;61 &;10 &;9 &;0 &;6 &;36 &;0 &;,,,
41 | 1190314: Vizela;8 &;3 &;5 &;0 &;0 &;0 &;0 &;,,,
42 | 11A: �rea Metropolitana do Porto;1072 &;159 &;21 &;1 &;40 &;677 &;174 &;,,,
43 | 11A0104: Arouca;69 &;43 &;1 &;0 &;1 &;24 &;0 &;,,,
44 | 11A0107: Espinho;1 &;0 &;1 &;0 &;0 &;0 &;0 &;,,,
45 | 11A1304: Gondomar;127 &;7 &;1 &;0 &;1 &;118 &;0 &;,,,
46 | 11A1306: Maia;65 &;5 &;5 &;0 &;2 &;1 &;52 &;,,,
47 | 11A1308: Matosinhos;56 &;2 &;0 &;0 &;16 &;2 &;36 &;,,,
48 | 11A0113: Oliveira de Azem�is;63 &;13 &;0 &;0 &;0 &;50 &;0 &;,,,
49 | 11A1310: Paredes;164 &;6 &;3 &;0 &;11 &;144 &;0 &;,,,
50 | 11A1312: Porto;16 &;0 &;0 &;0 &;0 &;0 &;16 &;,,,
51 | 11A1313: P�voa de Varzim;29 &;0 &;0 &;0 &;0 &;0 &;29 &;,,,
52 | 11A0109: Santa Maria da Feira;64 &;26 &;3 &;0 &;8 &;27 &;0 &;,,,
53 | 11A1314: Santo Tirso;85 &;22 &;0 &;0 &;0 &;63 &;0 &;,,,
54 | 11A0116: S�o Jo�o da Madeira;4 &;2 &;0 &;0 &;0 &;2 &;0 &;,,,
55 | 11A1318: Trofa;44 &;5 &;1 &;0 &;0 &;38 &;0 &;,,,
56 | 11A0119: Vale de Cambra;37 &;10 &;0 &;1 &;0 &;26 &;0 &;,,,
57 | 11A1315: Valongo;52 &;4 &;0 &;0 &;1 &;47 &;0 &;,,,
58 | 11A1316: Vila do Conde;49 &;2 &;6 &;0 &;0 &;0 &;41 &;,,,
59 | 11A1317: Vila Nova de Gaia;147 &;12 &;0 &;0 &;0 &;135 &;0 &;,,,
60 | 11B: Alto T�mega e Barroso;317 &;254 &;39 &;3 &;16 &;5 &;0 &;,,,
61 | 11B1702: Boticas;47 &;41 &;3 &;1 &;2 &;0 &;0 &;,,,
62 | 11B1703: Chaves;36 &;29 &;5 &;0 &;2 &;0 &;0 &;,,,
63 | 11B1706: Montalegre;117 &;104 &;10 &;0 &;3 &;0 &;0 &;,,,
64 | 11B1709: Ribeira de Pena;23 &;15 &;4 &;1 &;1 &;2 &;0 &;,,,
65 | 11B1712: Valpa�os;51 &;45 &;2 &;1 &;3 &;0 &;0 &;,,,
66 | 11B1713: Vila Pouca de Aguiar;43 &;20 &;15 &;0 &;5 &;3 &;0 &;,,,
67 | 11C: T�mega e Sousa;878 &;158 &;103 &;0 &;37 &;580 &;0 &;,,,
68 | 11C1301: Amarante;132 &;7 &;32 &;0 &;4 &;89 &;0 &;,,,
69 | 11C1302: Bai�o;80 &;5 &;25 &;0 &;0 &;50 &;0 &;,,,
70 | 11C0106: Castelo de Paiva;33 &;9 &;0 &;0 &;0 &;24 &;0 &;,,,
71 | 11C0305: Celorico de Basto;40 &;22 &;16 &;0 &;2 &;0 &;0 &;,,,
72 | 11C1804: Cinf�es;66 &;45 &;18 &;0 &;3 &;0 &;0 &;,,,
73 | 11C1303: Felgueiras;74 &;15 &;0 &;0 &;5 &;54 &;0 &;,,,
74 | 11C1305: Lousada;129 &;18 &;1 &;0 &;3 &;107 &;0 &;,,,
75 | 11C1307: Marco de Canaveses;102 &;8 &;2 &;0 &;10 &;82 &;0 &;,,,
76 | 11C1309: Pa�os de Ferreira;69 &;5 &;0 &;0 &;0 &;64 &;0 &;,,,
77 | 11C1311: Penafiel;132 &;11 &;2 &;0 &;9 &;110 &;0 &;,,,
78 | 11C1813: Resende;21 &;13 &;7 &;0 &;1 &;0 &;0 &;,,,
79 | 11D: Douro;266 &;138 &;76 &;14 &;13 &;25 &;0 &;,,,
80 | 11D1701: Alij�;15 &;8 &;0 &;1 &;0 &;6 &;0 &;,,,
81 | 11D1801: Armamar;5 &;2 &;3 &;0 &;0 &;0 &;0 &;,,,
82 | 11D0403: Carrazeda de Ansi�es;8 &;3 &;3 &;1 &;0 &;1 &;0 &;,,,
83 | 11D0404: Freixo de Espada � Cinta;10 &;10 &;0 &;0 &;0 &;0 &;0 &;,,,
84 | 11D1805: Lamego;39 &;25 &;13 &;0 &;1 &;0 &;0 &;,,,
85 | 11D1704: Mes�o Frio;8 &;0 &;4 &;0 &;1 &;3 &;0 &;,,,
86 | 11D1807: Moimenta da Beira;18 &;13 &;3 &;0 &;2 &;0 &;0 &;,,,
87 | 11D1707: Mur�a;8 &;5 &;0 &;1 &;1 &;1 &;0 &;,,,
88 | 11D1812: Penedono;7 &;2 &;5 &;0 &;0 &;0 &;0 &;,,,
89 | 11D1708: Peso da R�gua;15 &;6 &;3 &;0 &;2 &;4 &;0 &;,,,
90 | 11D1710: Sabrosa;16 &;2 &;6 &;0 &;3 &;5 &;0 &;,,,
91 | 11D1711: Santa Marta de Penagui�o;11 &;3 &;4 &;0 &;0 &;4 &;0 &;,,,
92 | 11D1815: S�o Jo�o da Pesqueira;11 &;9 &;1 &;1 &;0 &;0 &;0 &;,,,
93 | 11D1818: Sernancelhe;14 &;5 &;5 &;4 &;0 &;0 &;0 &;,,,
94 | 11D1819: Tabua�o;10 &;8 &;1 &;1 &;0 &;0 &;0 &;,,,
95 | 11D1820: Tarouca;13 &;9 &;2 &;1 &;1 &;0 &;0 &;,,,
96 | 11D0409: Torre de Moncorvo;11 &;2 &;6 &;2 &;0 &;1 &;0 &;,,,
97 | 11D0914: Vila Nova de Foz C�a;5 &;5 &;0 &;0 &;0 &;0 &;0 &;,,,
98 | 11D1714: Vila Real;42 &;21 &;17 &;2 &;2 &;0 &;0 &;,,,
99 | 11E: Terras de Tr�s-os-Montes;104 &;79 &;6 &;3 &;3 &;13 &;0 &;,,,
100 | 11E0401: Alf�ndega da F�;1 &;0 &;0 &;0 &;0 &;1 &;0 &;,,,
101 | 11E0402: Bragan�a;22 &;18 &;1 &;0 &;0 &;3 &;0 &;,,,
102 | 11E0405: Macedo de Cavaleiros;14 &;10 &;1 &;1 &;0 &;2 &;0 &;,,,
103 | 11E0406: Miranda do Douro;5 &;4 &;0 &;0 &;0 &;1 &;0 &;,,,
104 | 11E0407: Mirandela;4 &;4 &;0 &;0 &;0 &;0 &;0 &;,,,
105 | 11E0408: Mogadouro;12 &;8 &;0 &;2 &;1 &;1 &;0 &;,,,
106 | 11E0410: Vila Flor;1 &;1 &;0 &;0 &;0 &;0 &;0 &;,,,
107 | 11E0411: Vimioso;6 &;6 &;0 &;0 &;0 &;0 &;0 &;,,,
108 | 11E0412: Vinhais;39 &;28 &;4 &;0 &;2 &;5 &;0 &;,,,
109 | 19: Centro;1460 &;672 &;479 &;47 &;31 &;231 &;0 &;,,,
110 | 191: Regi�o de Aveiro;290 &;97 &;73 &;2 &;13 &;105 &;0 &;,,,
111 | 1910101: �gueda;32 &;16 &;11 &;0 &;3 &;2 &;0 &;,,,
112 | 1910102: Albergaria-a-Velha;38 &;11 &;21 &;0 &;4 &;2 &;0 &;,,,
113 | 1910103: Anadia;19 &;5 &;1 &;1 &;1 &;11 &;0 &;,,,
114 | 1910105: Aveiro;44 &;18 &;0 &;0 &;0 &;26 &;0 &;,,,
115 | 1910108: Estarreja;43 &;10 &;18 &;0 &;3 &;12 &;0 &;,,,
116 | 1910110: �lhavo;23 &;5 &;0 &;0 &;0 &;18 &;0 &;,,,
117 | 1910112: Murtosa;4 &;3 &;0 &;0 &;0 &;1 &;0 &;,,,
118 | 1910114: Oliveira do Bairro;20 &;8 &;7 &;0 &;0 &;5 &;0 &;,,,
119 | 1910115: Ovar;23 &;5 &;9 &;0 &;0 &;9 &;0 &;,,,
120 | 1910117: Sever do Vouga;15 &;7 &;6 &;1 &;1 &;0 &;0 &;,,,
121 | 1910118: Vagos;29 &;9 &;0 &;0 &;1 &;19 &;0 &;,,,
122 | 192: Regi�o de Coimbra;277 &;94 &;151 &;5 &;3 &;24 &;0 &;,,,
123 | 1920601: Arganil;2 &;1 &;1 &;0 &;0 &;0 &;0 &;,,,
124 | 1920602: Cantanhede;64 &;10 &;49 &;0 &;0 &;5 &;0 &;,,,
125 | 1920603: Coimbra;33 &;20 &;12 &;0 &;0 &;1 &;0 &;,,,
126 | 1920604: Condeixa-a-Nova;6 &;5 &;1 &;0 &;0 &;0 &;0 &;,,,
127 | 1920605: Figueira da Foz;32 &;14 &;18 &;0 &;0 &;0 &;0 &;,,,
128 | 1920606: G�is;6 &;2 &;3 &;0 &;0 &;1 &;0 &;,,,
129 | 1920607: Lous�;21 &;3 &;16 &;0 &;0 &;2 &;0 &;,,,
130 | 1920111: Mealhada;18 &;1 &;12 &;0 &;0 &;5 &;0 &;,,,
131 | 1920608: Mira;11 &;5 &;3 &;0 &;0 &;3 &;0 &;,,,
132 | 1920609: Miranda do Corvo;11 &;4 &;3 &;0 &;0 &;4 &;0 &;,,,
133 | 1920610: Montemor-o-Velho;26 &;7 &;16 &;0 &;3 &;0 &;0 &;,,,
134 | 1921808: Mort�gua;6 &;3 &;0 &;3 &;0 &;0 &;0 &;,,,
135 | 1920611: Oliveira do Hospital;13 &;3 &;7 &;2 &;0 &;1 &;0 &;,,,
136 | 1920612: Pampilhosa da Serra;3 &;0 &;1 &;0 &;0 &;2 &;0 &;,,,
137 | 1920613: Penacova;5 &;4 &;1 &;0 &;0 &;0 &;0 &;,,,
138 | 1920614: Penela;8 &;3 &;5 &;0 &;0 &;0 &;0 &;,,,
139 | 1920615: Soure;7 &;4 &;3 &;0 &;0 &;0 &;0 &;,,,
140 | 1920616: T�bua;3 &;3 &;0 &;0 &;0 &;0 &;0 &;,,,
141 | 1920617: Vila Nova de Poiares;2 &;2 &;0 &;0 &;0 &;0 &;0 &;,,,
142 | 193: Regi�o de Leiria;171 &;79 &;60 &;1 &;9 &;22 &;0 &;,,,
143 | 1931002: Alvai�zere;6 &;3 &;1 &;0 &;1 &;1 &;0 &;,,,
144 | 1931003: Ansi�o;5 &;1 &;3 &;0 &;0 &;1 &;0 &;,,,
145 | 1931004: Batalha;6 &;2 &;1 &;0 &;0 &;3 &;0 &;,,,
146 | 1931007: Castanheira de P�ra;4 &;1 &;1 &;0 &;0 &;2 &;0 &;,,,
147 | 1931008: Figueir� dos Vinhos;5 &;4 &;1 &;0 &;0 &;0 &;0 &;,,,
148 | 1931009: Leiria;70 &;30 &;23 &;0 &;6 &;11 &;0 &;,,,
149 | 1931010: Marinha Grande;16 &;11 &;3 &;0 &;0 &;2 &;0 &;,,,
150 | 1931013: Pedr�g�o Grande;7 &;3 &;4 &;0 &;0 &;0 &;0 &;,,,
151 | 1931015: Pombal;35 &;13 &;19 &;1 &;1 &;1 &;0 &;,,,
152 | 1931016: Porto de M�s;17 &;11 &;4 &;0 &;1 &;1 &;0 &;,,,
153 | 194: Viseu D�o Laf�es;324 &;175 &;106 &;6 &;4 &;33 &;0 &;,,,
154 | 1940901: Aguiar da Beira;11 &;6 &;5 &;0 &;0 &;0 &;0 &;,,,
155 | 1941802: Carregal do Sal;7 &;4 &;3 &;0 &;0 &;0 &;0 &;,,,
156 | 1941803: Castro Daire;80 &;65 &;10 &;0 &;0 &;5 &;0 &;,,,
157 | 1941806: Mangualde;23 &;9 &;12 &;0 &;1 &;1 &;0 &;,,,
158 | 1941809: Nelas;17 &;5 &;11 &;0 &;0 &;1 &;0 &;,,,
159 | 1941810: Oliveira de Frades;10 &;2 &;7 &;0 &;0 &;1 &;0 &;,,,
160 | 1941811: Penalva do Castelo;12 &;2 &;10 &;0 &;0 &;0 &;0 &;,,,
161 | 1941814: Santa Comba D�o;2 &;1 &;1 &;0 &;0 &;0 &;0 &;,,,
162 | 1941816: S�o Pedro do Sul;10 &;6 &;1 &;2 &;1 &;0 &;0 &;,,,
163 | 1941817: S�t�o;18 &;7 &;10 &;0 &;1 &;0 &;0 &;,,,
164 | 1941821: Tondela;28 &;16 &;7 &;1 &;0 &;4 &;0 &;,,,
165 | 1941822: Vila Nova de Paiva;41 &;23 &;17 &;1 &;0 &;0 &;0 &;,,,
166 | 1941823: Viseu;58 &;26 &;12 &;1 &;0 &;19 &;0 &;,,,
167 | 1941824: Vouzela;7 &;3 &;0 &;1 &;1 &;2 &;0 &;,,,
168 | 195: Beira Baixa;143 &;93 &;26 &;13 &;1 &;10 &;0 &;,,,
169 | 1950502: Castelo Branco;58 &;35 &;11 &;4 &;0 &;8 &;0 &;,,,
170 | 1950505: Idanha-a-Nova;18 &;15 &;1 &;1 &;1 &;0 &;0 &;,,,
171 | 1950506: Oleiros;9 &;2 &;4 &;2 &;0 &;1 &;0 &;,,,
172 | 1950507: Penamacor;11 &;4 &;5 &;2 &;0 &;0 &;0 &;,,,
173 | 1950508: Proen�a-a-Nova;10 &;7 &;1 &;1 &;0 &;1 &;0 &;,,,
174 | 1950509: Sert�;19 &;16 &;3 &;0 &;0 &;0 &;0 &;,,,
175 | 1950510: Vila de Rei;6 &;4 &;1 &;1 &;0 &;0 &;0 &;,,,
176 | 1950511: Vila Velha de R�d�o;12 &;10 &;0 &;2 &;0 &;0 &;0 &;,,,
177 | 196: Beiras e Serra da Estrela;255 &;134 &;63 &;20 &;1 &;37 &;0 &;,,,
178 | 1960902: Almeida;8 &;6 &;1 &;1 &;0 &;0 &;0 &;,,,
179 | 1960501: Belmonte;10 &;8 &;0 &;0 &;0 &;2 &;0 &;,,,
180 | 1960903: Celorico da Beira;6 &;4 &;1 &;1 &;0 &;0 &;0 &;,,,
181 | 1960503: Covilh�;68 &;27 &;11 &;3 &;0 &;27 &;0 &;,,,
182 | 1960904: Figueira de Castelo Rodrigo;17 &;9 &;7 &;0 &;0 &;1 &;0 &;,,,
183 | 1960905: Fornos de Algodres;7 &;2 &;4 &;1 &;0 &;0 &;0 &;,,,
184 | 1960504: Fund�o;36 &;25 &;6 &;2 &;1 &;2 &;0 &;,,,
185 | 1960906: Gouveia;6 &;6 &;0 &;0 &;0 &;0 &;0 &;,,,
186 | 1960907: Guarda;23 &;9 &;10 &;2 &;0 &;2 &;0 &;,,,
187 | 1960908: Manteigas;1 &;0 &;0 &;1 &;0 &;0 &;0 &;,,,
188 | 1960909: M�da;11 &;3 &;6 &;2 &;0 &;0 &;0 &;,,,
189 | 1960910: Pinhel;11 &;5 &;3 &;3 &;0 &;0 &;0 &;,,,
190 | 1960911: Sabugal;27 &;18 &;6 &;1 &;0 &;2 &;0 &;,,,
191 | 1960912: Seia;11 &;5 &;4 &;1 &;0 &;1 &;0 &;,,,
192 | 1960913: Trancoso;13 &;7 &;4 &;2 &;0 &;0 &;0 &;,,,
193 | 1D: Oeste e Vale do Tejo;829 &;333 &;255 &;1 &;10 &;144 &;86 &;,,,
194 | 1D1: Oeste;342 &;79 &;106 &;0 &;5 &;66 &;86 &;,,,
195 | 1D11001: Alcoba�a;26 &;16 &;7 &;0 &;0 &;3 &;0 &;,,,
196 | 1D11101: Alenquer;42 &;8 &;13 &;0 &;0 &;21 &;0 &;,,,
197 | 1D11102: Arruda dos Vinhos;2 &;0 &;0 &;0 &;0 &;2 &;0 &;,,,
198 | 1D11005: Bombarral;9 &;6 &;2 &;0 &;0 &;1 &;0 &;,,,
199 | 1D11104: Cadaval;48 &;3 &;29 &;0 &;4 &;12 &;0 &;,,,
200 | 1D11006: Caldas da Rainha;58 &;26 &;30 &;0 &;0 &;2 &;0 &;,,,
201 | 1D11108: Lourinh�;30 &;1 &;0 &;0 &;0 &;5 &;24 &;,,,
202 | 1D11011: Nazar�;7 &;4 &;2 &;0 &;0 &;1 &;0 &;,,,
203 | 1D11012: �bidos;32 &;8 &;20 &;0 &;1 &;3 &;0 &;,,,
204 | 1D11014: Peniche;5 &;2 &;3 &;0 &;0 &;0 &;0 &;,,,
205 | 1D11112: Sobral de Monte Agra�o;14 &;0 &;0 &;0 &;0 &;1 &;13 &;,,,
206 | 1D11113: Torres Vedras;69 &;5 &;0 &;0 &;0 &;15 &;49 &;,,,
207 | 1D2: M�dio Tejo;240 &;113 &;99 &;1 &;4 &;23 &;0 &;,,,
208 | 1D21401: Abrantes;41 &;23 &;14 &;0 &;1 &;3 &;0 &;,,,
209 | 1D21402: Alcanena;22 &;14 &;5 &;0 &;0 &;3 &;0 &;,,,
210 | 1D21408: Const�ncia;11 &;2 &;2 &;0 &;0 &;7 &;0 &;,,,
211 | 1D21410: Entroncamento;7 &;3 &;3 &;0 &;0 &;1 &;0 &;,,,
212 | 1D21411: Ferreira do Z�zere;10 &;3 &;6 &;1 &;0 &;0 &;0 &;,,,
213 | 1D21413: Ma��o;8 &;7 &;1 &;0 &;0 &;0 &;0 &;,,,
214 | 1D21421: Our�m;70 &;22 &;44 &;0 &;3 &;1 &;0 &;,,,
215 | 1D21417: Sardoal;6 &;6 &;0 &;0 &;0 &;0 &;0 &;,,,
216 | 1D21418: Tomar;33 &;19 &;11 &;0 &;0 &;3 &;0 &;,,,
217 | 1D21419: Torres Novas;26 &;10 &;11 &;0 &;0 &;5 &;0 &;,,,
218 | 1D21420: Vila Nova da Barquinha;6 &;4 &;2 &;0 &;0 &;0 &;0 &;,,,
219 | 1D3: Lez�ria do Tejo;247 &;141 &;50 &;0 &;1 &;55 &;0 &;,,,
220 | 1D31403: Almeirim;10 &;7 &;2 &;0 &;0 &;1 &;0 &;,,,
221 | 1D31404: Alpiar�a;8 &;6 &;1 &;0 &;0 &;1 &;0 &;,,,
222 | 1D31103: Azambuja;27 &;8 &;2 &;0 &;0 &;17 &;0 &;,,,
223 | 1D31405: Benavente;31 &;25 &;2 &;0 &;0 &;4 &;0 &;,,,
224 | 1D31406: Cartaxo;18 &;11 &;3 &;0 &;1 &;3 &;0 &;,,,
225 | 1D31407: Chamusca;13 &;5 &;5 &;0 &;0 &;3 &;0 &;,,,
226 | 1D31409: Coruche;28 &;24 &;3 &;0 &;0 &;1 &;0 &;,,,
227 | 1D31412: Goleg�;3 &;1 &;0 &;0 &;0 &;2 &;0 &;,,,
228 | 1D31414: Rio Maior;24 &;6 &;12 &;0 &;0 &;6 &;0 &;,,,
229 | 1D31415: Salvaterra de Magos;26 &;16 &;3 &;0 &;0 &;7 &;0 &;,,,
230 | 1D31416: Santar�m;59 &;32 &;17 &;0 &;0 &;10 &;0 &;,,,
231 | 1A: Grande Lisboa;225 &;30 &;0 &;0 &;7 &;187 &;1 &;,,,
232 | 1A0: Grande Lisboa;225 &;30 &;0 &;0 &;7 &;187 &;1 &;,,,
233 | 1A01115: Amadora;21 &;0 &;0 &;0 &;0 &;20 &;1 &;,,,
234 | 1A01105: Cascais;24 &;2 &;0 &;0 &;3 &;19 &;0 &;,,,
235 | 1A01106: Lisboa;7 &;0 &;0 &;0 &;0 &;7 &;0 &;,,,
236 | 1A01107: Loures;14 &;4 &;0 &;0 &;1 &;9 &;0 &;,,,
237 | 1A01109: Mafra;30 &;13 &;0 &;0 &;1 &;16 &;0 &;,,,
238 | 1A01116: Odivelas;1 &;1 &;0 &;0 &;0 &;0 &;0 &;,,,
239 | 1A01110: Oeiras;18 &;0 &;0 &;0 &;0 &;18 &;0 &;,,,
240 | 1A01111: Sintra;85 &;1 &;0 &;0 &;0 &;84 &;0 &;,,,
241 | 1A01114: Vila Franca de Xira;25 &;9 &;0 &;0 &;2 &;14 &;0 &;,,,
242 | 1B: Pen�nsula de Set�bal;204 &;96 &;23 &;0 &;11 &;74 &;0 &;,,,
243 | 1B0: Pen�nsula de Set�bal;204 &;96 &;23 &;0 &;11 &;74 &;0 &;,,,
244 | 1B01502: Alcochete;13 &;13 &;0 &;0 &;0 &;0 &;0 &;,,,
245 | 1B01503: Almada;6 &;1 &;0 &;0 &;0 &;5 &;0 &;,,,
246 | 1B01504: Barreiro;16 &;5 &;5 &;0 &;0 &;6 &;0 &;,,,
247 | 1B01506: Moita;22 &;8 &;7 &;0 &;1 &;6 &;0 &;,,,
248 | 1B01507: Montijo;36 &;20 &;7 &;0 &;0 &;9 &;0 &;,,,
249 | 1B01508: Palmela;75 &;30 &;2 &;0 &;10 &;33 &;0 &;,,,
250 | 1B01510: Seixal;4 &;0 &;0 &;0 &;0 &;4 &;0 &;,,,
251 | 1B01511: Sesimbra;11 &;8 &;1 &;0 &;0 &;2 &;0 &;,,,
252 | 1B01512: Set�bal;21 &;11 &;1 &;0 &;0 &;9 &;0 &;,,,
253 | 1C: Alentejo;541 &;290 &;33 &;4 &;7 &;207 &;0 &;,,,
254 | 1C1: Alentejo Litoral;98 &;47 &;0 &;2 &;2 &;47 &;0 &;,,,
255 | 1C11501: Alc�cer do Sal;26 &;11 &;0 &;0 &;0 &;15 &;0 &;,,,
256 | 1C11505: Gr�ndola;23 &;9 &;0 &;0 &;0 &;14 &;0 &;,,,
257 | 1C10211: Odemira;23 &;13 &;0 &;2 &;0 &;8 &;0 &;,,,
258 | 1C11509: Santiago do Cac�m;16 &;11 &;0 &;0 &;1 &;4 &;0 &;,,,
259 | 1C11513: Sines;10 &;3 &;0 &;0 &;1 &;6 &;0 &;,,,
260 | 1C2: Baixo Alentejo;156 &;101 &;15 &;0 &;0 &;40 &;0 &;,,,
261 | 1C20201: Aljustrel;13 &;12 &;0 &;0 &;0 &;1 &;0 &;,,,
262 | 1C20202: Almod�var;10 &;7 &;3 &;0 &;0 &;0 &;0 &;,,,
263 | 1C20203: Alvito;6 &;2 &;0 &;0 &;0 &;4 &;0 &;,,,
264 | 1C20204: Barrancos;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
265 | 1C20205: Beja;34 &;12 &;7 &;0 &;0 &;15 &;0 &;,,,
266 | 1C20206: Castro Verde;7 &;5 &;1 &;0 &;0 &;1 &;0 &;,,,
267 | 1C20207: Cuba;5 &;4 &;0 &;0 &;0 &;1 &;0 &;,,,
268 | 1C20208: Ferreira do Alentejo;12 &;11 &;0 &;0 &;0 &;1 &;0 &;,,,
269 | 1C20209: M�rtola;4 &;0 &;1 &;0 &;0 &;3 &;0 &;,,,
270 | 1C20210: Moura;17 &;14 &;2 &;0 &;0 &;1 &;0 &;,,,
271 | 1C20212: Ourique;12 &;12 &;0 &;0 &;0 &;0 &;0 &;,,,
272 | 1C20213: Serpa;24 &;16 &;1 &;0 &;0 &;7 &;0 &;,,,
273 | 1C20214: Vidigueira;12 &;6 &;0 &;0 &;0 &;6 &;0 &;,,,
274 | 1C3: Alto Alentejo;145 &;105 &;9 &;2 &;3 &;26 &;0 &;,,,
275 | 1C31201: Alter do Ch�o;2 &;2 &;0 &;0 &;0 &;0 &;0 &;,,,
276 | 1C31202: Arronches;7 &;7 &;0 &;0 &;0 &;0 &;0 &;,,,
277 | 1C31203: Avis;8 &;6 &;0 &;0 &;0 &;2 &;0 &;,,,
278 | 1C31204: Campo Maior;21 &;17 &;1 &;0 &;0 &;3 &;0 &;,,,
279 | 1C31205: Castelo de Vide;3 &;2 &;0 &;0 &;0 &;1 &;0 &;,,,
280 | 1C31206: Crato;3 &;3 &;0 &;0 &;0 &;0 &;0 &;,,,
281 | 1C31207: Elvas;34 &;26 &;1 &;0 &;1 &;6 &;0 &;,,,
282 | 1C31208: Fronteira;4 &;4 &;0 &;0 &;0 &;0 &;0 &;,,,
283 | 1C31209: Gavi�o;5 &;2 &;3 &;0 &;0 &;0 &;0 &;,,,
284 | 1C31210: Marv�o;6 &;5 &;1 &;0 &;0 &;0 &;0 &;,,,
285 | 1C31211: Monforte;3 &;2 &;0 &;0 &;0 &;1 &;0 &;,,,
286 | 1C31212: Nisa;6 &;1 &;3 &;0 &;0 &;2 &;0 &;,,,
287 | 1C31213: Ponte de Sor;20 &;11 &;0 &;1 &;1 &;7 &;0 &;,,,
288 | 1C31214: Portalegre;10 &;8 &;0 &;1 &;1 &;0 &;0 &;,,,
289 | 1C31215: Sousel;13 &;9 &;0 &;0 &;0 &;4 &;0 &;,,,
290 | 1C4: Alentejo Central;142 &;37 &;9 &;0 &;2 &;94 &;0 &;,,,
291 | 1C40701: Alandroal;6 &;5 &;0 &;0 &;0 &;1 &;0 &;,,,
292 | 1C40702: Arraiolos;10 &;1 &;0 &;0 &;0 &;9 &;0 &;,,,
293 | 1C40703: Borba;4 &;1 &;0 &;0 &;0 &;3 &;0 &;,,,
294 | 1C40704: Estremoz;6 &;1 &;0 &;0 &;0 &;5 &;0 &;,,,
295 | 1C40705: �vora;30 &;4 &;0 &;0 &;0 &;26 &;0 &;,,,
296 | 1C40706: Montemor-o-Novo;11 &;3 &;0 &;0 &;0 &;8 &;0 &;,,,
297 | 1C40707: Mora;3 &;1 &;0 &;0 &;0 &;2 &;0 &;,,,
298 | 1C40708: Mour�o;13 &;2 &;3 &;0 &;0 &;8 &;0 &;,,,
299 | 1C40709: Portel;11 &;4 &;0 &;0 &;1 &;6 &;0 &;,,,
300 | 1C40710: Redondo;12 &;2 &;0 &;0 &;1 &;9 &;0 &;,,,
301 | 1C40711: Reguengos de Monsaraz;17 &;6 &;6 &;0 &;0 &;5 &;0 &;,,,
302 | 1C40712: Vendas Novas;9 &;3 &;0 &;0 &;0 &;6 &;0 &;,,,
303 | 1C40713: Viana do Alentejo;4 &;3 &;0 &;0 &;0 &;1 &;0 &;,,,
304 | 1C40714: Vila Vi�osa;6 &;1 &;0 &;0 &;0 &;5 &;0 &;,,,
305 | 15: Algarve;275 &;139 &;25 &;0 &;1 &;110 &;0 &;,,,
306 | 150: Algarve;275 &;139 &;25 &;0 &;1 &;110 &;0 &;,,,
307 | 1500801: Albufeira;34 &;6 &;0 &;0 &;0 &;28 &;0 &;,,,
308 | 1500802: Alcoutim;5 &;2 &;1 &;0 &;0 &;2 &;0 &;,,,
309 | 1500803: Aljezur;8 &;3 &;3 &;0 &;0 &;2 &;0 &;,,,
310 | 1500804: Castro Marim;16 &;8 &;3 &;0 &;0 &;5 &;0 &;,,,
311 | 1500805: Faro;27 &;20 &;0 &;0 &;0 &;7 &;0 &;,,,
312 | 1500806: Lagoa;6 &;3 &;1 &;0 &;0 &;2 &;0 &;,,,
313 | 1500807: Lagos;8 &;4 &;1 &;0 &;0 &;3 &;0 &;,,,
314 | 1500808: Loul�;64 &;26 &;8 &;0 &;1 &;29 &;0 &;,,,
315 | 1500809: Monchique;11 &;8 &;3 &;0 &;0 &;0 &;0 &;,,,
316 | 1500810: Olh�o;24 &;21 &;0 &;0 &;0 &;3 &;0 &;,,,
317 | 1500811: Portim�o;8 &;4 &;1 &;0 &;0 &;3 &;0 &;,,,
318 | 1500812: S�o Br�s de Alportel;4 &;2 &;0 &;0 &;0 &;2 &;0 &;,,,
319 | 1500813: Silves;31 &;21 &;2 &;0 &;0 &;8 &;0 &;,,,
320 | 1500814: Tavira;19 &;8 &;0 &;0 &;0 &;11 &;0 &;,,,
321 | 1500815: Vila do Bispo;4 &;3 &;0 &;0 &;0 &;1 &;0 &;,,,
322 | 1500816: Vila Real de Santo Ant�nio;6 &;0 &;2 &;0 &;0 &;4 &;0 &;,,,
323 | 2: Regi�o Aut�noma dos A�ores;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
324 | 20: Regi�o Aut�noma dos A�ores;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
325 | 200: Regi�o Aut�noma dos A�ores;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
326 | 2004301: Angra do Hero�smo;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
327 | 2004501: Calheta (R.A.A.);0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
328 | 2004901: Corvo;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
329 | 2004701: Horta;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
330 | 2004201: Lagoa (R.A.A.);0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
331 | 2004801: Lajes das Flores;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
332 | 2004601: Lajes do Pico;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
333 | 2004602: Madalena;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
334 | 2004202: Nordeste;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
335 | 2004203: Ponta Delgada;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
336 | 2004204: Povoa��o;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
337 | 2004205: Ribeira Grande;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
338 | 2004401: Santa Cruz da Graciosa;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
339 | 2004802: Santa Cruz das Flores;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
340 | 2004603: S�o Roque do Pico;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
341 | 2004502: Velas;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
342 | 2004302: Vila da Praia da Vit�ria;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
343 | 2004101: Vila do Porto;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
344 | 2004206: Vila Franca do Campo;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
345 | 3: Regi�o Aut�noma da Madeira;39 &;6 &;2 &;0 &;0 &;31 &;0 &;,,,
346 | 30: Regi�o Aut�noma da Madeira;39 &;6 &;2 &;0 &;0 &;31 &;0 &;,,,
347 | 300: Regi�o Aut�noma da Madeira;39 &;6 &;2 &;0 &;0 &;31 &;0 &;,,,
348 | 3003101: Calheta (R.A.M.);7 &;0 &;1 &;0 &;0 &;6 &;0 &;,,,
349 | 3003102: C�mara de Lobos;3 &;2 &;0 &;0 &;0 &;1 &;0 &;,,,
350 | 3003103: Funchal;1 &;1 &;0 &;0 &;0 &;0 &;0 &;,,,
351 | 3003104: Machico;1 &;1 &;0 &;0 &;0 &;0 &;0 &;,,,
352 | 3003105: Ponta do Sol;5 &;0 &;0 &;0 &;0 &;5 &;0 &;,,,
353 | 3003106: Porto Moniz;1 &;1 &;0 &;0 &;0 &;0 &;0 &;,,,
354 | 3003107: Ribeira Brava;20 &;0 &;1 &;0 &;0 &;19 &;0 &;,,,
355 | 3003108: Santa Cruz;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
356 | 3003109: Santana;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
357 | 3003110: S�o Vicente;1 &;1 &;0 &;0 &;0 &;0 &;0 &;,,,
358 | 3003201: Porto Santo;0 &;0 &;0 &;0 &;0 &;0 &;0 &;,,,
359 | ,,,
360 | Rural fires (No.) by Geographic localization (NUTS - 2024) and Cause of fire - Annual - ICNF, Forestry statistics,,
361 | ,,,
362 | ,,,
363 | This data last updated:october 16,2024,,
364 | ,,,
365 | ,,,
366 | Table Metadata,,,
367 | ,,,
368 | Rural fires (No.),,,
369 | Name;Rural fires (No.) by Geographic localization (NUTS - 2024) and Cause of fire - Annual,,,
370 | Regularity;Annual,,,
371 | Source;ICNF, Forestry statistics,,
372 | First available period;2001,,,
373 | Last available period;2023,,,
374 | Dimensions,,,
375 | Dimension 1;Data reference period,,,
376 | Dimension 2;Geographic localization (NUTS - 2024),,,
377 | Dimension 3;Cause of fire,,,
378 | Concepts,,,
379 | REFERENCE PERIOD;Period to which the information refers and which may be a specific day or a time interval (month, fiscal year, calendar year, among others).
380 | RURAL FIRE;Outbreak or progression of fire, in an unplanned or uncontrolled manner, in rural territory, requiring suppression actions.
381 | Definition;,,,
382 | Formule;,,,
383 | Measure unit (symbol);Number (No.),,,
384 | Power of 10;0,,,
385 | Last update date;16-Out-2024,,,
386 |
--------------------------------------------------------------------------------