Im having trouble editing an object in OOP in my project - python

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

Related

this program checks whether it is in the file text.txt that the user has received

If I remove these lines of code:
else:
print("Boş")
break
Then, the program seems to work fine, but when I add it again, the program does not find any words in the text.txt and throw a Not found exception.
Here is the full code:
class x():
def __init__(self):
with open('metin.txt', 'r', encoding="utf-8")as file:
icerik = file.read()
icerik = icerik.split()
self.sade_kelime = []
self.sozluk = dict()
file.seek(0)
for i in icerik:
i = i.strip(".")
i = i.strip(",")
i = i.strip("")
self.sade_kelime.append(i)
for i in self.sade_kelime:
if i in self.sozluk:
self.sozluk[i] += 1
else:
self.sozluk[i] = 1
def kelime_frekans(self):
for i in self.sozluk:
if i == kelime:
print(kelime, self.sozluk[i], "kez metinde geciyor")
else:
print("Boş")
break
dosya = x()
while True:
kelime = input('kelime:')
if kelime == "q":
break
else:
dosya.kelime_frekans()
if i == kelime condition is not satisfy on first iteration, loop will break.
Logically this is not a correct code. Your kelime_frekans function should be like this:
def kelime_frekans(self):
for i in self.sozluk:
if i == kelime:
print(kelime, self.sozluk[i], "kez metinde geciyor")
return
print("Boş")

Terminate multi-line key, value inputs to a dictionary by a user defined keyword

I am having issues with breaking from a multi-line addition to a dictionary. The task requires adding multiple lines of Product,Quantity inputs into a 'Cart' dictionary. The addition to dictionary should stop by a keyword 'show' or something similar which results in printing added elements of the dictionary. I have been able to initiate multi-line inputs to the cart dictionary but can't get the addition to stop by 'show' keyword.
Here's a portion of my code for reference:
class cart():
pcart = {}
def __init__(self,name):
self.name = name
def Show_Cart(self):
print(self.pcart)
def Add_Item(self):
print('Adding your items and quantities')
p,q = input().rpartition(' ')[::2]
while q.lower() != 'show':
self.pcart[p] = q
if q.lower() == 'show':
self.Show_Cart()
My_Cart = cart(input('Name of your cart:'))
print('Choose from the following options:')
status = int(input('1:Add Item 2:Remove Item'))
if status == 1:
My_Cart.Add_Item()
EDIT-
As pointed out by #andrew_reece , the code above wouldnt get to Show_Cart function ever. I then tweaked it a bit and used While True condition to loop over the function operation and use an Else condition to break when 'Show' keyword appears. Here's my final code-
class cart():
pcart = {}
def __init__(self,name):
self.name = name
def Show_Cart(self):
print(self.pcart)
Main()
def Add_Item(self):
print('Adding your items and quantities')
while True:
p,q = input().rpartition(' ')[::2]
if q.lower() != 'show':
self.pcart[p] = q
else:
self.Show_Cart()
break
def Remove_Item(self):
print('Your cart contents are :' ,self.pcart)
print('What all do you want to remove?')
while True:
p = input()
if p.lower() != 'show':
del self.pcart[p]
else:
self.Show_Cart()
break
def Main():
status = int(input('1:Add Item 2:Remove Item'))
if status == 1:
My_Cart.Add_Item()
elif status == 2:
My_Cart.Remove_Item()
My_Cart = cart(input('Name of your cart:'))
print('Choose from the following options:')
Main()
The code now works. However I am still wondering if using While True is a pythonic way to do things?

Object Does Not Support Indexing

I'm creating a work log in python where a user can enter a task or can lookup a task by date. My initial prompt asks user to either enter a task or lookup by date. If the user starts by looking up by date--the program works correctly and displays all dates. If a user starts by adding a task, and then looking up tasks by date, the program displays an 'object does not support indexing error'. I think for some reason, the list is getting emptied, but i can't for the life of me understand where or when this might be happening. Here is main worklog file:
import csv
import re
import datetime
from task import Task
from task_list import TaskList
class Worklog():
def __init__(self):
self.filename = "work_log.csv"
self.tasklist = TaskList()
self.tasklist.read_task_from_file(self.filename)
def search_by_date(self):
for d, i in enumerate(self.tasklist.dates()):
print(d+1, ':', i)
# while True:
# datereq = input("Select Number To See Tasks For A Date").strip().lower()
# try:
# datereq = int(datereq)
# return datereq
# except ValueError:
# print("Invalid Entry. Please try again")
# continue
def search_by_time(self):
pass
def exact_search(self):
pass
def pattern_search(self):
pass
def add_task(self):
task = Task()
task.input_task()
task.input_minutes()
task.input_notes()
task.date = datetime.date.today()
self.tasklist.app_task(task)
self.tasklist.save_task_to_file(self.filename,task)
def lookup_task(self):
if len(self.tasklist.task_list) == 0:
print("Your task log is empty.\n")
input("Hit Enter to add a new task.")
else:
while True:
lookup = input("Lookup by Date(D), Time(T), Exact Search(E) or Pattern(P): ")
lookup.lower()
if lookup == 'd':
self.search_by_date()
break
elif lookup == 't':
self.search_by_time()
break
elif lookup == 'e':
self.exact_search()
break
elif lookup == 'p':
self.pattern_search()
break
else:
print("Sorry invalid option. Please try again")
def start_message(self):
while True:
q = input("Add New Task(1) or Lookup Task(2) or Quit(3): ".strip().lower())
if q == "1":
self.add_task()
elif q == "2":
self.lookup_task()
elif q == "3":
exit()
else:
print("Sorry that's an invalid entry. Please try again.")
continue
if __name__ == '__main__':
log = Worklog()
log.start_message()
The error is pointing to the dates function which is shown below along with a few of the other methods for my 'task-list' class. Is there an issue with the way that I am indexing this list? Or am i right in that the task_list list is getting reset somehow when the user enters the second step of the loop. Thanks:
def app_task(self, task):
self.task_list.append(task)
def save_task_to_file(self,filename,task):
with open(filename, 'a', newline="\n", encoding="utf-8") as csvfile:
# creating a csv writer object
csvwriter = csv.writer(csvfile, delimiter=",")
# writing the data rows
csvwriter.writerow([task.date, task.task, task.minutes, task.notes])
def read_task_from_file(self,filename):
with open(filename, 'r') as csvfile:
task_reader = csv.reader(csvfile, delimiter=',')
for row in task_reader:
task = Task()
self.task_list.append(row)
return self.task_list
def dates(self):
self.read_task_from_file("work_log.csv")
dates = []
for row in self.task_list:
date = row[0]
if row[0] not in dates:
dates.append(date)
return sorted(dates)
Note--here is an example of what the work_log.csv file looks like:
2017-03-23,gardening,30,not really
2017-03-23,bowling,30,none
2017-03-23,bowling,90,none
2017-03-23,bowling,93,none
2017-03-23,baseball,2,none
2017-03-23,bowling,20,none
2017-03-23,base,0,jj
2017-03-23,bowling,33,none
Added per Jake's recommendation:
def get_date(self):
for row in self.task_list:
d = row[0]
return d
def dates(self):
dates = []
for row in dates:
date = row.get_date()
if date not in dates:
dates.append(date)
return sorted(dates)
The issue appears to be where you call date = row[0]; this is because in the loop row will be a Task object as you are iterating over self.task_list. In this case you are trying to index into a Task object, which is not set up for indexing.
The simple solution for this would be to replace row[0] with row.date; which will directly access the date field of the row object, without needing to bother about indexing at all.

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

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