The purpose of the two programs is to have twitter.py manage tweet.py by having the 5 most recent tweets that are saved in the program twitter.py to show up once you search and find it. There are four options, make a tweet, view recents tweets, search a tweet and quit. I'm having trouble saving because it keeps saying no recent tweets are found. Also I'm having trouble with the fact that I can't search for my tweets but that is probably the same reason as my first problem because they aren't being saved correctly. Thank you please help!!
tweet.py
import time
class tweet:
def __init__(self, author, text):
self.__author = author
self.__text = text
self.__age = time.time()
def get_author(self):
return self.__author
def get_text(self):
return self.__text
def get_age(self):
now = time.time()
difference = now - self.__time
hours = difference // 3600
difference = difference % 3600
minutes = difference // 60
seconds = difference % 60
# Truncate units of time and convert them to strings for output
hours = str(int(hours))
minutes = str(int(minutes))
seconds = str(int(seconds))
# Return formatted units of time
return hours + ":" + minutes + ":" + seconds
twitter.py
import tweet
import pickle
MAKE=1
VIEW=2
SEARCH=3
QUIT=4
FILENAME = 'tweets.dat'
def main():
mytweets = load_tweets()
choice = 0
while choice != QUIT:
choice = get_menu_choice()
if choice == MAKE:
add(mytweets)
elif choice == VIEW:
recent(mytweets)
elif choice == SEARCH:
find(mytweets)
else:
print("\nThanks for using the Twitter manager!")
save_tweets(mytweets)
def load_tweets():
try:
input_file = open(FILENAME, 'rb')
tweet_dct = pickle.load(input_file)
input_file.close()
except IOError:
tweet_dct = {}
return tweet_dct
def get_menu_choice():
print()
print('Tweet Menu')
print("----------")
print("1. Make a Tweet")
print("2. View Recent Tweets")
print("3. Search Tweets")
print("4. Quit")
print()
try:
choice = int(input("What would you like to do? "))
if choice < MAKE or choice > QUIT:
print("\nPlease select a valid option.")
except ValueError:
print("\nPlease enter a numeric value.")
return choice
def add(mytweets):
author = input("\nWhat is your name? ")
while True:
text = input("what would you like to tweet? ")
if len(text) > 140:
print("\ntweets can only be 140 characters!")
continue
else:
break
entry = tweet.tweet(author, text)
print("\nYour tweet has been saved!")
def recent(mytweets):
print("\nRecent Tweets")
print("-------------")
if len(mytweets) == 0:
print("There are no recent tweets. \n")
else:
for tweets in mytweets[-5]:
print(tweets.get_author, "-", tweets.get_age)
print(tweets.get_text, "\n")
def find(mytweets):
author = input("What would you like to search for? ")
if author in mytweets:
print("\nSearch Results")
print("----------------")
print(tweet.tweet.get_author(), - tweet.tweet.get_age())
print(tweet.tweet.get_text())
else:
print("\nSearch Results")
print("--------------")
print("No tweets contained ", author)
def save_tweets(mytweets):
output_file = open(FILENAME, 'wb')
pickle.dump(mytweets, output_file)
output_file.close()
main()
In twitter.py:add_tweets, mytweets is passed into the function and entry is created, but it is never added to mytweets. The created entry is lost after the function returns.
Your question was:
I'm having trouble saving because it keeps saying no recent tweets are
found.
Function add does not seem to be adding tweets anywhere. It creates a tweet.tweet instance, but it does not do anything with it.
You probably want to add the tweet to mytweets?
Another problem:
You initialize mytweets as a dicionary (tweet_dct = {}), but later you use it as a list (mytweets[-5]). It should be a list from start. And you probably want last five tweets (mytweets[-5:]), not just the fifth from the end.
On the sidenotes:
What you have here is not "two programs" - it is one program in two python files, or "modules"
Although there is nothing wrong with having getters (functions like get_author), there is no need for them in Python (see How does the #property decorator work?). Do youself a favour and keep it simple, e.g.:
class Tweet:
def __init__(self, author, text):
self.author = author
self.text = text
self.creation_time = time.time()
def get_age_as_string(self):
# your code from get_age
There will be time when you need private variables. When that happens, use a single leading underscore (self._author) until you fully understand what double underscore does and why.
Pickle is probably not the best way to store information here, but it is a good start for learning.
Related
Ok so I am trying really hard to get this working. I think I am still not so familiar with the self argument yet, not sure if that matters in this case but I want to append user input once I choose number 1 in the menu and input data that appends to user_list and eventually saves in csv file. But I only get the code <main.User object at 0x7f36d7ccdfa0> in the csv file once I put in the data throught the program
import csv
user_list = []
class User:
def __init__(self, first, last):
self.first = first
self.last = last
self.email = first + '.' + last + '#expressdelivery.com'
def menu():
while True:
print("[1]. Add/remove/update: user to the system.")
try:
option = int(input("Choose from the menu: "))
if option == 1:
user_list.append(User(first = input("Name: "), last = input("Last: ")))
with open('User.csv', 'w') as file:
writer = csv.writer(file)
writer.writerow(user_list)
return(menu())
else:
print("Program quits")
break
except:
print("Error")
menu()
I've made these classes and now I'm trying to make a function that allows you to instantiate a new object from data a user inputs. But I'm getting syntax errors with using var()
The class structure is that there is one main with two sub-classes. The main, "Gokemon" is:
class Gokemon:
def __init__(self,NAME,TYPE,HEALTH,POWER): #Contructor #Mayb think about using dict key words
self._Name = str(NAME)
self._Type = str(TYPE) #Water, Earth, Fire or Flying. Used in Battle() to allow adders
self._HP = int(HEALTH) #Health Points
self._DP = int(POWER) #Power Points - attacking power
and the two sub-classes are named "Tame" and "Wild".
class Tame(Gokemon):
def __init__(self,NAME,TYPE,HEALTH,POWER):
Gokemon.__init__(self,NAME,TYPE,HEALTH,POWER)
self._Owner = ""
self._Time = 0 #How long have they owned it
class Wild(Gokemon):
def __init__(self,NAME,TYPE,HEALTH,POWER):
Gokemon.__init__(self,NAME,TYPE,HEALTH,POWER)
The function for making the new object by user input is as follows:
def NewGokemon():
n = input("What's its name?: ")
while True:
t = input("what's its type?: ")
if t == "Water" or t == "Fire" or t=="Earth" or t =="Flying":
break
else:
print("please try again, the types include:\nFire\nWater\nEarth\nFlying")
while True:
h = input("How many Health Points(HP) does it have")
try:
int(h)/2
except ValueError:
print("Sorry please input a numerical value")
else:
break
while True:
p = input("How many Health Points(HP) does it have")
try:
int(p)/2
except ValueError:
print("Sorry please input a numerical value")
else:
break
while True:
dom = input("Is the Gokemon tame(input t) or wild(input w)?")
if dom =="t":
return var()[n] = Tame(n,t,h,p)
if dom == 'w':
return var()[n] = Wild(n,t,h,p)
The function is fine until at the bottom, when im compiling to execute my Editor (VS code) says.
File "c:\Users\rufar\Desktop\python\little projects\Gokemon - learning class\Gokemon.py", line 38
return var()[n] = Tame(n,t,h,p)
^
SyntaxError: invalid syntax
What am i doing wrong? Is there a better way of doing this?
replaced the whole bit with vars() with this:
while True:
dom = input("Is the Gokemon tame(input t) or wild(input w)?")
if dom =="t":
globals()[n] = Tame(n,t,h,p)
return n
elif dom == 'w':
globals()[n] = Wild(n,t,h,p)
return n
else:
print("Did not understand input")
And now it works fine.
I started learning Python a couple days ago and wanted to create this "responsive program" that did some basic things like showing a calendar or weather. Everything works fine until it says "What can I help you with?" where it only shows the same line again. I am sorry if this is basic I just started Python somedays ago.
Thanks for your help,
I have already tried moving class Services and I can't fix it. Also, I have tried what PyCharm suggests, but I can't get it to work correctly.
#First attempt at responsive code
#Code made by dech
print('Hello! My name is Py. What is your name?')
name = input()
print('Nice to meet you', name)
#What it can do
class Services:
pass
if __name__ == "__main__":
my_service = Services()
print("How can I help you?")
while True:
action = input(
"I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
if action not in "WC" or len(action) != 1:
print("I don't know how to do that")
elif action == 'W':
my_services.weather()
elif action == 'C':
my_services.Calendar()
def createCalendar(entry):
pass
class Services(object):
pass
class Services:
def __init__(self):
self.weather
self.calendar
def weather(self):
import string
import json
from urllib.request import urlopen
# parameters
params1 = "<||^{tss+^=r]^/\A/+|</`[+^r]`;s.+|+s#r&sA/+|</`y_w"
params2 = ':#%:%!,"'
params3 = "-#%&!&')&:-/$,)+-.!:-::-"
params4 = params2 + params3 # gives k
params_id = "j+^^=.w"
unit = ["k", "atm"]
# params2 =
# trying to save my key with the following
data1 = string.printable
data2 = string.punctuation + string.ascii_uppercase + string.ascii_lowercase + string.digits
encrypt = str.maketrans(dict(zip(data1, data2)))
decrypt = str.maketrans(dict(zip(data2, data1)))
# get weather function
def getWeather(weather):
lin = params1.translate(decrypt)
kim = params4.translate(decrypt)
idm = params_id.translate(decrypt)
# open this
link = urlopen(lin + weather + idm + kim).read()
getjson = json.loads(link)
# result = getjson.gets()
print("Weather result for {}".format(weather), '\n')
"""
get json objects // make'em
"""
main = getjson.get("main", {"temp"}) # temperature
main2 = getjson.get("main", {"pressure"}) # pressure
main3 = getjson.get("main", {"humidity"}) # humidity
main4 = getjson.get("main", {"temp_min"})
main5 = getjson.get("main", {"temp_max"})
wind = getjson.get("wind", {"speed"}) # windspeed
sys = getjson.get("sys", {"country"}) # get country
coord = getjson.get("coord", {"lon"})
coord1 = getjson.get("coord", {"lat"})
weth = getjson.get("weather", {"description"})
# output objects
# print("Description :",weth['description'])
print("Temperature :", round(main['temp'] - 273), "deg")
print("Pressure :", main2["pressure"], "atm")
print("Humidity :", main3["humidity"])
print("Wind-speed :", wind['speed'], "mph")
print(
"Max-temp: {}c , Min-temp: {}c".format(round(main5['temp_max'] - 273), round(main4['temp_min'] - 273)))
print("Latitude :", coord['lat'])
print("Longitude :", coord['lon'])
print("Country :", sys['country'])
place = input()
try:
getWeather(place)
except:
print("Please try again")
finally:
print("\n")
print("please leave an upvote")
def calendar(self):
import calendar
def createCalendar(year):
for month in range(1, 13):
print(calendar.month(year.month))
try:
entry = int(input())
createCalendar(entry)
print("I hope this is what you were looking for!")
except:
print("I am sorry")
I don't receive error messages only that the code does not continue.
You have an infinite loop:
while True:
action = input("I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
# The rest of your code is outside the loop.
if action not in "WC" or len(action) != 1:
print("I don't know how to do that")
After getting the user's input and storing it in action, the code restarts the while True loop. Only the codes indented after the while loop are part of the loop.
You should move your code inside the loop.
while True:
action = input("I can do several things.I can check the [W]eather, or I can check the [C]alendar. What should I do?").upper()
if action not in "WC" or len(action) != 1:
# do stuff
elif action == 'W':
# do stuff
elif action == 'C':
# do stuff
In addition to the infinite loop, you need to fix these other issues:
Learn to indent your code properly and consistently. Indentation is important in Python. The PEP8 standard dictates using 4 spaces. You seem to be using more than 4.
Remove the duplicate, unnecessary class Services: pass codes. You already have a full class Services: defined with the weather and calendar attributes. You don't need to nest it inside another Services class.
class Services:
def __init__(self):
self.weather
self.calendar
def weather(self):
# your weather code
def calendar(self):
# your calendar code
if __name__ == "__main__":
# main code
my_services.Services()
# use my_services.weather...
# use my_services.calendar...
Be consistent in your variable names. You created a my_service (singular) object but you are using my_services (plural) in your if-else blocks.
Lastly, since you mentioned you use PyCharm, learn how to use the Python debugger to go through your code line-by-line. The debugger is a very helpful tool to check issues with your code.
I am trying to figure out a way to store songdata as a list in a .txt. The method I am using seems to be storing the values somewhere, but its not writing them to the file. I also am trying to insert a loop into it so I can keep entering "songs" instead of only one. I haven't used classes before and I cant quite grasp how it would be done. I maybe am going about it wrong and need to reformat parts? Any advice would be awesome.
class Song:
def __init__(self,song,chart,member):
self.song = song
self.chart = chart
self.member = member
def __str__(self):
return self.song + " topped the charts at " + str(self.chart)+ " band memebers include " + str(self.member)
songdata = Song(input("song"),input("chart spot"), input("bandemember"))
def readstring(f, line):
string = line.strip('\r\n')
return string
def writestring(f, string):
f.write(string)
with open("string.txt", "a+", encoding="utf-8") as f:
cont = "Y"
while cont.upper() == "Y":
d = input(songdata)
if d != "q":
string = " "+d
writestring(f, string)
else:
print("saving.....")
break
f.seek(0)
for line in f:
print(readstring(f,line))
f.close()
Couple of notes:
Because you only initialised the class once when you request the information from you user in the code d = input(songdata), the prompt from input will always display the same thing after the first time.
The reason why nothing is being written to file is probably because the response from d=... is always blank from the user. You requested the song information when you initialised the class (which you only did once), but never wrote that to file (instead you wrote f.write(string), where string=" "+d)
As mentioned in the replies, you don't really need a specific function to write to file when you can just call the file descriptors write() method.
I've re-written some of your code (the writing to file parts) below. I assumed you wanted the user to be able to exit the program at any time by entering in the key sequence q, and have done so accordingly. You can make something more nifty with generators I believe, but this isn't related to the problem:
class Song:
"""
song class
"""
def __init__(self, song, chart, member):
self.song = song
self.chart = chart
self.member = member
def __str__(self):
return (self.song
+ " topped the charts at "
+ str(self.chart)
+ " band memebers include "
+ str(self.member)
+ '\n'
)
def main():
with open("string.txt", "a+", encoding="utf-8") as fd:
#Loop until user requests to stop
#Key sequence to stop = 'q'
while(1):
#Get user input
prompt = ">>\t"
in_song = input("song" + prompt)
if (in_song == 'q'):
break
in_chart_spot = input("chart spot" + prompt)
if (in_chart_spot == 'q'):
break
in_band_mem = input("band members" + prompt)
if (in_band_mem == 'q'):
break
#Create the class
song_data = Song(in_song, in_chart_spot, in_band_mem)
#Write out the data
fd.write(str(song_data))
if __name__ == '__main__':
main()
Hope this helps :)
I'm working on a Tweet Manager program in python for my programming class. For the assignment, I'm supposed to create a Tweet class that stores the author of a tweet, the tweet itself, and the time the tweet was created. Then, I'm supposed to create a Twitter program that gives users a menu of options to choose from.
When I try to run my Twitter program, it opens without syntax errors, but prints the Menu over and over and over again really rapidly without stopping. I can't figure out what in my code is causing this problem.
Here is my Twitter code:
import Tweet
import pickle
def main():
try:
load_file = open('tweets.dat', 'rb')
tweets = pickle.load('tweets.dat')
load_file.close()
except:
tweet_list = []
while (True):
choice = display_menu()
#Make a Tweet
if (choice == 1):
tweet_author = input("\nWhat is your name? ")
tweet_text = input("What would you like to tweet? ")
print()
if len(tweet_text) > 140:
print("Tweets can only be 140 characters!\n")
else:
print(tweet_author, ", your Tweet has been saved.")
age = 0
tweets = tweet.Tweet(tweet_author, tweet_text)
tweet_list.append(tweets)
try:
output_file = open('tweets.dat', 'wb')
pickle.dump(tweets, output_file)
output_file.close()
except:
print("Your tweets could not be saved!")
#View Recent Tweets
elif (choice == 2):
print("Recent Tweets")
print("--------------")
if len(tweet_list) == 0:
print("There are no recent tweets. \n")
for tweets in tweet_list[-5]:
print(tweets.get_author(), "-", tweets.get_age())
print(tweets.get_text(), "\n")
#Search Tweets
elif (choice == 3):
match = 0
tweet_list.reverse()
if tweet_list == []:
print("There are no tweets to search. \n")
search = input("What would you like to search for? ")
for tweets in tweet_list:
if (search in tweets.get_text()):
match = 1
if match = 1:
print("Search Results")
print("--------------")
print(tweets.get_author(), "-", tweets.get_age())
print(tweets.get_text(), "\n")
elif match == 0:
print("No tweets contained", search, "\n")
#Quit
elif (choice == 4):
print("Thank you for using the Tweet Manager!")
exit()
def display_menu():
print("Tweet Menu")
print("------------")
print()
print("1. Make a Tweet")
print("2. View Recent Tweets")
print("3. Search Tweets")
print("4. Quit")
print()
main()
There's no problem, the code is doing precisely what you told it to.
display_menu does exactly what the name implies: displays the menu. The main function calls that function inside a loop.
At no point do you actually ask for any input corresponding to the menu options.
display_menu always returns None - that's the default if you don't return anything.
Display menu does not retrieve any input into choice... Just displays the menu.
Thus, no if is matched and you loop indefinitely.
Your display_menu function doesn't actually give a value.
Change the last line of that function (print()) to
return input()
or if you are using python 2.x
return raw_input()