Britannica: https://kids.britannica.com/students/article/African-American-history-timeline/625406 UCSC: https://diversity.ucsc.edu/news-events/news/images/blackhistory.pdf

################################# # Public Domain Image Sources ################################# ''' 1936, Jesse Owens: https://upload.wikimedia.org/wikipedia/commons/1/19/Jesse_Owens_1936.jpg 1920, Louis Armstrong: https://upload.wikimedia.org/wikipedia/commons/thumb/0/0e/Louis_Armstrong_restored.jpg/1280px-Louis_Armstrong_restored.jpg 1963, Martin Luther King Jr.: https://en.wikipedia.org/wiki/Martin_Luther_King_Jr.#/media/File:Martin_Luther_King_Jr_St_Paul_Campus_U_MN.jpg ''' ################################# # Event Information ################################# ''' This list stores all event information. date_list[i][0] is the display date (what appears on the timeline). date_list[i][1] is the numerical date (used to plot the event on the timeline). date_list[i][2] is the information about the timeline event. date_list[i][3] is the image URL or image label (optional). ''' date_list = [ ["~1600", 1600, "European colonists begin enslaving and transporting African people to the Americas. 1619 marks the first documented record of slaves brought to Virginia."], ["1808", 1808, "Congress bans importing slaves."], ["1820", 1820, "The Missouri Compromise bans slavery in the northern states."], ["1849", 1859, "Harriet Tubman escapes to Philadelphia. She would go on to return to Maryland to help her family and over 300 enslaved people escape using the Underground Railroad."], ["1861", 1861, "Southern states secede from the union and the Civil War begins."], ["1865", 1865, "The Civil War ends."], ["1865", 1865, "The Thirteenth Amendment to the U.S. Constitution abolishes slavery."], ["1868", 1868, "The Fourteenth Amendment to the U.S. Constitution grants citizenship and equal rights to Black Americans."], ["1916", 1916, "The Great Migration begins. Over the next 50 years, millions of Black Americans move from southern states to urban centers in the North and West."], ["~1920", 1920, "The Jazz Age starts led by talented musicians like Louis Armstrong, Jelly Roll Morton, Fletcher Henderson, and Duke Ellington.", "louis_armstrong_b7e"], ["~1924", 1924, "The Harlem Renaissance begins, starting a cultural movement in Harlem, NYC led by black writers, artists, and musicians."], ["1936", 1936, "Jesse Owens wins four gold medals at the 1936 Berlin Olympics in Nazi Germany. He wins gold in the 100m dash, 200m dash, long jump, and 4x100m Relay.", "jesse_owens_da8"], ["1947", 1947, "Jackie Robinson joins the Brooklyn Dodgers and becomes the first Black major league baseball player."], ["1955", 1955, "Rosa Parks refuses to give up her seat to a white person, leading to the Montgomery bus boycott."], ["1960", 1960, "Sit ins and become a nonviolent protest tactic, started by college students in North Carolina."], ["1963", 1963, 'Martin Luther King Jr. writes "Letter from a Birmingham Jail" and later in the year leads a march on D.C. where he makes his famous speech before 200,000 people.', "mlkjr_708"], ["1966", 1966, "The Black Panther Party is founded in Oakland, CA by Huey Newton and Bobby Seale to protect people from police brutality."], ] ################################# # Scrolling functionality ################################# stage.disable_all_walls() scroll_sprites = [] # List to store all sprites that can scroll def up_arrow_press(): for s in scroll_sprites: s.set_y_speed(-10) def up_arrow_release(): for s in scroll_sprites: s.set_y_speed(0) def down_arrow_press(): for s in scroll_sprites: s.set_y_speed(10) def down_arrow_release(): for s in scroll_sprites: s.set_y_speed(0) def disable_event(): pass def turn_controls_off(): for s in scroll_sprites: s.set_y_speed(0) stage.event_key("up", disable_event) stage.event_key_press("up", disable_event) stage.event_key_release("up", disable_event) stage.event_key("down", disable_event) stage.event_key_press("down", disable_event) stage.event_key_release("down", disable_event) def turn_controls_on(): stage.event_key_press("up", up_arrow_press) stage.event_key_release("up", up_arrow_release) stage.event_key_press("down", down_arrow_press) stage.event_key_release("down", down_arrow_release) ################################# # Click Events ################################# # Click event for each event sprite def date_click(sprite): # Turn off event until info box is closed for s in event_sprites: s.event_click(None) info_box.glide_to(info_box_x, info_box.get_y()) info_date.set_text(sprite.info[0]) info_text.show() info_text.set_text(sprite.info[2]) info_text.set_text_width(info_box_width-50) close_button.go_to(195, 190) close_button_x.go_to(195, close_button.get_y()-2) # Check if there's an image and show toggle if yes if sprite.image != None: switch.go_to(switch_x, switch_y) switch_left_label.go_to(switch_x-25, switch_y) switch_right_label.go_to(switch_x+25, switch_y) toggle.go_to(switch_x-25, switch_y) toggle.linked_image = sprite.image toggle.event_click(image_text_toggle) close_button.linked_image = sprite.image close_button.event_click(close_info_box) # Click event for image/text toggle def image_text_toggle(): toggle.event_click(None) # Disable event while performing it toggle.set_speed(10) # Perform actions to show the image if toggle.get_x() == switch_x-25: toggle.glide_to(switch_x+25, switch_y) info_text.hide() toggle.linked_image.go_to(info_box_x, info_box.get_y()) toggle.linked_image.show() # Perform actions to show the text else: toggle.glide_to(switch_x-25, switch_y) toggle.linked_image.hide() info_text.show() toggle.event_click(image_text_toggle) # Enable event # Click event for close button def close_info_box(): close_button.event_click(None) # Move sprites offstage to hide them if close_button.linked_image != None: close_button.linked_image.go_to(0, offstage_below) info_date.set_text("") info_text.set_text("") close_button.go_to(0, offstage_below) close_button_x.go_to(0, offstage_below) switch.go_to(switch_x, offstage_below) switch_left_label.go_to(switch_x-25, offstage_below) switch_right_label.go_to(switch_x+25, offstage_below) toggle.go_to(switch_x-25, offstage_below) info_box.glide_to(400, info_box.get_y()) # Enable the event clicking after close for s in event_sprites: s.event_click(date_click) # Click event for NEW button def new_click(): # Collect user input display_date = stage.ask("What date information would you like to appear on the timeline? (ex. 1950, ~1730)") numerical_date = int(stage.ask("What is the closest true date of the event? (This must be an integer)")) event_info = stage.ask("What information would you like to include about this event?") image_info = stage.ask("Paste the URL for an image here (optional):") confirmation = stage.ask("Enter yes to confirm entry or no to discard.") required_list = [display_date, numerical_date, event_info, confirmation] # These inputs are required if confirmation.lower() in ["n", "no"] or "" in required_list: print("Try again to make a new entry.") return # Exit event and cancel new entry if chosen or missing required inputs else: new_entry = [display_date, numerical_date, event_info] # Create new event entry if image_info != "": new_entry.append(image_info) # Add image URL if included date_list.append(new_entry) # Add new entry to date_list # Sort date_list using second item of inner lists date_list.sort(key=lambda x: x[1]) # Remove current event sprites to recreate timeline for s in event_sprites: stage.remove_sprite(s.text) stage.remove_sprite(s) event_sprites.clear() plot_dates(date_list) # Replot and recreate event sprites for s in event_sprites: s.event_click(date_click) # Provide instructions for user to save inputted information print("Copy the list below and paste it into\nyour code as a new item in date_list.\nClick save so that it appears the next time you run your code!\n") print(new_entry) # Click event for START button def start_click(): start_button.hide() start_button_text.hide() stage_shade.hide() instructions_text.hide() turn_controls_on() # Allow scrolling after start for s in event_sprites: s.event_click(date_click) new_button.event_click(new_click) ################################# # Helper Functions ################################# # Helper function to dynamically resize images def resize_sprite(sprite, max_dimension): if sprite.get_width() >= sprite.get_height(): if sprite.get_width() >= max_dimension: while sprite.get_width() > max_dimension: sprite.set_size(.95) else: while sprite.get_width() < max_dimension: sprite.set_size(1.05) else: if sprite.get_height() >= max_dimension: while sprite.get_height() > max_dimension: sprite.set_size(.95) else: while sprite.get_height() < max_dimension: sprite.set_size(1.05) # Create event sprite and add multiple properties to store data def make_event(event_info, y_position): rand_color = random.choice(["red", "orange", "yellow", "blue", "purple", "indigo", "violet", "green", "cyan", "pink"]) event_ellipse = codesters.Ellipse(timeline_x, y_position, 125, 35, rand_color, "black") event_date = codesters.Text(event_info[0], event_ellipse.get_x(), event_ellipse.get_y()) event_ellipse.info = event_info # Store info text as property on event sprite event_ellipse.text = event_date # Store date text sprite as property on event sprite # If the item includes an image URL, create and resize the image offstage if len(event_info) > 3: event_ellipse.image = codesters.Sprite(event_info[-1], 0, offstage_below) resize_sprite(event_ellipse.image, 290) else: event_ellipse.image = None if rand_color in ["blue", "purple", "indigo", "green"]: event_date.set_color("white") scroll_sprites.extend([event_ellipse, event_date]) event_sprites.append(event_ellipse) # Calculate relative position of each event item def plot_dates(dates): global last_event_y # Changes to store the position of the last created event sprite for i, val in enumerate(dates): if i == 0: event_y = first_event_y else: event_y = last_event_y - (dates[i][1] - dates[i-1][1])*scale if last_event_y - event_y < 40: event_y -= 25 last_event_y = event_y # Store position of last created event sprite to plot the next one make_event(val, event_y) # Create an event sprite # Turn physics on so that event sprites can scroll for s in scroll_sprites: s.set_physics_on() ################################# # Main Stage Setup ################################# stage.set_color("cornflowerblue") offstage_below = -1000 # Use as y value to create objects below the stage event_sprites = [] # store all the event sprites to turn events on and off first_event_y = 200 # initial position of the earliest event last_event_y = first_event_y # store position of last created event sprite scale = 2 # determines spacing between events on the timeline timeline_x = -175 timeline = codesters.Rectangle(timeline_x, 0, 5, 1000, "black") # Information display sprites info_box_width = 300 info_box_x = 70 info_box = codesters.Rectangle(400, 10, info_box_width, 400, "orange", "black") info_box.set_opacity(.75) info_date = codesters.Text("", info_box_x, 190, "black") info_date.set_text_weight("bold") info_text = codesters.Text("", info_box_x, 0, "black") close_button = codesters.Circle(0, offstage_below, 20, "red", "black") close_button.linked_image = None close_button_x = codesters.Text("X", 0, offstage_below, "black") close_button_x.set_text_size(18) switch_x = 70 switch_y = -165 switch = codesters.Rectangle(switch_x, offstage_below, 100, 25, "black") switch_left_label = codesters.Text("TEXT", switch_x-25, offstage_below, "yellow") switch_left_label.set_text_size(10) switch_right_label = codesters.Text("IMAGE", switch_x+25, offstage_below, "yellow") switch_right_label.set_text_size(10) toggle = codesters.Rectangle(switch_x-25, offstage_below, 45, 20, "white") toggle.linked_image = None toggle.set_opacity(.5) # Create event sprites plot_dates(date_list) new_button = codesters.Rectangle(70, -220, 100, 35, "green", "black") new_button_text = codesters.Text("NEW", new_button.get_x(), new_button.get_y()) # Show instructions and start button stage_shade = codesters.Square(0, 0, 500, "blue") stage_shade.set_opacity(.3) instructions = '''Use the UP and DOWN arrow keys to navigate the timeline! \n\nClick on a date to learn what event took place at that time. \n\nClick NEW and follow the instructions to add more events!''' instructions_text = codesters.Text(instructions, 70, 50) instructions_text.set_text_width(300) start_button = codesters.Rectangle(70, -110, 250, 100, "orange", "black") start_button_text = codesters.Text("START", start_button.get_x(), start_button.get_y()) start_button.event_click(start_click)
  • Run Code
  • Show Console
  • Codesters How To (opens in a new tab)