Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit f53b9a93 authored by Loic Huder's avatar Loic Huder
Browse files

Added DIY HumidWeatherStation + correction

parent 12243978
......@@ -12,7 +12,7 @@
"\n",
"**A training to acquire strong basis in Python to use it efficiently**\n",
"\n",
"Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTERRE), Christophe Picard (LJK)\n",
"Pierre Augier (LEGI), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre), Christophe Picard (LJK), Loïc Huder (ISTerre)\n",
"\n",
"# Object-oriented programming: inheritance\n",
"\n",
......@@ -75,10 +75,8 @@
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": true
},
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"class AdultBee(object):\n",
......@@ -132,7 +130,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
......@@ -159,7 +157,7 @@
},
{
"cell_type": "code",
"execution_count": 19,
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
......@@ -224,7 +222,7 @@
},
{
"cell_type": "code",
"execution_count": 20,
"execution_count": 4,
"metadata": {},
"outputs": [
{
......@@ -245,7 +243,7 @@
},
{
"cell_type": "code",
"execution_count": 22,
"execution_count": 5,
"metadata": {},
"outputs": [
{
......@@ -287,7 +285,7 @@
},
{
"cell_type": "code",
"execution_count": 16,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
......@@ -333,7 +331,7 @@
},
{
"cell_type": "code",
"execution_count": 15,
"execution_count": 7,
"metadata": {},
"outputs": [
{
......@@ -359,7 +357,7 @@
},
{
"cell_type": "code",
"execution_count": 23,
"execution_count": 8,
"metadata": {},
"outputs": [
{
......@@ -468,7 +466,7 @@
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 12,
"metadata": {},
"outputs": [
{
......@@ -480,6 +478,10 @@
}
],
"source": [
"class Person(object):\n",
" def __init__(self):\n",
" pass\n",
"\n",
"class Student(Person):\n",
" role = 'student'\n",
" @classmethod\n",
......@@ -505,10 +507,8 @@
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": true
},
"execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
"class IdPerson(Person):\n",
......@@ -525,7 +525,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 14,
"metadata": {},
"outputs": [
{
......@@ -545,6 +545,188 @@
"IdPerson.show_nb_person()"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Do it yourself\n",
"At the end of the last presentation, we asked the following question about our weather stations measuring wind and temperature:\n",
"> What if we now have a weather station that also measure humidity ? Do we have to rewrite everything ?\n",
"\n",
"Give your own answer by doing the following tasks:\n",
"- Write a class `HumidWeatherStation` inheriting `WeatherStation` (code reproduced below) to implement a new attribute to store the humidity measurements.\n",
"- Write a function `humidity_at_max_temp` that returns the value of the humidity at the maximal temperature. Use the fact that `HumidWeatherStation` inherits from `WeatherStation` and therefore can use the method `arg_max_temp` previously implemented !\n",
"- *Advanced*: Overloadg the methods of `WeatherStation` to take humidity into account when computing percieved temperatures `Tp`. For simplicity, we will assume that `Tp = Tw + 5*humidity` with `Tw` the temperature computed with the wind chill effect.\n",
"- *Advanced*: Write tests for this new class"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
"# Code to use for the DIY\n",
"class WeatherStation(object):\n",
" \"\"\" A weather station that holds wind and temperature \"\"\"\n",
"\n",
" def __init__(self, wind, temperature):\n",
" \"\"\" initialize the weather station. \n",
" Precondition: wind and temperature must have the same length\n",
" :param wind: any ordered iterable\n",
" :param temperature: any ordered iterable\"\"\"\n",
" self.wind = [x for x in wind]\n",
" self.temp = [x for x in temperature]\n",
" if len(self.wind) != len(self.temp):\n",
" raise ValueError(\n",
" \"wind and temperature should have the same size\"\n",
" )\n",
"\n",
" def perceived_temp(self, index):\n",
" \"\"\" computes the perceived temp according to \n",
" https://en.wikipedia.org/wiki/Wind_chill\n",
" i.e. The standard Wind Chill formula for Environment Canada is: \n",
" apparent = 13.12 + 0.6215*air_temp - 11.37*wind_speed^0.16 + 0.3965*air_temp*wind_speed^0.16\n",
" \n",
" :param index: the index for which the computation must be made\n",
" :return: the perceived temperature\"\"\"\n",
" air_temp = self.temp[index]\n",
" wind_speed = self.wind[index]\n",
" # Perceived temperature does not have a sense without wind...\n",
" if wind_speed == 0:\n",
" apparent_temp = air_temp\n",
" else:\n",
" apparent_temp = 13.12 + 0.6215*air_temp \\\n",
" - 11.37*wind_speed**0.16 \\\n",
" + 0.3965*air_temp*wind_speed**0.16\n",
" # Let's round to the integer to avoid trailing decimals...\n",
" return round(apparent_temp,0)\n",
" \n",
" def perceived_temperatures(self):\n",
" \"\"\" Returns an array of percieved temp computed from the temperatures and wind speed data \"\"\"\n",
" apparent_temps = []\n",
" for index in range(len(self.wind)):\n",
" # Reusing the method perceived_temp defined above\n",
" apparent_temperature = self.perceived_temp(index)\n",
" apparent_temps.append(apparent_temperature)\n",
" return apparent_temps\n",
"\n",
" def max_temp(self, perceived=False):\n",
" \"\"\" returns the maximum temperature record in the station\"\"\"\n",
" if perceived:\n",
" apparent_temp = self.perceived_temperatures()\n",
" return max(apparent_temp)\n",
" else:\n",
" return max(self.temp)\n",
"\n",
" def arg_max_temp(self, perceived=False):\n",
" \"\"\" returns the index of (one of the) maximum temperature record in the station\"\"\"\n",
" if perceived:\n",
" temp_array_to_search = self.perceived_temperatures()\n",
" else:\n",
" temp_array_to_search = self.temp\n",
" return temp_array_to_search.index(self.max_temp(perceived))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### A Solution"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.5\n",
"35\n",
"[33.9, 39.15, 37.05, 37.9, 41.5, 41.6]\n",
"41.6\n"
]
}
],
"source": [
"class HumidWeatherStation(WeatherStation):\n",
" \"\"\" A weather station that holds wind, temperature and humidity. Inherits from WeatherStation \"\"\"\n",
" \n",
" def __init__(self, wind, temperature, humidity):\n",
" \"\"\" initialize the weather station. \n",
" Precondition: wind, temperature and humidity must have the same length\n",
" :param wind: any ordered iterable\n",
" :param temperature: any ordered iterable\n",
" :param humidity: any ordered iterable\"\"\"\n",
" # Delegate the initialisation of wind and temperature to the mother class constructor\n",
" super(HumidWeatherStation, self).__init__(wind, temperature)\n",
" # Or: super().init(wind, temperature)\n",
" \n",
" # Add humidity treatement\n",
" self.humidity = [x for x in humidity]\n",
" if len(self.humidity) != len(self.temp):\n",
" raise ValueError(\"humidity and temperature should have the same size\")\n",
" # If humidity and temp have the same size, humidity and wind do as well\n",
" # as len(temp) == len(wind) is enforced from the mother class constructor\n",
" \n",
" def humidity_at_max_temp(self):\n",
" \"\"\" Returns the value of humidity at the maximal temperature \n",
" \"\"\"\n",
" index_max_temp = self.arg_max_temp()\n",
" return self.humidity[index_max_temp]\n",
" \n",
" def perceived_temp(self, index):\n",
" \"\"\" Compute the perceived temperature according to wind_speed (wind-chill) and humidity \n",
" \n",
" :param index: the index for which the computation must be made\n",
" :return: the perceived temperature\"\"\"\n",
" # Compute the wind-chilled temp from WeatherStation method\n",
" wind_chilled_temp = super().perceived_temp(index)\n",
" apparent_temp = wind_chilled_temp + 5*self.humidity[index]\n",
" return round(apparent_temp, 2)\n",
" \n",
" def perceived_temps(self):\n",
" \"\"\" Returns an array of percieved temp computed from the temperatures, wind speed and humidity data \"\"\"\n",
" apparent_temps = []\n",
" for index in range(len(self.temp)):\n",
" # This time, we use the perceived_temp method of HumidWeatherStation\n",
" apparent_temperature = self.perceived_temp(index)\n",
" apparent_temps.append(apparent_temperature)\n",
" return apparent_temps\n",
" \n",
"singapore = HumidWeatherStation(wind=[11, 23, 23, 19, 18, 18], \n",
" temperature = [28, 33, 31, 32, 35, 34],\n",
" humidity = [0.78, 0.63, 0.61, 0.58, 0.5, 0.72])\n",
"print(singapore.humidity_at_max_temp()) #0.5 expected\n",
"print(singapore.max_temp()) #35 expected\n",
"# As we overloaded perceived_temp, the rest of the class features work with the new behaviour\n",
"print(singapore.perceived_temps())\n",
"print(singapore.max_temp(perceived=True))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this case, we used inheritance to create the new object (`HumidWeatherStation`) to:\n",
"\n",
"- Add new features (`humidity_at_max_temp`) to an existing object without rewritting the common features\n",
"- Define new behaviours for features already present (`perceived_temp`) that integrate well with the structure in place\n",
"\n",
"For such needs, think about inheritance."
]
},
{
"cell_type": "markdown",
"metadata": {
......@@ -566,7 +748,7 @@
},
{
"cell_type": "code",
"execution_count": 13,
"execution_count": 17,
"metadata": {
"slideshow": {
"slide_type": "subslide"
......@@ -649,7 +831,7 @@
}
],
"metadata": {
"celltoolbar": "Slideshow",
"celltoolbar": "Diaporama",
"kernelspec": {
"display_name": "Python 3",
"language": "python",
......@@ -665,7 +847,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.6"
"version": "3.6.7"
}
},
"nbformat": 4,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment