Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
840b109
(fix) Fix minor typos in Readme
andrewzey Aug 18, 2016
c4e2fa7
Merge pull request #2 from andrewzey/fix/typos
ericdouglas Aug 18, 2016
fd3f168
Add links in Additional Resources section
ericdouglas Aug 18, 2016
4f12bdb
Add contributors link
ericdouglas Aug 18, 2016
4b8f62e
Add essential/optional path
ericdouglas Aug 28, 2016
288f705
Add optional path header
ericdouglas Aug 28, 2016
13b2b83
Issue #4 adding optional path >> typescript
brauliodiez Aug 28, 2016
f02b5ce
Merge pull request #5 from Lemoncode/Typescript
ericdouglas Aug 28, 2016
1a39f60
Add typescript link on TOC
ericdouglas Aug 28, 2016
190ea38
Fixed typo
williamgranli Sep 12, 2016
4f48bf7
Merge pull request #7 from williamgranli/master
ericdouglas Sep 12, 2016
f5b7de3
Add new logo
ericdouglas Sep 27, 2016
600023a
Rename logo file
ericdouglas Sep 27, 2016
87f3f6f
Fix logo link
ericdouglas Sep 27, 2016
7b2b7b2
Remove some resources
ericdouglas Oct 6, 2016
f7d2762
Move Bundlers section
ericdouglas Oct 7, 2016
7f8b6f0
Fix TOC
ericdouglas Oct 7, 2016
5f38029
Fix TOC
ericdouglas Oct 7, 2016
0399da1
update react-router link
yanisurbis Oct 21, 2016
5bd211d
Merge pull request #10 from yanisurbis/patch-1
ericdouglas Oct 21, 2016
91f0dc2
Refactor of React, ES6 and Static Type section
ericdouglas Oct 24, 2016
d8bf132
Add basic tutorial to React section
ericdouglas Oct 25, 2016
95aa6af
Add labels in Webpack section
ericdouglas Oct 25, 2016
c0fd161
Fix React Router text
ericdouglas Oct 25, 2016
9d87f2f
Add Immutable section
ericdouglas Nov 10, 2016
a36ae65
Update Webpack and Immutable.js sections
ericdouglas Nov 12, 2016
4bddffe
Move Bundlers section
ericdouglas Nov 12, 2016
d181d34
Add book The Road to learn React in React section
ericdouglas Dec 24, 2016
df40e50
Add Plotly Academy link in "Build Stuff" section
ericdouglas Dec 30, 2016
e674082
feat: Add script to generate 7-day Kano weather report
google-labs-jules[bot] May 23, 2025
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
153 changes: 55 additions & 98 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,55 @@
![React Roadmap](img/logo.png)

<p align="center">
A curated list of <strong>free resources</strong> to master React Development
</p>

