Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First code to repo #1

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/images/
/__pycache__/
/weatherfiles/
/.git/
/Weatherman.pdf
140 changes: 140 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Weather Man
weatherfiles.zip contains weather data files for Murree in multiple formats. Write an application that generates the following reports. The user can specify more than one report at the same time.
The program should have the following components:
* It should extract the files into a destination folder and execute further tasks as described below.
* A data structure for holding each weather reading.
* A parser for parsing the files and populating the reading data structure with correct data types.
* A data structure for holding the calculations results.
* A module for computing the calculations given the readings.
* A report generator for creating the reports given the computation results.
* PEP-8 conventions should be followed in the code.
* Your code should be concise and self-explanatory and understandable.

## 1. For a given year display the highest temperature, the lowest temperature and humidity.
#### Command to execute:

_weatherman.py /path/to/files-dir -e 2002_

#### Example Output:

Highest: 45C on June 23

Lowest: 01C on December 22

Humidity: 95% on August 14

## 2. For a given month display the average highest temperature, average lowest temperature, average mean humidity.
#### Command to execute:

_weatherman.py /path/to/files-dir -a 2005/6_

#### Example Output:

Highest Average: 39C

Lowest Average: 18C

Average Mean Humidity: 71%

## 3. For a given month draw horizontal bar charts on the console for the highest and lowest temperature on each day. Highest in red and lowest in blue.
#### Command to execute:

_weatherman.py /path/to/files-dir -c 2011/03_


#### Example Output:

March 2011

01 +++++++++++++++++++++++++ 25C

01 +++++++++++ 11C

02 ++++++++++++++++++++++ 22C

02 ++++++++ 08C

## 4. Multiple Reports should be generated if multiple available options are passed to application
#### Command to execute:
_weatherman.py /path/to/files-dir -c 2011/03 -a 2011/3 -e 2011_

## 5. BONUS TASK. For a given month draw one horizontal bar chart on the console for the highest and lowest temperature on each day. Highest in red and lowest in blue.
#### Command to execute:
_weatherman.py /path/to/files-dir -b 2011/3_
#### Example output:
March 2011

01 ++++++++++++++++++++++++++++++++++++ 11C - 25C

02 ++++++++++++++++++++++++++++++ 08C - 22C


# Virtual Environment
### Install virtualenv and virtualenvwrapper
_pip install virtualenv_

_pip install virtualenvwrapper_
### Add variables to path (Recommended)

export WORKON_HOME=$HOME/.virtualenv

export PROJECT_HOME=$HOME/projects
### Find virtualenvwrapper and run it
_which virtualenvwrapper.sh_

_The command will output a path similar to this "/usr/local/bin/virtualenvwrapper.sh"_

Enter the following command to run this file

_source /usr/local/bin/virtualenvwrapper.sh_

### Reload startup file ".bashrc"
_source ~/.bashrc_

### Create a new virtual environment
_mkvirtualenv env-name_

Comment on lines +73 to +96

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use venv for virtual envirnoment setup. It is much easier to use
https://docs.python.org/3/library/venv.html

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we dont need all the commands related to the virutal envirnoment here, we are only cocerned with our usage. Simplify this to having steps like

  • command to install virtualenv,
  • command to activate virtualenv,
  • command to install requirements of project from requirement.txt

This environment will be loaded automatically after successful creation, if it is not loaded use

_workon env-name_

### Installing requirements
Run the following command in the environment to install the requirements

_pip install -r requirements.txt_

# Usage
<ul>

### <li>For yearly report, execute
python3 weatherman.py path/to/all/files -e year
#### Example
python3 weatherman.py weatherfiles/ -e 2015

![Yearly report output](images/yearly_report.png "Yearly report output")</li>


### <li>For monthly report, execute
python3 weatherman.py path/to/all/files -a year/month
#### Example
python3 weatherman.py weatherfiles/ -a 2015/02

![Monthly report output](images/monthly_report.png "Monthly report output")</li>


### <li>For monthly graph (two lines), execute
python3 weatherman.py path/to/all/files -c year/month
#### Example
python3 weatherman.py weatherfiles/ -c 2015/02

![Monthly graph (Single line) output](images/monthly_graph.png "Monthly graph (single line) output")</li>


### <li>For monthly graph (single line), execute
python3 weatherman.py path/to/all/files -b year/month
#### Example
python3 weatherman.py weatherfiles/ -b 2015/02

![Monthly graph (Two lines) output](images/monthly_graph_bonus.png "Monthly graph (two lines) output")</li>

</ul>
115 changes: 115 additions & 0 deletions WeatherData.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
class WeatherData:
"""This class holds all the data of the weather.

Methods:
To add data in the structure, use method add_month_data
To get data use "get_column_data" method with month and year
To get the column name use method get_column_name_from_alias.
Valid aliases are
max_temperature
min_temperature
max_humidity
min_humidity
mean_humidity

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add an example of an object of this class, and what is the structure of the data it holds!


Data Structure:
It contains a single dict whose all values are also dict
complete_data (data)
year 1 (dict)
month 1 (dict)
Weather Attribute 1 (dict)
weather_attribute_of_month (list)
Weather Attribute 2 (dict)
...
month 2 (dict)
...
year 2 (dict)
...
To get an attribute for a month, we would use
complete_data[year][month][weather_attribute]
It will return a list
"""

