Running a dictionary with a while loop - python

I am trying to insert a while loop into this program so when it asks for member it starts a dictionary (assuming I would use a dictionary) that lets me input n number of band members and the instrument they use in some form like (name,instrument),(name2,instrument2)..and so on. I know it will be run as a while loop, but I'm not not sure how to enter it in this instance. Would using a dictionary be the best action and if so how would I add it in a case like this?
class Song:
def __init__(self, song, chart, member):
self.song = song
self.chart = chart
self.member = member
def __str__(self):
return (self.song
+ " Top Chart:"
+ str(self.chart)
+ " Band Members: "
+ str(self.member)
+ '\n')
def write():
with open("string.txt", "a+", encoding="utf-8") as f:
while(1):
prompt = ":\t"
in_song = input("Input song or type q " + prompt)
if (in_song == 'q'):
break
in_chart_spot = input("Input chart spot" + prompt)
in_band_mem = input("Input band members" + prompt)
song_data = Song(in_song, in_chart_spot, in_band_mem)
#albumdata = Album()
f.write(str(song_data))
if __name__ == '__main__':
write()

Related

How can I prevent my JSON file from getting overwritten in Python?

I am currently building a school homework project - a contact manager, using classes in Python.
I was able to assemble all the needed parts to make my code work, yet upon exiting the program with Terminal, the data inside of my JSON file keep being overwritten.
I've tried changing the with open attribute to "w" and "a", sadly nothing works.
Main Code:
from colorama import Fore, Style
from LoadAndSave import load_file, save_file
from ContactBook import ContactBook
contacts = []
DATA_FILE = "contactbook.json"
def menu():
print(Fore.RED + "Welcome to Contacts Manager v2.0.0!" + Style.RESET_ALL)
print(Fore.LIGHTCYAN_EX + "Please enter your selection according to the menu." + Style.RESET_ALL)
print("a - Add a contact")
print("r - Remove a contact")
print("s - Search for a contact")
print("p - Print a list of all contacts")
print("x - Exit")
user_selection = input(Fore.GREEN + "Your selection: " + Style.RESET_ALL)
return user_selection
def main():
load_file(DATA_FILE)
contactbook = ContactBook()
user_selection = ""
while user_selection != "x":
user_selection = menu() # As long as user did not select "x", program will always run.
if user_selection == "a":
contactbook.add_contact(input("Please enter contact's name: "), int(input("Please enter contact's number: ")))
if user_selection == "r":
contactbook.remove_contact(contactbook.search_contact(input("Contact's Name? ")))
if user_selection == "s":
contactbook.search_contact(input("Contact's name?"))
print(Fore.GREEN + "Success!" + Style.RESET_ALL)
if user_selection == "p":
print(contactbook)
print(Fore.GREEN + "Success!" + Style.RESET_ALL)
print(Fore.MAGENTA + "Thank you for using my software. Bye!")
save_file(contactbook.make_contact_json(), DATA_FILE)
if __name__ == "__main__":
main()
Load and save:
import json
def load_file(DATA_FILE): # Loading JSON file with all information
with open (DATA_FILE) as file:
return json.load(file)
def save_file(json_list, DATA_FILE):
with open (DATA_FILE, "w") as file:
json.dump(json_list, file, indent = 4)
Contact & ContactBook classes:
import json
class Contact:
name = ""
tel = 0
def __init__(self, name = "", tel = 0):
self.name = name
self.tel = tel
def __str__(self):
return json.dumps({"contact_info":[{"name": self.name, "tel": self.tel}]})
from colorama import Fore, Style, Back
from Contact import Contact
import json
class ContactBook:
contacts = []
def __init__(self):
pass
def add_contact(self, name = "", tel = 0):
self.contacts.append(Contact(name, tel))
print(Fore.GREEN + "Success!" + Style.RESET_ALL)
def remove_contact(self, contact_name):
self.contacts.remove(contact_name)
print(Fore.RED + "Removed.\n" + Style.RESET_ALL)
def search_contact(self, contact_name):
for contact in self.contacts:
if type(contact) is Contact:
if contact.name == contact_name:
return contact
return (Back.RED + "\nThere is no contact with that name." + Style.RESET_ALL + "\n")
def make_contact_json(self):
result = []
for contact in self.contacts:
result.append(json.loads(contact.__str__()))
return result
def __str__(self) -> str:
result = ""
for contact in self.contacts:
result += contact.__str__()
return result
JSON File:
[
[
{
"name": "sdfgh",
"tel": 654321
}
]
]
Thanks in advance to all helpers!
Your contacts are getting overwritten because every time you run your program, you are creating a fresh ContactBook
contactbook = ContactBook() # In your Main Code
This in turn initializes an empty contacts list
contacts = [] # Inside Class ContactBook
I suggest that you add an __init__ logic to you ContactBook Class that initialises your contacts list with the existing ones
Something Like
class ContactBook:
def __init__(self, existing_contacts=None):
self.contacts = [] if existing_contacts is None else existing_contacts
Also while creating the ContactBook object in you main code please pass the existing contacts.
try:
existing_contacts = load_file(DATA_FILE)
except FileNotFoundError:
existing_contacts = None
contactbook = ContactBook(existing_contacts)
Also please make sure that you are saving the contacts correctly. It seems to currently be a list of list of objects where as it should ideally be a list of objects
Hope you get good grades. Peace out.

