0

Im new to python I wrote the code below, to search in a dictionary, do something, clear old items in dictionary and update dictionary with new key and values and break while there is noting to add to dictionary (it is empty), how can I modify my code to do this process?

#since_id - Returns results with an ID greater than 
#(that is, more recent than) the specified ID. There are limits to the 
#number of Tweets which can be accessed through the API.
# If the limit of Tweets has occured since the since_id,
# the since_id will be forced to the oldest ID available. 
# max_id - Returns results with an ID less than (that is, older than) 
#or equal to the specified ID.

Dict2 = dict({'@TweeetLorraine':1392217841680764931})
d2 = {}
rep=[] 
from tqdm import tqdm
for key, value in tqdm(Dict2.items()):
  for i in tweepy.Cursor(api.search,
                     q='to:{} -filter:retweets"'.format(key),lang="en"
                     ,since_id=value,tweet_mode='extended',
                     wait_on_rate_limit=True,
                     wait_on_rate_limit_notify=True).items(50):
                     if (i.in_reply_to_status_id == value):
                       rep.append(i)


                       from pandas.io.json import json_normalize
                       dfflat = pd.DataFrame()
                       for tweet in rep:
                         df_for_tweet = json_normalize(tweet._json)
                         dfflat=dfflat.append(df_for_tweet,ignore_index=True,sort=True)

                         d2.update(zip(dfflat["user.screen_name"].tolist(), dfflat["id"].tolist()))





