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 2 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
159 changes: 159 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
# 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_

### Useful virtual environment commands
<ul>
<li>To create an environment

_mkvirtualenv env-name_
</li>
<li>
To change working environment

_workon env-name_
</li>
<li> Remove a virtual environment

_rmvirtualenv env-name_
</li>
<li> Deactivate the environment (Go back to use system python)

_deactivate_

</li>


</ul>

# Usage
<ul>

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

![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 2014/06

![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 2014/06

![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 2014/06

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

</ul>
96 changes: 96 additions & 0 deletions WeatherData.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import pandas as pd


class WeatherData:
"""
This class holds all the data of the weather.
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
"""

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"
return

Choose a reason for hiding this comment

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

I don't think we need return here


def add_month_data(self, month: int, year: int,
month_data: pd.DataFrame):
"""
add_month_data(self, month, year, month_data)
self: object in which you want to add data
month: integer range(1-12)
year: integer representing year
month_data: pandas data frame having data of all days

Stores month weather information in data structure

Choose a reason for hiding this comment

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

This is not the correct format for a docstring. Please check pep8

"""

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):
"""
Pass alias to get column name
Valid aliases are
max_temperature
min_temperature
max_humidity
min_humidity
mean_humidity

Returns column name for other function from alias

Choose a reason for hiding this comment

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

check docstring format from pep8

"""

string = string.lower()
if string == "max_temperature":
return self.__max_temp_c
elif string == "min_temperature":
return self.__min_temp_c
elif string == "max_humidity":
return self.__max_humidity
elif string == "min_humidity":
return self.__min_humidity
elif string == "mean_humidity":
return self.__mean_humidity
return None

def get_column_data(self, column_name, month: int, year: int):
"""
get_column_data(column_name, month, year)

Get column_name from method get_column_came_from_alias
month: integer range(1-12)
year: integer
"""

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].tolist()
except Exception:
print("Data not found")
return []
Binary file added Weatherman.pdf
Binary file not shown.
111 changes: 111 additions & 0 deletions common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
def get_month_year_from_string(string):
"""
return month and year from combined string

month and year should be numbers and separated with /
Examples:
input string: 12/2006
output: 12, 2006
input string: jan/2006
output: None, None

Choose a reason for hiding this comment

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

check docstring format.

"""

month, year = string.split('/')
try:
month = int(month)
year = int(year)
except Exception:
print("Invalid input")

Choose a reason for hiding this comment

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

add more information to this print statement, include reason why the input is invalid.

return None, None
return month, year


def get_month_number_from_string(string):
"""
Converts 3 characters month name to string
Example
input: "jan"
output: 1
input: "feb"
output: 2
input: "January":
output: None

Choose a reason for hiding this comment

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

check docstring format.

"""

string = str(string).lower()
if string == "jan":
return 1
elif string == "feb":
return 2
elif string == "mar":
return 3
elif string == "apr":
return 4
elif string == "may":
return 5
elif string == "jun":
return 6
elif string == "jul":
return 7
elif string == "aug":
return 8
elif string == "sep":
return 9
elif string == "oct":
return 10
elif string == "nov":
return 11
elif string == "dec":
return 12

Choose a reason for hiding this comment

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

instead of if/else statements, you can have a dict containing month name as key and month number as month number. would make code more readable.

Choose a reason for hiding this comment

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

Also, in case of a lot of if/else statements, please use switch case instead.

return None


def get_month_string_from_number(number: int):

Choose a reason for hiding this comment

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

change number to a better variable name!

"""
converts integer number to 3 character month name
Examples
input: 1
output: "Jan"
input: 2
output: "Feb"
input: 100
output: ""

Choose a reason for hiding this comment

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

check docstring format.

"""

if number == 1:
return "Jan"
elif number == 2:
return "Feb"
elif number == 3:
return "Mar"
elif number == 4:
return "Apr"
elif number == 5:
return "May"
elif number == 6:
return "Jun"
elif number == 7:
return "Jul"
elif number == 8:
return "Aug"
elif number == 9:
return "Sep"
elif number == 10:

Choose a reason for hiding this comment

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

have a dict mapping here instead of if/else statements.

return "Oct"
elif number == 11:
return "Nov"
elif number == 12:
return "Dec"
return ""


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

Choose a reason for hiding this comment

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

docstring

"""
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)
Loading