Created
August 6, 2013 06:03
-
-
Save wgx731/6162396 to your computer and use it in GitHub Desktop.
Simple script for my PyconSG 2013 ticket application
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
#ticket.py -- Application for pyconsg ticket. | |
#Author: wgx731 | |
#Adopted from life.py | |
# | |
#An empty board will be displayed, and the following commands are available: | |
# E : Erase the board | |
# S : Show the application | |
# C : Credit | |
# Q : Quit | |
import random, string, traceback, itertools | |
import curses | |
STATE_LIST = [ | |
'Reason: I graduate from Republic Polytechnic and pyconsg is held in RP.', | |
'Reason: I like python and enjoy writing pythonic code.', | |
'Reason: Life is short we must use python.', | |
'Reason: I have participated in Pycon Asia 2011 as well as been a helper for Pycon Asia 2012.', | |
'Reason: I want to see the new threading of python in Singapore.', | |
'Promise: A presentation to share what I have learnt in pyconsg.', | |
'Promise: Help others by sharing what I know about python on orbital askbot forum.', | |
] | |
CREDIT = [ | |
'Made By wgx731', | |
'Used python 2.7.5 (random, string, traceback, itertools, curses)', | |
'Special Thanks to python', | |
] | |
SLEEP_TIME = 1500 | |
class TicketBoard: | |
"""Encapsulates a board | |
Attributes: | |
X,Y : horizontal and vertical size of the board | |
state : current string on the screen | |
Methods: | |
display(update_board) -- refresh the screen and show the new state. | |
erase() -- clear the entire board | |
get_next() -- set new string; doesn't refresh the screen | |
""" | |
def __init__(self, scr): | |
"""Create a new Board instance. | |
scr -- curses screen object to use for display | |
""" | |
self.state_list = list(STATE_LIST) | |
random.shuffle(self.state_list) | |
self.states = itertools.cycle(self.state_list) | |
self.scr = scr | |
Y, X = self.scr.getmaxyx() | |
self.X, self.Y = X-2, Y-2-1 | |
self.clear() | |
def clear(self): | |
self.scr.clear() | |
# Draw a border around the board | |
border_line = '+'+(self.X*'-')+'+' | |
self.scr.addstr(0, 0, border_line) | |
self.scr.addstr(self.Y+1,0, border_line) | |
for y in range(0, self.Y): | |
self.scr.addstr(1+y, 0, '|') | |
self.scr.addstr(1+y, self.X+1, '|') | |
self.state = 'wgx731 application for pyconsg ticket' | |
self.scr.addstr(5,55,self.state) | |
self.scr.refresh() | |
def get_next(self, x, y, clear=False): | |
"""Set a cell to the live state""" | |
if x<0 or self.X<=x or y<0 or self.Y<=y: | |
raise ValueError, "Coordinates out of range %i,%i, max: %i, %i"% (x,y, self.X,self.Y) | |
if clear: | |
self.clear() | |
return | |
self.state = self.states.next() | |
self.scr.addstr(x,y,self.state) | |
def erase(self): | |
"""Clear the entire board and update the board display""" | |
self.display(update_board=False) | |
def display(self, update_board=True): | |
"""Display the whole board with new string""" | |
if not update_board: | |
self.get_next(0,0,True) | |
self.scr.refresh() | |
return | |
self.get_next(random.randint(17,25),random.randint(6,15)) | |
self.scr.refresh() | |
def erase_menu(stdscr, menu_y): | |
"Clear the space where the menu resides" | |
stdscr.move(menu_y, 0) | |
stdscr.clrtoeol() | |
stdscr.move(menu_y+1, 0) | |
stdscr.clrtoeol() | |
def display_menu(stdscr, menu_y): | |
"Display the menu of possible keystroke commands" | |
erase_menu(stdscr, menu_y) | |
stdscr.addstr(menu_y+1, 4, | |
'E)rase the board, C)redit, S)how the application or Q)uit') | |
def keyloop(stdscr): | |
# Clear the screen and display the menu of keys | |
stdscr.clear() | |
stdscr_y, stdscr_x = stdscr.getmaxyx() | |
menu_y = (stdscr_y-3)-1 | |
display_menu(stdscr, menu_y) | |
# Allocate a subwindow for the Life board and create the board object | |
subwin = stdscr.subwin(stdscr_y-3, stdscr_x, 0, 0) | |
board = TicketBoard(subwin) | |
board.display(update_board=False) | |
# xpos, ypos are the cursor's position | |
xpos, ypos = board.X//2, board.Y//2 | |
# Main loop: | |
while (1): | |
c = stdscr.getch() # Get a keystroke | |
if 0<c<256: | |
c = chr(c) | |
if c in ' Qq': | |
break | |
elif c in 'Ee': | |
board.erase() | |
elif c in 'Ss': | |
stdscr.nodelay(1) | |
while (1): | |
c = stdscr.getch() | |
if c != -1: | |
break | |
board.erase() | |
erase_menu(stdscr, menu_y) | |
stdscr.addstr(menu_y, 6, 'Application, hit any key to quit to main screen.') | |
stdscr.refresh() | |
for i, r in enumerate(STATE_LIST): | |
stdscr.addstr(8+i,10,r) | |
board.display() | |
stdscr.timeout(SLEEP_TIME) | |
stdscr.nodelay(0) # Disable nodelay mode | |
board.erase() | |
display_menu(stdscr, menu_y) | |
elif c in 'Cc': | |
stdscr.nodelay(1) | |
credits = itertools.cycle(CREDIT) | |
current = 0 | |
while (1): | |
c = stdscr.getch() | |
if c != -1: | |
break | |
board.erase() | |
erase_menu(stdscr, menu_y) | |
stdscr.addstr(menu_y, 6, 'Credit, hit any key to quit to main screen.') | |
stdscr.refresh() | |
if (current >= 50): | |
current = 10 | |
else: | |
current += 10 | |
stdscr.addstr(20,current,credits.next()) | |
stdscr.timeout(SLEEP_TIME) | |
stdscr.nodelay(0) # Disable nodelay mode | |
board.erase() | |
display_menu(stdscr, menu_y) | |
else: | |
pass # Ignore incorrect keys | |
else: | |
# Ignore incorrect keys | |
pass | |
def main(stdscr): | |
keyloop(stdscr) # Enter the main loop | |
if __name__ == '__main__': | |
curses.wrapper(main) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment