Day 061 - Project 61 : Twitter rip off

If you have any questions, comments or issues with this project please post them here!

Hi everyone,

I was having a problem with day 61. I managed to view tweets in order, 5 at a time as I wanted, but when user inputs they want to stop viewing messages, it causes an infinite loop. Can anyone explain why?

Below you see I have for loop inside a while True loop. Once user should have caused a break inside the for loop: system seemed to ignore break command, ignore counters, and just print till eternity. I tried modifying my IFs and counters and later I made it into a function, but I only beat this problem once I removed the while True loop :hot_face:
Why infinite loop begins after break command was meant to kill the print?
If interested, you should see final working program here.

from replit import db
import os, time, datetime


while True:
    os.system("clear")
    choice = input("Do you want to \nAdd a tweet (1) \nSee old tweets (2):\n> ").strip()

    if choice == "1":
        tweet = input("Write your tweet: ")
        timestamp = datetime.datetime.now()
        db[timestamp] = tweet

    elif choice == "2":
        keys = db.keys()
        keys = sorted(keys)
        
        print()
        
        counter = 0
        counter2 = 0

        while True:
            for key in list(reversed(keys)):
                print(db[key])
                print()
                counter += 1
                counter2 += 1

                if counter == 5:
                    print()
                    see_more = input("More tweets? y/n > ").strip().lower()
                    print()
                    if see_more[0] == "y":
                        continue
                    else:
                        break

            if counter2 == len(list(keys)):
                print("<<System notice: that is all, folks!>>")
                break

        time.sleep(2)
        
    else:
        print()
        print("You must press 1 or 2.")
        time.sleep(1)
        continue

Hi @Monco-Carser thanks for your question.

The break command only stops execution of the current loop (in this case, the โ€œfor key in listโ€ loop). The while loop still continues.

4 Likes

how do I delete my tweets the del db[keyname] isnโ€™t working ig Iโ€™m messing up on somewhere

#tweeter clone project no copyright intended 
from replit import db
import datetime,os, time
def addTweet():
  twee=input("Share your thoughts\n๐Ÿ•Š๏ธ   ")
  zone=datetime.datetime.now()
  key= f"msg{zone}"
  db[key] = twee
  time.sleep(1)
  os.system("clear")
def viewTweet():
  os.system("clear")
  time.sleep(0.5)
  matches = db.prefix("msg")
  print()
  matches=matches[::-1]
  counter=0
  for i in matches:
    print(db[i])
    print()
    counter+=1
    if (counter%10)==0:
      more=input("Show more\n~ ").lower()
      if more =="no":
        break
      else:
        os.system("clear")
        continue
  time.sleep(4)
  os.system("clear")
def delTweet():
  twee=input("Select a thought to delete \n๐Ÿ•Š๏ธ   ")
  if twee in db["msg"]:
    del db["msg"]
print("๐Ÿ•Š๏ธ๐Ÿ•Š๏ธTweeter๐Ÿ•Š๏ธ๐Ÿ•Š๏ธ")
print()
time.sleep(0.5)
print("""
             ๐Ÿ•Š๏ธ๐Ÿ•Š๏ธ๐Ÿ•Š๏ธ๐Ÿ•Š๏ธ๐Ÿ•Š๏ธ๐Ÿ•Š๏ธ        ๐Ÿ•Š๏ธ       ๐Ÿ•Š๏ธ         ๐Ÿ•Š๏ธ๐Ÿ•Š๏ธ
                ๐Ÿ•Š๏ธ          ๐Ÿ•Š๏ธ      ๐Ÿ•Š๏ธ๐Ÿ•Š๏ธ      ๐Ÿ•Š๏ธ
                 ๐Ÿ•Š๏ธ         ๐Ÿ•Š๏ธ    ๐Ÿ•Š๏ธ  ๐Ÿ•Š๏ธ     ๐Ÿ•Š๏ธ
                  ๐Ÿ•Š๏ธ       ๐Ÿ•Š๏ธ    ๐Ÿ•Š๏ธ    ๐Ÿ•Š๏ธ   ๐Ÿ•Š๏ธ
                   ๐Ÿ•Š๏ธ      ๐Ÿ•Š๏ธ  ๐Ÿ•Š๏ธ       ๐Ÿ•Š๏ธ ๐Ÿ•Š๏ธ     """)