def __init__(self):
self.__complete_data = {}
# column names mapping from text to variables
self.__max_temp_c = "Max TemperatureC"
self.__min_temp_c = "Min TemperatureC"
self.__max_humidity = "Max Humidity"
self.__min_humidity = "Min Humidity"
self.__mean_humidity = "Mean Humidity"

def add_month_data(self, month: int, year: int, month_data):
"""Stores month weather information in data structure

Arguments:
month: int:
integer range(1-12)
year: int:
integer representing year
month_data: dict:
dictionary having data of all days
"""

if not (0 < month < 13):
print("Invalid month ", month, ". Data not added")
return
month = str(month)
year = str(year)
if year not in self.__complete_data:
self.__complete_data[year] = {}
if month not in self.__complete_data[year]:
self.__complete_data[year][month] = {}
self.__complete_data[year][month] = month_data
return

def get_column_name_from_alias(self, string):
"""Returns column name from alias

Arguments:
string: str:
Pass alias to get column name
Valid aliases are
max_temperature
min_temperature
max_humidity
min_humidity
mean_humidity
"""

string = string.lower()
alias_name_mapping_dictionary = {
"max_temperature": self.__max_temp_c,
"min_temperature": self.__min_temp_c,
"max_humidity": self.__max_humidity,
"min_humidity": self.__min_humidity,
"mean_humidity": self.__mean_humidity
}
return alias_name_mapping_dictionary.get(string, None)

def get_column_data(self, column_name, month: int, year: int):
"""Returns column data from column name, month and year

Arguments:
column_name: str:
column name whose data is required
month: int:
month in integer range(1-12)
year: int:
integer representing year

Returns:
column_data: list:
list that contains the whole month data
"""

if not (0 < month < 13):
print("Invalid month", month)
return []
month = str(month)
year = str(year)
try:
return self.__complete_data[year][month][column_name]
except Exception:
print("Data not found for " + year + "/" + month)
return []
86 changes: 86 additions & 0 deletions common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from constants import MONTH_NUMBER_STRING_MAPPING


def get_month_year_from_string(month_year_string):
"""Returns month and year from combined string
month and year should be numbers and separated with "/"

Arguments:
month_year_string: str
String containing month year in format mm/yyyy

Returns:
month: int, year: int
Month and year separated in integer
"""

try:
month, year = month_year_string.split('/')
month = int(month)
year = int(year)
except ValueError:
print("Invalid month/year. Input must be of format yyyy/mm")
return None, None
return month, year


def get_month_number_from_string(month_string):
"""
Converts 3 characters month name to month number

Arguments:
month_string: str
String containing month

Returns:
month: int
Returns month as number from string
"""

month_string = str(month_string).lower()
month_key_list = list(MONTH_NUMBER_STRING_MAPPING.keys())
month_values_list = list(MONTH_NUMBER_STRING_MAPPING.values())
month_values_list = [value.lower() for value in month_values_list]

try:
index_to_retrieve = month_values_list.index(month_string)
except ValueError:
return None
return month_key_list[index_to_retrieve]


def get_month_string_from_number(month_number: int):
"""Converts integer number to 3 character month name

Argument:
number: int

Returns:
string: str:
String of length 3 that represents month
"""

return MONTH_NUMBER_STRING_MAPPING.get(month_number, "")


def get_column_data_from_alias(weather_data, alias, month, year):
"""Returns column data from alias

Arguments:
weather_data: dict:
Contains complete weather data
alias: str:
Alias of column
month: int:
Month whose data is required
year: int:
Year whose data is required

Returns:
list_: list:
Complete column data from alias
"""
attrib_name = weather_data.get_column_name_from_alias(alias)
if attrib_name is None:
return []
return weather_data.get_column_data(attrib_name, month, year)
40 changes: 40 additions & 0 deletions constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
TEXT_STYLE_NORMAL = 0
TEXT_STYLE_BOLD = 1
TEXT_STYLE_LIGHT = 2
TEXT_STYLE_ITALICIZED = 3
TEXT_STYLE_UNDERLINED = 4
TEXT_STYLE_BLINK = 5

TEXT_COLOR_BLACK = 30
TEXT_COLOR_RED = 31
TEXT_COLOR_GREEN = 32
TEXT_COLOR_YELLOW = 33
TEXT_COLOR_BLUE = 34
TEXT_COLOR_PURPLE = 35
TEXT_COLOR_CYAN = 36
TEXT_COLOR_WHITE = 37

BACKGROUND_COLOR_BLACK = 40
BACKGROUND_COLOR_RED = 41
BACKGROUND_COLOR_GREEN = 42
BACKGROUND_COLOR_YELLOW = 43
BACKGROUND_COLOR_BLUE = 44
BACKGROUND_COLOR_PURPLE = 45
BACKGROUND_COLOR_CYAN = 46
BACKGROUND_COLOR_WHITE = 47


MONTH_NUMBER_STRING_MAPPING = {
1: "Jan",
2: "Feb",
3: "Mar",
4: "Apr",
5: "May",
6: "Jun",
7: "Jul",
8: "Aug",
9: "Sep",
10: "Oct",
11: "Nov",
12: "Dec"
}
Loading