5.4.2. Demo: Dictionaries#

Choose Social Media Platform: Reddit | Discord | Bluesky | No Coding

We’ve talked about lists, but the other data organization we need to work with social media data is dictionaries.

As we mentioned in chapter 4, dictionaries allow us to combine pieces of information by naming them (sort of like variables).

So for example, the information about a user might have the following pieces of data:

  • Username

  • Twitter handle

  • Profile Picture:

  • Follows

Python has two ways of doing these types of dictionaries: dict and objects

Dictionaries (dict)#

We can create dictionaries in Python by storing values into keys inside of curly braces { }, like this:

user_1 = {
    "username": "kylethayer",
    "twitter_handle": "@kylemthayer",
    "profile_picture": "kylethayer.jpg",
    "follows": ["@SusanNotess", "@UW", "@UW_iSchool", "@ajlunited"]
}

In the code above, inside of the curly braces are a set of lines. Each line has a string (the key, or name of the value), followed by a colon (:), followed by a value that is to be saved for the key. At the end of all but the last line is a comma (,) which indicates that another key and value will come next.

Now that we’ve saved some values for some keys in the dictionary now saved in user_1, we can look up the values by using square brackets ([, ]) with the key name inside, like this:

user_1_username = user_1["username"]
display(user_1_username)
'kylethayer'
user_1_handle = user_1["twitter_handle"]
display(user_1_handle)
'@kylemthayer'
user_1_picture = user_1["profile_picture"]
display(user_1_picture)
'kylethayer.jpg'
user_1_follows = user_1["follows"]
display(user_1_follows)
['@SusanNotess', '@UW', '@UW_iSchool', '@ajlunited']

Objects#

The other way of saving information that works similarly in Python is through an object. We won’t be creating any in this book, but we will have to get data from some.

The main difference from what we will need is that while in dictionaries we use square brackets and put the key name in quotes as a string (e.g., user_1["profile_picture"]), in an object you use a period (.) and don’t put they key name (called a field) in quotes (e.g., user_1.profile_picture)

We have already seen code that used this period to get something from an object a few times, specifically getting functions from them, like:

  • channel.send(...

  • normal_message.upper()

When we go through data from twitter, sometimes we will need to use . to get parts of the information out of objects, and sometimes we will need to use [" "] to get information out of dictionaries.

Looping through lists of dictionaries#

Now that we’ve seen loops, lists, and dictionaries, we can go to Discord, run a search and look through multiple messages:

load “discord” and nest_asyncio libraries#

# Load some code called "discord" that will help us work with Discord
import discord

# Load another library that helps the bot work in Jupyter Noteboook
import nest_asyncio
nest_asyncio.apply()

(optional) make a fake Discord connection with the fake_discord library#

For testing purposes, we’ve added this line of code, which loads a fake version of Discord, so it wont actually connect to Discord. If you want to try to actually connect to Discord, don’t run this line of code.

%run ../../fake_apis/fake_discord.ipynb
Fake discord is replacing the discord.py library. Fake discord doesn't need real passwords, and prevents you from accessing real discord

set up your Discord connection#

To use this on your real Discord account, copy your discord token into the code below, replacing our fake passwords.

# Set up your Discord connection
# TODO: put the discord token for your bot below
discord_token = "m#5@_fake_discord_token_$%Ds"


# set up Discord client with permissions to read message_contents
intents = discord.Intents.default()
intents.message_content = True 

find a list of discord posts#

We can now make a bot that loads a list of discord posts.

Note: If you run this on real discord, we can’t gurantee anything about how offensive what you might find is.

# set up discord connection
client = discord.Client(intents=intents)

# TODO: put the discord channel id number below for the channel you want to use
channel_id = 123456789

# Provide instructions for what your discord bot should do once it has logged in
@client.event
async def on_ready():
    global recent_posts # Save the recent_posts variable outside our running bot
    
    # Load the discord channel you want to post to
    channel = client.get_channel(channel_id)

    # Get the latest post in the channel history
    post_history = channel.history(limit=10)
    
    #special code to turn the post_history from discord into a python list
    recent_posts = [post async for post in post_history]

    # Tell your bot to stop running
    await client.close()
    
# Now that we've defined how the bot should work, start running your bot
client.run(discord_token)
Fake discord is pretending to set up a client connection
Fake discord bot is fake logging in and starting to run
Fake discord bot is shutting down

Loop through the list of posts#

The variable recent_posts now has a list of Discord posts. So we can use a for loop to go through each submission, and then use . to access info from each post (other pieces of information would need [" "] to access).

For each of the tweets, we will use print to display information about the tweet

for post in recent_posts:
    print("Info for post with id: " + str(post.id))
    print("  content: " + str(post.content))
    print("  author display name: " + str(post.author.display_name))
    print("  author id: " + str(post.author.id))
    print("  created at: " + str(post.created_at))
    print("  reactions: " + str(post.reactions))
    print("  is pinned?: " + str(post.pinned))
    print()
Info for post with id: 984353
  content: Breaking news: A lovely cat took a nice long nap today!
  author display name: fake_user
  author id: 4564563
  created at: 2024-07-25 01:23:04
  reactions: [FakeReaction(emoji='👍', me=False, count=2), FakeReaction(emoji='🥳', me=True, count=1)]
  is pinned?: False

Info for post with id: 7643
  content: Breaking news: Someone said a really mean thing on the internet today!
  author display name: pretend_user
  author id: 986545
  created at: 2024-07-20 05:20:04
  reactions: [FakeReaction(emoji='😠', me=True, count=8)]
  is pinned?: False

Info for post with id: 4534
  content: Breaking news: Some grandparents made some yummy cookies for all the kids to share!
  author display name: imaginary_user
  author id: 2358658
  created at: 2024-07-19 07:00:01
  reactions: [FakeReaction(emoji='👍', me=False, count=2), FakeReaction(emoji='🍪', me=True, count=3)]
  is pinned?: False

Info for post with id: 35588
  content: Breaking news: All the horrors of the universe revealed at last!
  author display name: not_real_user
  author id: 73458345
  created at: 2024-07-01 07:00:01
  reactions: []
  is pinned?: False