print()
time.sleep(2)
os.system("clear")
while True:
  print("Welcome to Tweeter๐Ÿ•Š๏ธ")
  print()
  menu=input("1: Add tweet, 2: view tweet, 3: delete tweet  4: Exit \n~ ")
  if menu=="1":
    addTweet()
  elif menu=="2":
    viewTweet()
  elif menu=="3":
    delTweet()
  elif menu=="4":
    os.system("clear")
    time.sleep(0.5)
    break
  else:
    continue

Hi @Rocko,

I have moved your topic into #100-days-of-code.

One thing that would be useful is if you would format your code. Python has meaningful whitespace, so thereโ€™s a chance that could be the error.
But I have manually formatted your code and seemed to have found the problem.

Here you get the time and add it to the key.

Here you try to delete it but you did not enter the entire key. You did not put the time.

So the solution to this would be to loop through every key instead:

for key in db.keys():
	if twee in db[key]:
		del db[key]

Full code:

#tweeter clone project no copyright intended
from replit import db
import datetime, os, time

def addTweet():
	twee = input("Share your thoughts")
	zone = datetime.datetime.now()
	key = f"msg{zone}"
	db[key] = twee
	time.sleep(1)
	os.system("clear")

def viewTweet():
	os.system("clear")
	time.sleep(0.5)
	matches = db.prefix("msg")
	print()
	matches = matches[::-1]
	counter = 0
	for i in matches:
		print(db[i])
		print()
		counter += 1
		if (counter % 10) == 0:
			more=input("Show more\n~ ").lower()
			if more == "no":
				break
			else:
				os.system("clear")
				continue
			time.sleep(4)
			os.system("clear")
def delTweet():
	twee=input("Select a thought to delete \n")
	for key in db.keys():
		if twee in db[key]:
			del db[key]
			print(":dove::dove:Tweeter:dove::dove:")
			print()
			time.sleep(0.5)
			print("""
			:dove::dove::dove::dove::dove::dove: :dove: :dove: :dove::dove:
			:dove: :dove: :dove::dove: :dove:
			:dove: :dove: :dove: :dove: :dove:
			:dove: :dove: :dove: :dove: :dove:
			:dove: :dove: :dove: :dove: :dove: """)
			print()
	time.sleep(2)
	os.system("clear")
while True:
	print("\nWelcome to Tweeter๐Ÿ•Š๏ธ\n")
	menu = input("1: Add tweet, 2: view tweet, 3: delete tweet 4: Exit \n~ ")
	if menu == "1":
		addTweet()
	elif menu == "2":
		viewTweet()
	elif menu == "3":
		delTweet()
	elif menu == "4":
		os.system("clear")
		time.sleep(0.5)
		break
	else:
		continue
2 Likes

@QwertyQwerty88 ,
noice thanks again bro!

1 small question bro so writing key replicates the process of writing its corresponding key name? itโ€™s a bit confusing how it worked we just wrote key and didnโ€™t put the actual key name here too :sweat_smile:
so its like key is the name for all the keys stored inside if we need some specific keys then we write the names is it right?

I created a similar chatroom in Python that uses replit db. There are no sockets anywhere.

ReplTalk Terminal.
ReplTalk Web

Sorry I didnโ€™t notice you edited your reply earlier.

Yes, to access a key you must use the exact same key name that you saved it as.

1 Like

a short comment on sorting. in the solution, the db.prefix(โ€œprefixโ€) method is used to pull keys, which are then sorted in descending order by applying [::-1]. this works because the keys are returned already sorted by ascending order.

this doesnโ€™t work if you get the keys using db.keys(). i was wondering why, and the answer is that while db.prefix returns the keys as tuples, db.keys() returns them as a set. hence [::-1] can not be applied, but sorted() can be used: keys = sorted(db.keys(),reverse=True).

though i didnโ€™t properly look into this until after i already solved the challenge in a way too convoluted way.

3 Likes

Totally a better solution!

2 Likes

You can also use Recursion for viewing the latest n tweets (I have chosen 3 instead of 10):

Iโ€™m kinda a little proud I managed to successfully use this new concept :relieved: :innocent:

import datetime, os, time
from replit import db


def add(tweet):
  timestamp = datetime.datetime.now()
  db[timestamp] = tweet


def view(x):
  tweets = sorted(db.keys(), reverse=True)
  for tweet in (tweets[:x]):
    print(f"{tweet}:\t{db[tweet]}")
  more = input("\n\nview more? (y/n)\n")
  if more[0] == "y":
    os.system("clear")
    view(x + 3)
  else:
    menu()


