<jupyter_start><jupyter_text>Meteor Shower Predictions Comets, Moon phases, and place on Earth influence the observation of the meteor showers.Meteoroids can come from comets, asteroids, moons, and planets - here, the focus is on meteoroids that come from 4 popular comets. Four Comets  1. Comet ThatcherComet Thatcher was first discovered in 1861. It takes 415.5 years for comet Thatcher to orbit the sun.The debris from this comet creates the Lyrids meteor shower each April. The first recorded sighting of the Lyrids meteor shower goes back to 687 BC.The Lyrids meteor shower appears to come from the direction of the constellation Lyra. But the comet and meteor shower don't actually originate from this constellation. 2. Comet HalleyComet Halley was first discovered in 1531. However, only in 1705 was it discovered that the comet sighted in 1531, 1607, and 1682 was the same comet.Comet Halley takes 76 years to orbit the sun. The debris from this comet creates the Eta Aquarids meteor shower each May and the Orionids meteor shower each October.The Eta Aquarids meteor shower appears to come from the direction of the constellation Aquarius. The Orionids meteor shower appears to come from the direction of the constellation Orion. 3. Comet Swift-TuttleComet Swift-Tuttle was first discovered in 1862. This comet takes 133 years to orbit the sun. Debris from this comet creates the Perseids meteor shower each August.It wasn't until 1865 that it was understood that this meteor shower originated from Comet Swift-Tuttle. The Perseids meteor shower appears to come from the direction of the constellation Perseus. 4. Comet Tempel-TuttleComet Tempel-Tuttle was independently discovered twice, in 1865 and 1866. This comet takes 33 years to orbit the sun. Debris from this comet creates the Leonids meteor shower each November.Every 33 years, the Leonids meteor shower becomes a meteor storm. A meteor storm is when there are at least 1,000 meteors per hour. The Leonids meteor shower appears to come from the direction of the constellation Leo. Moon phasesAs the Moon orbits Earth, and Earth orbits the sun, different amounts of sunlight are reflected off the Moon to Earth. Each month, the Moon cycles through different phases. The phases are basically the names we apply to how much sunlight we see reflecting off certain parts of the Moon.These are the phases of the Moon:- New Moon: Around the 15th of the month- Waxing crescent- First quarter: Around the 23rd of the month- Waxing gibbous- Full Moon: Around the 1st of the month- Waning gibbous- Third quarter: Around the 10th of the month- Waning crescentNew Moon, first quarter, full Moon, and third quarter are the most frequently tracked phases. The phases cycle every 29 days, so the exact dates depend on the number of days in the month.  Step 1: Import & Clean Data  Import data science libraries<jupyter_code>import numpy as np
import pandas as pd<jupyter_output><empty_output><jupyter_text>Import & Read data<jupyter_code>meteor_showers = pd.read_csv('data/meteorshowers.csv')
moon_phases = pd.read_csv('data/moonphases.csv')
constellations = pd.read_csv('data/constellations.csv')
cities = pd.read_csv('data/cities.csv')<jupyter_output><empty_output><jupyter_text>Check first 5 rows & info of each dataset Meteor Showers<jupyter_code>meteor_showers.head()

meteor_showers.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 9 columns):
 #   Column               Non-Null Count  Dtype 
---  ------               --------------  ----- 
 0   name                 5 non-null      object
 1   radiant              5 non-null      object
 2   bestmonth            5 non-null      object
 3   startmonth           5 non-null      object
 4   startday             5 non-null      int64 
 5   endmonth             5 non-null      object
 6   endday               5 non-null      int64 
 7   hemisphere           5 non-null      object
 8   preferredhemisphere  5 non-null      object
dtypes: int64(2), object(7)
memory usage: 488.0+ bytes<jupyter_text>Moon phases<jupyter_code>moon_phases.head()
moon_phases.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 365 entries, 0 to 364
Data columns (total 4 columns):
 #   Column        Non-Null Count  Dtype 
---  ------        --------------  ----- 
 0   month         365 non-null    object
 1   day           365 non-null    int64 
 2   moonphase     50 non-null     object
 3   specialevent  10 non-null     object
