I'm working on this project in python where I'm trying to code a system that allows the user to book, cancel, print train tickets and also save everything they've done to a separate file that the program reads every time it opens and the re-saves it with the new information when it is closed. I'm stuck because I don't know what to do next, I've defined a class for reservations and also some methods within the class. I'll eventually attempt to code a GUI, where the user just clicks on the button with the seat number they want to order to book it and so on. Here's what I've done so far, I'm a new programmer so please be kind, I need suggestions on what I should do next, I'm I on the right track or do I need to code in another way? Here's what I've done so far:
class Reservation:
def __init__ (self, seatCol, seatRow, department, destination, departure, price):
self.__seatCol = seatCol
self.__seatRow = seatRow
self.__departement = departement
self.__destination = destination
self.__departure = departure
self.__price = price
def selectDeparture(departure):
#Asks the user to pick a departure
def selectDestination(destination):
#Asks the user to pick a destination
def selectSeat(seatCol, seatRow, department):
#Asks the user to pick a seat and checks if it's already booked
def ticketPrice (price):
def printBookedTicket:
If you are dead set on using classes for this project, make sure to follow a good tutorial on Python OOP programming.
However, I recommend learning some Python fundamentals before tackling OOP stuff.
If I was going to make this program, I would put all my data in a dictionary and make functions that could do all my editing of the data. Once you get this, if you feel like wrapping a class around it, you could.
Start with a simple command line interface to manipulating your data, something like:
ticket_booker.py add John Smith
>> Departure : ?
>> Destination: ?
>> (etc).
Related
I'm making a text-based game, which is based largely in if-, elif- and else-statements. However, I also use while loops for different "areas" within the game. (Play_loop, Main_loop, Shop_loop, Fish_loop, etc.).
Lately I've implemented admin commands which I use in-game to change things on the go, and I want these to be available in every loop. I also have some general commands which I want to be available (help, leave, quit, logout, go to another area, check inventory, etc.).
The issue I'm facing is knowing that duplicated code should be avoided, but i'm wondering if this is necessary in this situation. I've already made many functions to make each command code pretty short, about 2-15 lines in general.
Should I add the code blocks into functions that do the same thing, and then just repeat the function, or should I just keep it as is? Or maybe I should do something else that I havent even thought about?
Example code:
elif command == '/user info':
if user.admin:
print(f'User-list: {users}')
who = input('Name of user: ').strip()
who_user = admin_load_user(who, users)
if who_user:
print(who_user.info())
print(who_user.display_inv())
else:
print(DNEError)
else:
print(PError)
elif command == '/add coins':
who = input('Who gets coins? ').strip()
amount = int(input('How much? ').strip())
admin_add_coins(who, amount, users)
save_users(users)
Code that is repeated should typically be put into functions, so that you have better overview and control over what they are doing. There you can also easily give them default arguments and expand on the code without bloating the main function of your program.
Here is a concise argument for using functions. It's written for C but applies to python as well.
Then, as Jason Chia pointed out, you should consider thinking about building your game into classes, as they solve some of the problems you mentioned and generally are an important control instrument for bigger programs where you need to coordinate different states (e.g. changing something in a room based on the player's actions).
This tutorial could help with that.
Does that about answer your question?
You should use decorator style to do it nice to read and write.
get inspiration here:
def requires_admin(f):
def wrapper(f):
#wraps(f)
def wrapped(*args, **kwargs):
#if not admin:
#return render_template('error.html')
return f(*args, **kwargs)
return wrapped
return wrapper
#app.route('/admin/action')
#requires_admin
def AdminAction():
whatyouwant()
For some days I've been breaking my head over some issues I'm having with a Win32Com Excel object in python.
What I'm trying to do is very simple; get the sheet names from a workbook and write a value to the bottom of a column. The workbook is often opened by the users and needs to remain accessible/editable, hence I decided to use Win32Com. Any other suggestions to achieve the same are very welcome as well.
The base-code is quite straightforward:
class excelCOM():
def __init__(self, file):
self.xl = win32com.client.gencache.EnsureDispatch('Excel.Application')
self.wb = self.xl.Workbooks(os.path.basename(file))
def getSheets(self):
return [s.Name for s in self.wb.Sheets]
def dataToCell(self, sheet, column, string):
sht = self.wb.Sheets(sheet)
maxLastCell = sht.Range('{}{}'.format(column, 1048576))
lastCell = maxLastCell.End(win32com.client.constants.xlUp)
lastCell.Offset(2, 1).Value = string
Issues occur when integrated with the rest of the software. I've gone through lots of documentation and trying different things but I've been unable to get a reliable result. I'll try my best to summarize what I've tried and what the observations were.
When I create a single instance of this class and run the methods, everything works as expected.
if __name__ == '__main__':
xlWb = excelCOM(r"TestBook.xlsx")
print(xlWb.getSheets())
xlWb.dataToCell("Sheet1", 'B', 'All Good')
The information to write to the excel file comes from a logfile that is being written to by another (external) program. My software monitors the file and writes to excel whenever there is a new line added. All of this is handled by the 'processor'. The formatting for the text that's written to excel is user defined. Those formatting settings (and others) are imported to the processor from a pickled (settings) object (allowing the user to save settings (using a GUI) and run the processor without needing the GUI). As code (extremely simplified, just to get the idea across):
class processor():
def __init__(self, settings_object):
self.com_object = excelCOM(settings_object.excel_filepath)
self.file_monitor(settings_object.input_filepath)
self.file_monitor.start()
def dispatch():
# called whenever file_monitor registers a change to the file at input_filepath
last_line = self.get_last_line(input_filepath)
sheet, column, formatted_text = self.process(last_line)
self.com_object.dataToCell(sheet, column, formatted_text)
Now, when text is supposed to be written to the excel file by the processor, I get Exception in thread Thread-1: pywintypes.com_error: (-2147221008, 'CoInitialize has not been called.', None, None) at sht = self.wb.Sheets(sheet)
When I call CoInitialize() before sht = self.wb.Sheets(sheet) I get Exception in thread Thread-1: pywintypes.com_error: (-2147417842, 'The application called an interface that was marshalled for a different thread.', None, None). Calling CoInitialize() anywhere else in the code doesn't seem to do anything.
Adding the same code as in init solves the issue from point 3, but this seems very wrong to me. Mainly because I don't exactly know why it fixes the issue and what's going on in the background with com objects in windows.
def dataToCell(self, sheet, column, string):
pythoncom.CoInitialize() # point 3.
self.xl = win32com.client.gencache.EnsureDispatch('Excel.Application') # point 4.
self.wb = self.xl.Workbooks(os.path.basename(self.file)) # point 4.
sht = self.wb.Sheets(sheet)
maxLastCell = sht.Range('{}{}'.format(column, 1048576))
lastCell = maxLastCell.End(win32com.client.constants.xlUp)
lastCell.Offset(2, 1).Value = string
Now switching to the GUI. As mentioned earlier, the settings file for the processor is created with help from a GUI. It basically gives the functionally to build the settings_object. In the GUI I also have a 'run' button which directly calls processor(settings_object) in a seperate Thread. When I do this, I don't even need to add the additional lines as described in point 3 and 4. It runs perfectly with just the base-code.
I've gone through dozens of pages of documentation, StackOverflow topics, tutorials, blogs hidden in the dark corners of the web, Python Programming on Win32 but I simply can't wrap my head around what's going on. I consider myself a half-decent programmer for 'get the job done' applications but I don't have any education in computer science (or even programming in general), which is what I suspect I'm lacking at the moment.
I'm hoping someone can point me in the right direction for understanding this behavior and maybe give some advice on the proper way of implementing this functionality for my scenario.
Please let me know if you require any more information.
Best regards and many thanks in advance,
RiVer
I am facing challenges implementing OOP in python to enable me to call the functions whenever i want , so far i have no syntax errors which makes quite challenging for me . The first part of the code runs ehich is to accept data but the function part does not run.
I have tried different ways of calling the function by creating an instance of it.
print (list)
def tempcheck(self,newList):
temp=newList[0]
if temp==27:
print ("Bedroom has ideal temperature ")
elif temp>=28 or temp<=26:
print ("Bedroom Temperature is not ideal ,either too low or too cold. ")
print ("Please to adjust the temperature to the optimum temperature which is 27 degree Celsuis")
# now to initialize args
def __init__(self,temp,puri1,bedwashroom,newList):
self.temp=temp
self.puri1=puri1
self.bedwashroom=bedwashroom
tempcheck(newList)
# now calling the functions
newvalue=tempcheck(list)
# where list contains the values from the input function.
I expected the function to to check the specific value at the location in the list provided which is called list and also for the function to return a string based on the if statements.
i got it right ,i figured out an alternative to my bug thanks for the critique however any further addition is welcome,
the main goal was to create a function that takes input and passes it to list to be used later i guess this code is less cumbersome
the link to the full code is pasted below
I am trying to use VLC player, controlled by Python (vlc.py bindings), as a media player on my Pi. I create a MediaList and it starts to play, so far so good.
I need to get the current item postion to save it in a db, so I can go back to the last played track when I restart the MediaList after a reboot or similar.
It's running on my Raspberry 3b+ with newest Raspbian and Python 3.5.
import vlc
mrl1 = '....1.3gp'
mrl2 = '....2.3gp'
Instance = vlc.Instance('--input-repeat=-1', '--fullscreen', '--mouse-hide-timeout=0')
MediaList = Instance.media_list_new()
MediaList.add_media(Instance.media_new(mrl2))
MediaList.add_media(Instance.media_new(mrl1))
list_player = Instance.media_list_player_new()
list_player.set_media_list(MediaList)
list_player.next()
This is a raw piece of code of what I am trying, but it plays my songs one by one. I want to be able to print the current playing filename or the position in the media list to save it.
You will want to use events to be notified when the currently playing media changes. You might have to experiment with a couple options to see which is the most reliable when using a media list
One option is the MediaListPlayerNextItemSet event
def listPlayerCallback(event):
print "listPlayerCallback:", event.type, event.u
list_player_events = list_player.event_manager()
list_player_events.event_attach(EventType.MediaListPlayerNextItemSet, listPlayerCallback)
The event passed in response to MediaListPlayerNextItemSet contains a Media item
event.u.media
Depending on your media, you might be able to pull meta data from it using the get_meta method
event.u.media.get_meta(0)
(There is an enumeration of meta data; 0 is the Title)
Alternatively, you might have better luck with the MediaPlayerMediaChanged event
media_player_events = mp.event_manager()
media_player_events.event_attach(EventType.MediaPlayerMediaChanged, listPlayerCallback)
The event data for that event is the same as above.
If pulling the meta data doesn't work, you might be able to do a straight comparison against the items in your list and then use that to index into a saved list of media filenames.
The other answer gives a hint on how to do it, but does not actually work. Since the edit queue is full, I will post a new answer.
The actual event is 'MediaListPlayerNextItemSet'.
media_player_events = media_list_player.event_manager()
media_player_events.event_attach(vlc.EventType.MediaListPlayerNextItemSet, lambda _: print("x"))
I'm coding a text game in python 3.4 and when I though about making a save game came the question:
How can I jump to the place that the player stopped?
I'm making a simple game, me and my friends, so I just wanna jump to a certain part of the code, and I can't do that without having to make around 15 copies of the code, so can I jump to a line?
You can do that using something like python-goto but this is a very bad idea.
In python, you don't have really any reason to do a goto.
A way better way would be to save the structure containing your data with something like pickle and loading it back when the user want to restart the game.
For instance:
import pickle
game_data = {'something': [1, 2, 3 ]}
pickle.dump(game_data, open('file.bin', 'wb')
Then, you can load the data back:
import pickle
game_data = pickle.load(open('file.bin', 'rb'))
There is no goto built into Python. There are ways to effectively 'halt' in a method by using yield and creating a generator, which is effectively how Python coroutines work (see the asyncio module) however this isn't really appropriate for your needs.
For saving game state, saving and serialising the state you need to resume the gameplay in a more general way is a much better idea. You could use pickle For this serialisation.
You need to consider the game-state as something that you can assign a value (or values) to. If this is a very simple text game, then the player will have a location, and that location will presumably be something you can "jump" to via use of a reference.
Let's say your code follows this pseudo-code pattern:
start
player_location = 0
print_start_game_text()
begin loop:
display_text_for_location[player_location]
display_options_for_location[player_location]
player_location = parse_player_response(response_options_for_location[player_location])
if isGameEndCondition(player_location):
break;
print_end_game_text()
end
This pattern would reference some data files that, for each location provided some collection such as 1, "you are in a room, doors are [E]ast and [W]est. You can [S]ave your game, or [L]oad a previously saved one", { "E" : 3, "W" : 2, "S" : "savegame", "L" : "loadgame" }
Then using a function to display some options, collecting the users response and parsing that data, returning a single value; the next location. You then have a new key to reference the next element in the data-file.
IF your game is as simple as this, then your save file need only contain a single reference, the player's location! Simple.
If you have objects that the player can manipulate, then you'll need to figure out a way to keep track of those, their locations, or state-values - it all depends on what your game does, and how it's played.
You should be thinking along these program vs data lines though, as it will make the game much easier to design, and later, extend, since all you'd have to do to create a new adventure, or level, is provide a new datafile.