d2 ```
user14269252
  • 412
  • 4
  • 15

1 Answers1

2

You can use a while loop for that :

#since_id - Returns results with an ID greater than 
#(that is, more recent than) the specified ID. There are limits to the 
#number of Tweets which can be accessed through the API.
# If the limit of Tweets has occured since the since_id,
# the since_id will be forced to the oldest ID available. 
# max_id - Returns results with an ID less than (that is, older than) 
#or equal to the specified ID.

Dict2 = dict({'@TweeetLorraine':1392217841680764931})
d2 = {}
rep=[] 
from tqdm import tqdm
for key, value in tqdm(Dict2.items()):
  for i in tweepy.Cursor(api.search,
                     q='to:{} -filter:retweets"'.format(key),lang="en"
                     ,since_id=value,tweet_mode='extended',
                     wait_on_rate_limit=True,
                     wait_on_rate_limit_notify=True).items(50):
                     if (i.in_reply_to_status_id == value):
                       rep.append(i)


                       from pandas.io.json import json_normalize
                       dfflat = pd.DataFrame()
                       for tweet in rep:
                         df_for_tweet = json_normalize(tweet._json)
                         dfflat=dfflat.append(df_for_tweet,ignore_index=True,sort=True)

                         d2.update(zip(dfflat["user.screen_name"].tolist(), dfflat["id"].tolist()))





d2

For your use case, here is roughly the code that does what you describe, there is better ways to do that using map, I let you search for it if you want to know more.

Also, I'm not sure whether you want to completely clear the dict or only clear the current "i", but I think you can modify the following snippet to your true needs

mydict = initial_dict
# while there is something in the dictionary
while mydict:
    value_searched = None
    for key, value in mydict.items():
        for i in tweepy.Cursor(api.search,
                     q='to:{} -filter:retweets"'.format(key),lang="en"
                     ,since_id=value,tweet_mode='extended',
                     wait_on_rate_limit=True,
                     wait_on_rate_limit_notify=True).items(50):
                     if (i.in_reply_to_status_id == value):
                       replies3.append(i)
                       value_searched = i
                       break
         break

    # create new dict from value retrieved
    mydict = {"@" +value_searched.user.screen_name : value_searched.id_str} 

Edit2 : Using recursivity

def tweepy_stub(key, value):
    if key == "TweeetLorraine" and value == 1392217841680764931:
        return [
            ("AlexBC997", 1392385334155956226),
            ("ChapinDolores", 1392432099945238529),
        ]
    elif key == "AlexBC997" and value == 1392385334155956226:
        return [("test", 139238533415595852)]
    elif ("ChapinDolores", 1392432099945238529):
        return []


def recursive(list_values, nb_recursion):
    mydict = {}
    if list_values == None or nb_recursion == 0:
        return mydict
    else:
        for name_user, tweet_id in list_values:
            mydict[(name_user, tweet_id)] = recursive(
                retrieve_direct_reply_stub(name_user, tweet_id), nb_recursion - 1
            )
        return mydict

class stub_tweepy_answer:
    def __init__(self, status_id) -> None:
        self.in_reply_to_status_id = status_id

def retrieve_direct_reply_stub(name_user, tweepy_id):
    rep = []
    d2 = []
    return tweepy_stub(name_user, tweepy_id)

def retrieve_direct_reply(name_user, tweet_id):
    rep = []
    d2 = []
    for i in tweepy_stub(name_user, tweet_id):
        val = i
        if (i.in_reply_to_status_id == tweet_id):
            rep.append(i)
            from pandas.io.json import json_normalize
            dfflat = pd.DataFrame()
            for tweet in rep:
                df_for_tweet = json_normalize(tweet._json)
                dfflat=dfflat.append(df_for_tweet,ignore_index=True,sort=True)

                d2.append(zip(dfflat["user.screen_name"].tolist(), dfflat["id"].tolist()))
    return d2

#print(retrieve_direct_reply_stub("TweeetLorraine", 1392217841680764931))

elem = [("TweeetLorraine", 1392217841680764931)]
print(recursive(elem, 3))
Wind56
  • 134
  • 7
  • Thank you so much , where should I put my main block of code? can you please update the answer based on my code? – user14269252 May 13 '21 at 08:16
  • what is retrieve_value = 4 ? – user14269252 May 13 '21 at 08:17
  • what is condition_met? – user14269252 May 13 '21 at 08:37
  • This is simply an example to show you how it's done, you have to write create_new_dict and condition_met for your use case. I'm editing and filling up the blanks with your specific case, but I won't verify that the code works. – Wind56 May 13 '21 at 12:20
  • The updated code unfortunately doesn't give me a correct answer, I want to extract replies to each tweet, in each loop of my code, it extract just replies to tweet, but I want all chain of replies such as replies to replies ..each tweet or reply has its own tweet id and user name.. my code is bale to bring to just replies to tweets, but what If I want replies to replies? that's why I wanted to clear the dict and fill it again with extracted replies to tweets ( each has tweet id and user name)... in this way I could be able to extract all the chain of replies.. maybe now you can help? – user14269252 May 13 '21 at 19:42
  • The code that you wrote just gives me one replies – user14269252 May 13 '21 at 19:45
  • Sorry if I sounded arrogant or something, it's just that you won't progress if I give you all the answers. For your specific problem, you need to use recursion. I'm modifying the code so that you can retrieve more than one tweet. – Wind56 May 13 '21 at 19:57
  • The problem is not progressing !.. I put more than one week time on it and I can't solve it that's why I asked here!, thanks any way ! the tweedy is the most annoying library – user14269252 May 13 '21 at 20:01
  • Thank you for modifying the code, it just made me so tired – user14269252 May 13 '21 at 20:03
  • It took me forever to write at least this pieces of code, at least I can get all replies to a tweet ....but I want also the replies to replies and replies to replies to replies.. – user14269252 May 13 '21 at 20:04
  • I also used recursion and I end up to this error and I asked here https://stackoverflow.com/questions/67516765/update-dictionary-during-a-loop-in-python-error-dictionary-changed-size-durin – user14269252 May 13 '21 at 20:08
  • To use recursion in python, you need to use a function that you will call again and again, and a stop condition. You should never modify a dict or a list while traversing it as it can create plenty of bugs. See here for more details https://stackoverflow.com/questions/10812272/modifying-a-list-while-iterating-over-it-why-not – Wind56 May 13 '21 at 20:16
  • Sorry but it gives the same answer as before {'@letsgettalking5': '1392643928864796673'} – user14269252 May 13 '21 at 20:17
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/232361/discussion-between-user14269252-and-wind56). – user14269252 May 13 '21 at 20:17
  • what is the value in dict ? what is @letsgettalking5 ? I feel I won't be able to help you if I do not understand better how tweepy works – Wind56 May 13 '21 at 20:19
  • Hi wind, I opened a new question regarding this, maybe you can have a look – user14269252 May 14 '21 at 06:41