dtypes: int64(1), object(3)
memory usage: 11.5+ KB<jupyter_text>Constellations<jupyter_code>constellations.head()
constellations.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 5 entries, 0 to 4
Data columns (total 6 columns):
 #   Column         Non-Null Count  Dtype 
---  ------         --------------  ----- 
 0   constellation  5 non-null      object
 1   bestmonth      5 non-null      object
 2   latitudestart  5 non-null      int64 
 3   latitudeend    5 non-null      int64 
 4   besttime       5 non-null      object
 5   hemisphere     5 non-null      object
dtypes: int64(2), object(4)
memory usage: 368.0+ bytes<jupyter_text>Cities where they can be seen<jupyter_code>cities.head()
cities.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 256 entries, 0 to 255
Data columns (total 3 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   city      256 non-null    object 
 1   latitude  256 non-null    float64
 2   country   256 non-null    object 
dtypes: float64(1), object(2)
memory usage: 6.1+ KB<jupyter_text>Data Wrangling<jupyter_code># Convert strings to integers for months

months = {'january':1, 'february':2, 'march':3, 'april':4, 'may':5, 'june':6, 'july':7, 'august':8, 'september':9, 'october':10, 'november':11, 'december':12}

# Map integers to strings for months
meteor_showers.bestmonth = meteor_showers.bestmonth.map(months)
meteor_showers.startmonth = meteor_showers.startmonth.map(months)
meteor_showers.endmonth = meteor_showers.endmonth.map(months)
moon_phases.month = moon_phases.month.map(months)
constellations.bestmonth = constellations.bestmonth.map(months)

# Check change

meteor_showers.head()
meteor_showers.info()
# Converting months and days in the meteor_showers DataFrame to a type called datetime, which tracks dates
# Creating 2 new columns startdate and enddate. These columns will contain a month and day in 2021

meteor_showers['startdate'] = pd.to_datetime(2021*10000+meteor_showers.startmonth*100+meteor_showers.startday,format='%Y%m%d')
meteor_showers['enddate'] = pd.to_datetime(2021*10000+meteor_showers.endmonth*100+meteor_showers.endday,format='%Y%m%d')
# Moon phases

moon_phases['date'] = pd.to_datetime(2021*10000+moon_phases.month*100+moon_phases.day,format='%Y%m%d')
# Converting hemisphere data to numbers

hemispheres = {'northern':0, 'southern':1, 'northern, southern':2}
meteor_showers.hemisphere = meteor_showers.hemisphere.map(hemispheres)
constellations.hemisphere = constellations.hemisphere.map(hemispheres)
preferredhemispheres = {'northern':0, 'southern':1, 'northern, southern':2}
meteor_showers.preferredhemisphere = meteor_showers.preferredhemisphere.map(preferredhemispheres)
meteor_showers.head()
# Converting Moon phases to numbers that represent the percentage of the Moon that's visible

phases = {'new moon':0,'third quarter':0.5, 'first quarter':0.5,'full moon':1.0}
moon_phases['percentage'] = moon_phases.moonphase.map(phases)
moon_phases.head()<jupyter_output><empty_output><jupyter_text>Remove unnecessary data<jupyter_code>meteor_showers = meteor_showers.drop(['startmonth', 'startday', 'endmonth', 'endday', 'hemisphere'], axis=1)
meteor_showers.head()

moon_phases = moon_phases.drop(['month','day','specialevent'], axis=1)

moon_phases.head()
constellations = constellations.drop(['besttime'], axis=1)
constellations.head()<jupyter_output><empty_output><jupyter_text>Fill in missing dataIn Moon Phases, make every value between 0 and 0.5 be 0.25, and every value between 0.5 and 1 be 0.75.<jupyter_code>moon_phases.head()
lastPhase = 0

for index, row in moon_phases.iterrows():
    if pd.isnull(row['percentage']):
        moon_phases.at[index,'percentage'] = lastPhase
    else:
        lastPhase = row['percentage']

moon_phases.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 365 entries, 0 to 364
Data columns (total 3 columns):
 #   Column      Non-Null Count  Dtype         
---  ------      --------------  -----         
 0   moonphase   50 non-null     object        
 1   date        365 non-null    datetime64[ns]
 2   percentage  365 non-null    float64       
dtypes: datetime64[ns](1), float64(1), object(1)
memory usage: 8.7+ KB<jupyter_text>Step 2: Analyze Data Predicting the date of a meteor shower, in a given city<jupyter_code>meteor_showers.info()
moon_phases.info()
cities.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
RangeIndex: 256 entries, 0 to 255
Data columns (total 3 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   city      256 non-null    object 
 1   latitude  256 non-null    float64
 2   country   256 non-null    object 
dtypes: float64(1), object(2)
memory usage: 6.1+ KB<jupyter_text>Steps The function will:1. Determine the latitude of a city.2. Use that latitude to figure out which constellations are visible to that city.3. Use the constellations to determine which meteor showers are visible to that city.4. Use the meteor showers to determine the dates that they're visible.5. Use the dates to find the optimal date that has the least amount of light from the Moon.<jupyter_code># Create a function called predict_best_meteor_shower_viewing that takes in a city as a parameter

def predict_best_meteor_shower_viewing(city):
    # Create an empty string to return the message back to the user
    meteor_shower_string = ""

    if city not in cities.values:
        meteor_shower_string = "Unfortunately, " + city + " isn't available for a prediction. Try a capital city."
        return meteor_shower_string

    # Get the latitude of the city from the cities DataFrame
    latitude = cities.loc[cities['city'] == city, 'latitude'].iloc[0]

    # Get the list of constellations that are viewable from that latitude
    constellation_list = constellations.loc[(constellations['latitudestart'] >= latitude) & (constellations['latitudeend'] <= latitude), 'constellation'].tolist()

    # If no constellations are viewable, let the user know
    if not constellation_list:
        meteor_shower_string = "Unfortunately, there are no meteor showers viewable from "+ city + "."

        return meteor_shower_string
    
    meteor_shower_string = "In " + city + ", you can see the following meteor showers:\n"

# Iterate through each constellation that is viewable from the city
    for constellation in constellation_list:
        # Find the meteor shower that is nearest to that constellation
        meteor_shower = meteor_showers.loc[meteor_showers['radiant'] == constellation, 'name'].iloc[0] 
        # Find the start and end dates for that meteor shower
        meteor_shower_startdate = meteor_showers.loc[meteor_showers['radiant'] == constellation, 'startdate'].iloc[0]
        meteor_shower_enddate = meteor_showers.loc[meteor_showers['radiant'] == constellation, 'enddate'].iloc[0]

        # Find the Moon phases for each date within the viewable time frame of that meteor shower
        moon_phases_list = moon_phases.loc[(moon_phases['date'] >= meteor_shower_startdate) & (moon_phases['date'] <= meteor_shower_enddate)]
        
        # Find the first date where the Moon is the least visible
        best_moon_date = moon_phases_list.loc[moon_phases_list['percentage'].idxmin()]['date']

        # Add that date to the string to report back to the user
        # Convert the date to a pydatetime and then into a string
        meteor_shower_string += meteor_shower + " is best seen if you look towards the " + constellation + " constellation on " +  best_moon_date.to_pydatetime().strftime("%B %d, %Y") + ".\n"
        
    return meteor_shower_string
print(predict_best_meteor_shower_viewing('Bucharest'))<jupyter_output>In Bucharest, you can see the following meteor showers:
Lyrids is best seen if you look towards the Lyra constellation on April 22, 2021.
Eta Aquarids is best seen if you look towards the Aquarius constellation on April 22, 2021.
Orionids is best seen if you look towards the Orion constellation on October 16, 2021.
Perseids is best seen if you look towards the Perseus constellation on July 20, 2021.
{'fraction_non_alphanumeric': 0.09003952569169961, 'fraction_numerical': 0.029723320158102768, 'mean_word_length': 3.782986767485822, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '530013', 'license': 'MIT', 'n_tokens_mistral': 4271, 'n_tokens_neox': 3776, 'n_words': 1340, 'path': 'meteor_showers.ipynb', 'repo_name': 'georgiavanc/MeteorShowerProject', 'size': '12650'}