## Table Of Contents
- [Motivation](#motivation)
- [Roadmap](#roadmap)
- [Why React?](#why-react)
- [React](#react)
- [Bundlers](#bundlers)
- [ES2015+](#es2015)
- [Routing](#routing)
- [Redux](#redux)
- [Build Stuff](#build-stuff)
- [How To Use This Guide](#how-to-use-this-guide)
- [How To Colaborate](#how-to-colaborate)
- [Team](#team)
- [Inspiration And Additional Resources](#inspiration-and-additional-resources)

## Motivation
This project aims to collect the **best free resources** for those that want to learn how to build applications with React and also understand the [concepts](https://github.com/reactjs/react-basic) that come with its adoption like Functional Programming, Composition, Unidirectional Data Flow and many others.

## Roadmap
### Why React?
1. [JS Apps at Facebook](https://www.youtube.com/watch?v=GW0rj4sNH2w)
1. [Why did we build React?](https://facebook.github.io/react/blog/2013/06/05/why-react.html)
1. [React: Rethinking best practices](https://www.youtube.com/watch?v=x7cQ3mrcKaY)

### [React](https://facebook.github.io/react/)
1. [React Fundamentals](http://courses.reactjsprogram.com/courses/reactjsfundamentals)
1. [Getting Started](https://facebook.github.io/react/docs/getting-started.html)
1. [Getting Started with create-react-app](https://daveceddia.com/create-react-app-official-project-generator/)
1. [React Docs Tutorial](https://facebook.github.io/react/docs/tutorial.html)
1. [Thinking in React](https://facebook.github.io/react/docs/thinking-in-react.html)
1. [The React Quick Start Guide](http://www.jackcallister.com/2015/01/05/the-react-quick-start-guide.html) ([ES6 version](http://www.jackcallister.com/2015/08/30/the-react-quick-start-guide-es6-edition.html))
1. [Removing User Interface Complexity, or Why React is Awesome](http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome)
1. [Learn Raw React — no JSX, no Flux, no ES6, no Webpack…](http://jamesknelson.com/learn-raw-react-no-jsx-flux-es6-webpack/)
1. [Learn Raw React: Ridiculously Simple Forms](http://jamesknelson.com/learn-raw-react-ridiculously-simple-forms/)
1. [Building a Router with Raw React](http://jamesknelson.com/routing-with-raw-react/)
1. [React's Official Guides](https://facebook.github.io/react/docs/why-react.html) & [Tips](https://facebook.github.io/react/tips/introduction.html)
1. [react-devtools](https://github.com/facebook/react-devtools)
1. [React Cheat Sheet](http://reactcheatsheet.com/)

### Bundlers
#### [Webpack](http://webpack.github.io/)
1. [Webpack your bags](https://blog.madewithlove.be/post/webpack-your-bags/)
1. [Webpack — The Confusing Parts](https://medium.com/@rajaraodv/webpack-the-confusing-parts-58712f8fcad9#.drs7xvnbi)
1. [SurviveJS - Webpack](http://survivejs.com/webpack/introduction/)

### ES2015+
1. [Learn ES6 (ECMAScript 2015)](https://egghead.io/courses/learn-es6-ecmascript-2015)
1. [Setting up ES6](https://leanpub.com/setting-up-es6/read)
1. [Overview of ECMAScript 6 features](https://github.com/lukehoban/es6features)
1. [Exploring ES6](http://exploringjs.com/es6/)
1. [Exploring ES2016 and ES2017](https://leanpub.com/exploring-es2016-es2017/read)

### Routing
1. [React Router Tutorial](https://github.com/reactjs/react-router-tutorial)

### Redux
1. [Getting Started with Redux](https://egghead.io/courses/getting-started-with-redux)
1. [Building React Applications with Idiomatic Redux](https://egghead.io/courses/building-react-applications-with-idiomatic-redux)

### Build Stuff
1. [Several project ideas](https://react.rocks/)
1. [React - TodoMVC](http://todomvc.com/examples/react/#/)
1. [Bootstrapping a React project](https://auth0.com/blog/bootstrapping-a-react-project/)
1. [The SoundCloud Client in React + Redux](http://www.robinwieruch.de/the-soundcloud-client-in-react-redux/)
1. A Primer on the React Ecosystem: [1](http://patternhatch.com/2016/07/06/a-primer-on-the-react-ecosystem-part-1-of-3/), [2](http://patternhatch.com/2016/08/02/a-primer-on-the-react-ecosystem-part-2-of-3/) and 3.
1. [Building a React/Redux App with JSON Web Token (JWT) Authentication](http://blog.slatepeak.com/build-a-react-redux-app-with-json-web-token-jwt-authentication/)

## How To Use This Guide
Use a **linear approach** to complete this guide. That means you should start with the first resource and pass to the next one after you finish the previous and after make a practical project to internalize what you have learned.

The React's ecosystem is overwhelming for beginners. Ensure to learn each new tool **isolatedly**.

Said this, our first course in the React section covers all the React ecosystem. Face this as a general introduction to each topic that will be studied deeply in the following sections.

In the sections about React, Webpack, and ES2015+, the initial resources are more superficial and the last ones are going deeper in the respective topic. You can opt to learn the basics first and return to them later, but don't skip them without have a basic knowledge of the matter.

## How To Colaborate
To suggest new sections or new resources, open an issue explaining why we should add/remove some resource/section. After at least 5 people approve (:+1:) your indication, you will be invited to create the pull request.

The reason to keep this way of collaboration is to ensure that our list of resources will be really concise, bringing only the best resources for those that want to master the topics listed here.

## Team
- **Rodmap creator**: [Eric Douglas](https://github.com/ericdouglas)
- **Rodmap maintainer**: [Eric Douglas](https://github.com/ericdouglas)

## Inspiration And Additional Resources
1. [You’re Missing the Point of React](https://medium.com/@dan_abramov/youre-missing-the-point-of-react-a20e34a51e1a#.qgt6xupid)
1. [react-makes-you-sad](https://github.com/gaearon/react-makes-you-sad)
1. [react-howto](https://github.com/petehunt/react-howto)
1. [Your Timeline for Learning React](https://daveceddia.com/timeline-for-learning-react/)
1. [5 Steps for Learning React Application Development](http://developer.telerik.com/featured/5-steps-for-learning-react-application-development/)
1. [Path to Learning React](https://www.reddit.com/r/reactjs/comments/4r95aj/path_to_learning_react/)
# Kano Weekly Weather Report

This script fetches and displays a 7-day weather forecast for Kano, Nigeria, using the OpenWeatherMap API.

## Prerequisites

- Python 3
- The `requests` library. You can install it using pip:
```bash
pip install requests
```
- An API key from OpenWeatherMap. You can obtain one by signing up on their website (https://openweathermap.org/price). The free tier for the "One Call API 3.0" is usually sufficient.

## How to Run

1. **Save the script**: Make sure you have the `kano_weather_report.py` script.
2. **Set your API Key**: You need to provide your OpenWeatherMap API key when running the script.
3. **Execute the script**: Run the script from your terminal using the following command:

```bash
python kano_weather_report.py YOUR_API_KEY
```
Replace `YOUR_API_KEY` with your actual OpenWeatherMap API key.

## Example Output Format

The script will print the weather report to the console in the following format:

```
Kano Weekly Weather Report:
---------------------------
Date: YYYY-MM-DD
Temperature: Min: XX°C, Max: YY°C
Humidity: ZZ%
Weather: Condition (Description)
Wind Speed: WW m/s
---
Date: YYYY-MM-DD
Temperature: Min: XX°C, Max: YY°C
Humidity: ZZ%
Weather: Condition (Description)
Wind Speed: WW m/s
---
... (for 7 days)
```

## Error Handling

The script includes error handling for:
- Invalid API key
- Network issues
- Problems fetching or parsing data from the API
- Missing or unexpected data in the API response

If an error occurs, an informative message will be printed to the console.
57 changes: 57 additions & 0 deletions get_kano_coordinates.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import argparse
import json
import requests

def get_kano_coordinates(api_key):
"""
Fetches the coordinates of Kano, NG using the OpenWeatherMap Geocoding API.

Args:
api_key: Your OpenWeatherMap API key.

Returns:
A tuple (latitude, longitude) if successful, None otherwise.
"""
base_url = "http://api.openweathermap.org/geo/1.0/direct"
params = {
"q": "Kano,NG",
"limit": 1,
"appid": api_key,
}

try:
response = requests.get(base_url, params=params)
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
except requests.exceptions.RequestException as e:
print(f"Error: An error occurred while making the request: {e}")
return None

try:
data = response.json()
except json.JSONDecodeError:
print("Error: Could not decode JSON response.")
return None

if not data:
print("Kano not found.")
return None

# Assuming the first result is the correct one
try:
latitude = data[0]["lat"]
longitude = data[0]["lon"]
return latitude, longitude
except (KeyError, IndexError):
print("Error: Unexpected response format. Could not extract coordinates.")
return None

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Get coordinates of Kano, NG using OpenWeatherMap API.")
parser.add_argument("api_key", help="Your OpenWeatherMap API key")
args = parser.parse_args()

coordinates = get_kano_coordinates(args.api_key)

if coordinates:
print(f"Latitude: {coordinates[0]}")
print(f"Longitude: {coordinates[1]}")
104 changes: 104 additions & 0 deletions get_kano_weather_forecast.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import argparse
import json
import requests
from datetime import datetime

def get_weather_forecast(api_key, lat, lon):
"""
Fetches and parses the 8-day daily weather forecast using the OpenWeatherMap One Call API 3.0.

Args:
api_key: Your OpenWeatherMap API key.
lat: Latitude.
lon: Longitude.

Returns:
The parsed 'daily' forecast list if successful, None otherwise.
"""
base_url = "https://api.openweathermap.org/data/3.0/onecall"
params = {
"lat": lat,
"lon": lon,
"exclude": "minutely,hourly,current,alerts",
"units": "metric",
"appid": api_key,
}

try:
response = requests.get(base_url, params=params)
response.raise_for_status()
except requests.exceptions.HTTPError as e:
if response.status_code == 401:
print(f"Error: Unauthorized. Invalid API key or subscription issue. Details: {e.response.text}")
elif 400 <= response.status_code < 500:
print(f"Error: Client error ({response.status_code}). Invalid parameters (e.g., coordinates). Details: {e.response.text}")
else:
print(f"Error: An HTTP error occurred: {e}. Details: {e.response.text}")
return None
except requests.exceptions.RequestException as e:
print(f"Error: An error occurred while making the request: {e}")
return None

try:
data = response.json()
except json.JSONDecodeError:
print("Error: Could not decode JSON response.")
return None

if "daily" not in data or not isinstance(data["daily"], list):
print("Error: 'daily' forecast data not found or not in expected format in API response.")
return None

return data["daily"]

if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Get and display 7-day daily weather forecast from OpenWeatherMap API.")
parser.add_argument("api_key", help="Your OpenWeatherMap API key")
parser.add_argument("latitude", type=float, help="Latitude for the forecast")
parser.add_argument("longitude", type=float, help="Longitude for the forecast")

args = parser.parse_args()

daily_forecast = get_weather_forecast(args.api_key, args.latitude, args.longitude)

if daily_forecast:
print("7-Day Weather Forecast:\n")
for i, day_data in enumerate(daily_forecast[:7]): # Iterate through the first 7 days
try:
date_ts = day_data["dt"]
date_readable = datetime.utcfromtimestamp(date_ts).strftime('%Y-%m-%d')

temp_min = day_data["temp"]["min"]
temp_max = day_data["temp"]["max"]
humidity = day_data["humidity"]

weather_main = day_data["weather"][0]["main"]
weather_desc = day_data["weather"][0]["description"]

wind_speed = day_data["wind_speed"]

print(f"Date: {date_readable}")
print(f" Temperature: Min: {temp_min}°C, Max: {temp_max}°C")
print(f" Humidity: {humidity}%")
print(f" Weather: {weather_main} ({weather_desc})")
print(f" Wind Speed: {wind_speed} m/s")
if i < 6: # Don't print separator after the last day
print("---")

except KeyError as e:
print(f"Error: Missing expected data for day {i+1}. Key not found: {e}")
print("Problematic day data:", day_data)
if i < 6:
print("---")
except IndexError:
print(f"Error: 'weather' data is missing or incomplete for day {i+1}.")
print("Problematic day data:", day_data)
if i < 6:
print("---")
except Exception as e: # Catch any other unexpected error during parsing/printing a day
print(f"An unexpected error occurred processing day {i+1}: {e}")
print("Problematic day data:", day_data)
if i < 6:
print("---")
else:
print("Could not retrieve or parse weather forecast.")
Binary file added img/logo-learning.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed img/logo.png
Binary file not shown.
Loading