def menu():
  os.system("clear")
  print("TWITTER FOR ONE\n\n")
  print(" MENU")
  print("========\n")
  menu = input("""Select Option:
  1: Add Tweet
  2: View Tweets\n\n""")
  if menu == "1":
    tweet = input("Type Your Thoughts here:\n")
    add(tweet)
  elif menu == "2":
    view(3)
  else:
    print(f"\n'{menu}' is not a Valid option!")
    time.sleep(2)


while True:
  menu()

2 Likes

https://replit.com/@arhanansari2009/Tweeter?v=1
here is my day 61 that I have solved
P.S:I have already completed my 100 Days of Code

I suggest using getkey and not the built-in input, b/c input temporarily halts all running code. When you use getkey you can view everything in real-time.

1 Like

i like your idea of using list slicing with :x . for some reason i never made the connection that string slicing could be applied to lists even though itโ€™s kinda obvious in hindsight.

1 Like


My Database tab looks nothing like the description in the tutorial.

Have your main.py tab and Database tab side by side:

(the outline means Iโ€™m focusing on that tab)

This is incredibly frustrating. I am writing the majority of my code in Pythonista and then copying it and pasting it. So sometimes I can get the code to work in Replit, and other times I get indentation errors. And vice versa, pasting from replit to Pythonista, the tabs and spaces are much altered.

Here is the code I have, I am not able to debug it further:


import os
import time
from replit import db
from datetime import datetime

def tweet():
	print("Please write your post.")
	post = input("> ")
	return post
	
def create_tweet():
	timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
	db[f"{timestamp}"] = tweet()
	
def Menu():
	print("1. Make a Tweet")
	print("2. View past Tweets")
	selection = input("(enter 1 or 2)> ")
	return selection
	
def view_tweets():
	page = 1
	while True:
		keys = db.keys
		keys.sort(reverse = True)
		display = keys[((page-1)*11):((page*10)+1)]
		for key in display:
		  print (db[key])
		page += 1
		moretweets = input("Display more tweets? y/n ")
		if moretweets == "n":
		  break
		else:
		  continue
	
	
	
while True:
  print("Twitter")
  print("")
  selection = Menu()

  if selection == "1":
	 create_tweet()
	 time.sleep(1)
	 os.system("clear")
	 print("Post successfully created!")
  elif selection == "2":
	 view_tweets()
	 time.sleep(1)
	 os.system("clear")
  else:
	 print("Please choose only 1 or 2")
	 time.sleep(1)
	 os.system("clear")
	 continue

What seems to be the problem?

It seems like Pythonista has a different tabbing convention, so if I paste anything into Replit and make a change, there is a different tabbing system for that one change. So I have to go through, delete all tabs, and start over. And if I donโ€™t start at the top, then the tabs inherit the tabbing system from the block they are in, which means working from bottom up does nothing.

As for the code, there were a few things I didnโ€™t do properly. I was using keys.sort, which kept denying that it was possible to sort. So I used the sorted function, with a similar effect. When I was eventually able to see my past tweets from the database I marked my tutorial as โ€œcompleted.โ€

Here is the version with the corrected indentations.

import os
import time
from replit import db
from datetime import datetime

def tweet():
	print("Please write your post.")
	post = input("> ")
	return post
	
def create_tweet():
	timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
	db[f"{timestamp}"] = tweet()
	
def Menu():
	print("1. Make a Tweet")
	print("2. View past Tweets")
	selection = input("(enter 1 or 2)> ")
	return selection
	
def view_tweets():
	page = 1
	while True:
		keys = db.keys
		keys.sort(reverse = True)
		display = keys[((page-1)*11):((page*10)+1)]
		for key in display:
		  print (db[key])
		page += 1
		moretweets = input("Display more tweets? y/n ")
		if moretweets == "n":
		  break
		else:
		  continue
	
	
	
while True:
  print("Twitter")
  print("")
  selection = Menu()

  if selection == "1":
	  create_tweet()
	  time.sleep(1)
	  os.system("clear")
	  print("Post successfully created!")
  elif selection == "2":
	  view_tweets()
	  time.sleep(1)
	  os.system("clear")
  else:
	  print("Please choose only 1 or 2")
	  time.sleep(1)
	  os.system("clear")
	  continue