Im having trouble editing an object in OOP in my project

Basically im doing a project in python as part of my full stack course, and i have ran into wall.
My project is a parking lot system, which gets you a ticket with your cars number, unique code, time entered. At the exit you will have to write the unique code and it will calculate the cost for the parked time. I created a class named Key which creates the object it self with the exit time as None, but my trouble begins by trying to update the self.exit which doesn't work out for me using the the function exit_time. Every time a car enters the data is written to a file using pickle, i tried using a list to be able to edit the object but something isn't working out for me.
Also I tried many varieties by calling the function or what happens in the function it self.
THIS IS MY MAIN
list_of_cars = []
while True:
startmessage() # prints message
choice() # prints message
action = input("\nYour choice: ")
if action == "1":
choice_one() # prints message
car_number = input(" here: ")
new_client = Key(car_number)
list_of_cars.append(new_client)
writing_file(list_of_cars)
reading_file()
if action == "2":
choice_two() # prints message
exit_key = input(" here: ")
Key(exit_key).exit_time(exit_key)
READ AND WRITE
def reading_file():
with open("parking.data", "rb") as readfile:
list_of_cars = pickle.load(readfile)
print("testing", [str(x) for x in list_of_cars])
readfile.close()
return list_of_cars
def writing_file(list_of_cars):
with open("parking.data", "wb") as myfile:
pickle.dump(list_of_cars, myfile)
myfile.close()
return list_of_cars
THE CLASS
import random
import pickle
import datetime as dt
class Key:
def __init__(self, car_number):
self.car_number = car_number
self.key = self.generate()
self.enter = self.enter_time()
self.exit = None
"""
creates the key it self and while creating it checks if it already exists so that there will be no duplicates
"""
def generate(self):
key = ""
chunk = ""
alphabet = "ABCDEFGHIJKLMNOPQRZTUVWXYZ1234567890"
while True:
while len(key) < 8:
char = random.choice(alphabet)
key += char
chunk += char
if len(chunk) == 3:
key += "-"
chunk = ""
key = key[:-1]
with open("parking.data", "rb") as readfile:
new_list = pickle.load(readfile)
if key in new_list:
key = ""
else:
return key
def __str__(self):
return f"{self.car_number},{self.key}," \
f"{self.enter},{self.exit}"
def enter_time(self):
start = str(dt.datetime.now().strftime('%H:%M:%S'))
return start
def exit_time(self, exit_key):
from read_and_write import reading_file
list_of_cars = reading_file()
if exit_key in list_of_cars:
self.exit = str(dt.datetime.now().strftime('%H:%M:%S'))
print("IT WORKED!!!")
print("got to the function :/")
your conditional is:
if exit_key in list_of_cars:
exit_key is OM7-XVX
list_of_cars is ['5412,OM7-XVX,21:09:42,None1',...]
So...
'OM7-XVX' in ['5412,OM7-XVX,21:09:42,None1'] -> False
'OM7-XVX' in ['5412,OM7-XVX,21:09:42,None1'][0] -> True
Therefore replace the conditional with
if any(exit_key in v for v in list_of_cars):

Loop in a class and writing to a txt file

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 :)

File Access in python

Whenever I go to load a text file for my program it displays the info in the text file yet when I input the roster function it does not display the text file and show it is available to be modified. Is it something with how I created the text file in the first place or is my coding for loadData not written correctly i think i may be confused on the difference between just setting up a function just to read back the file instead of actually opening the text file to be able to modify it.
dict_member = {}
players = dict_member
class Players:
def __init__(self, name, number, jersey):
self.name = name
self.number = number
self.jersey = jersey
def display(self):
print('Printing current members\n')
for number, player in dict_member.items():
print(player.name + ', ' + player.number + ', ' + player.jersey)
def add(self):
nam = input("Enter Player Name\n ")
numb = input("Enter Player Number\n ")
jers = input("Enter Jersey Number\n ")
dict_member[nam] = Players(nam, numb, jers)
def remove(self, name):
if name in dict_member:
del dict_member[name]
def edit(self, name):
if name in dict_member:
nam = input("Enter Different Name\n")
num = input("Enter New Number\n ")
jers = input("Enter New Jersey Number\n ")
del dict_member[name]
dict_member[name] = Players(nam, num, jers)
else:
print("No such player exists")
def saveData(self):
roster = input("Filename to save: ")
print("Saving data...")
with open(roster, "r+") as rstr:
for number, player in dict_member.items():
rstr.write(player.name + ', ' + player.number + ', ' + player.jersey)
print("Data saved.")
rstr.close()
def loadData(self):
dict_member = {}
roster = input("Filename to load: ")
file = open(roster, "r")
while True:
inLine = file.readline()
if not inLine:
'break'
inLine = inLine[:-1]
name, number, jersey = inLine.split(",")
dict_member[name] = (name, number, jersey)
print("Data Loaded Successfully.")
file.close()
return dict_member
def display_menu():
print("")
print("1. Roster ")
print("2. Add")
print("3. Remove ")
print("4. Edit ")
print("5. Save")
print("6. Load")
print("9. Exit ")
print("")
return int(input("Selection> "))
print("Welcome to the Team Manager")
player_instance = Players(None, None, None)
menu_item = display_menu()
while menu_item != 9:
if menu_item == 1:
player_instance.display()
elif menu_item == 2:
player_instance.add()
elif menu_item == 3:
m = input("Enter Player to Remove\n")
player_instance.remove(m)
elif menu_item == 4:
m = input("Enter Player to Edit\n")
player_instance.edit(m)
elif menu_item == 5:
player_instance.saveData()
elif menu_item == 6:
player_instance.loadData()
menu_item = display_menu()
print("Exiting Program...")
Try this:
def loadData(self):
file = open(input("Filename to load: "), "r")
text = file.read()
file.close()
for line in text:
name, number, jersey = (line.rstrip()).split(',')
dict_member[name] = (name, number, jersey)
print("Data Loaded Successfully.")
return dict_member
def saveData(self, dict_member):
file = open(input("Filename to save: "), "a")
for number, player in dict_member.items():
rstr.write(player.name + ', ' + player.number + ', ' + player.jersey)
print("Data saved.")
file.close()
What I think was the error was you using "break" in string from instead of the command, break (no quotes required). I optimized the code a little so maybe it will work now? If not, what exactly happens? Try debugging as well as checking your file.
you didnt load your data into dict_member before displaying the roster
when you load your data in the loadData function you redefine dict_member
so it will "shadow" the outer dict_member so when the display function is called dict_member will always be empty
so you probably want to remove this line
def loadData(self):
# **remove this line --->** dict_member = {}
roster = input("Filename to load: ")
file = open(roster, "r")
while True:
inLine = file.readline()
if not inLine:
break
inLine = inLine[:-1]
name, number, jersey = inLine.split(",")
dict_member[name] = (name, number, jersey)
print("Data Loaded Successfully.")
file.close()
return dict_member

Problems with pickling data

import random
import pickle, shelve
import os
#import RPi.GPIO as GPIO | Raspberry pi only
import tkinter
import sys
import time
class Operator(object):
global list_name
def __init__(self):
print("Welcome to Python OS 1.0")
print("type 'help' to access help...") # ADD CODE OS.REMOVE("FILE")
def CheckDetails(self):
if not os.path.isfile( 'details.dat' ) :
data=[0]
data[0] = input('Enter Your Name: ' )
file= open( 'details.dat' , 'wb' )
pickle.dump( data , file )
file.close()
else :
File = open( 'details.dat' , 'rb' )
data = pickle.load( File )
file.close()
user = ""
while user != data[0]:
input("please enter your username...")
print( 'Welcome Back To Python OS, '+ data[0])
def Help(self):
print("""
write(sentence) - Prints the typed sentence on the screen
open(file, mode) - Opens the file and mode such as 'r'
create(listName) - creates the list, listName
add(data, listName) - adds the data to listName
remove(data, listName) - removes the selected data from listName
""")
def write(self, sentence):
print(sentence)
#classmethod
def create(self):
list_name = input("Please enter the list name...")
vars()[list_name] = []
time.sleep(1)
print("List (" + list_name + ") created")
def add(self):
data = input("Please specify the data to be added...")
list_name += data
def remove(self, data, list_name):
remove_data = input("Plese specify the data to be removed...")
list_name -= data
def main():
os = Operator()
os.CheckDetails()
ans = ""
ans = ans.lower()
while ans != "quit":
ans = input()
if ans == "write":
os.write()
elif ans == "help":
os.Help()
elif ans == "create":
os.create()
elif ans == "add":
os.add()
elif ans == "remove":
os.remove()
elif ans == "quit":
break
else:
print("Sorry, that command does not exist or it will be added into a future update...")
print("goodbye...")
main()
I am trying to make some sort of simplified python, but hitting errors only on the CheckDetails() function. I'm pickling data (which is fine) but getting errors when making the user check his or her username is correct, I've tested it and even though I have typed in the correct username, it carry's on asking for my username. Can anyone please help?
You have a while loop that will execute forever because you are not assigning your user variable to anything.
while user != data[0]:
user = input("please enter your username...")
print( 'Welcome Back To Python OS, '+ data[0])

Categories

Resources