Wednesday, May 20, 2009

HWSched

I've been working on a new program: a homework scheduler suitable for high school and college students. Right now, it has the following objects that can be added, deleted, etc.:

  • Quarters/Terms
  • Instructors
  • Classes (each has a Quarter and Instructor)
  • Additional Class Sections (for each class)
  • Exams (for each class)
  • Assignments and their respective parts (for each class)

To add an assignment, all one needs to do is specify a class, due date, and all of its parts. I had previously written something similar, but it wasn't as efficient as this system.

I'll put it up here when I've tested it enough.

Thursday, May 7, 2009

cwork.py

I finally realized that the time I spent figuring out the path do a directory I wanted to go to via tab-completion was being wasted! I've created an alternative method for oft-accessed directories:

cwork.py

#!/usr/bin/python
from sys import argv, stderr, exit
from subprocess import Popen
from os import chdir, environ, getcwd
from os.path import join
from sqlite3 import Connection, IntegrityError
from datetime import datetime


class Sdatetime(datetime):
def strftime(self, fmt = None):
return datetime.strftime(self, '%Y-%m-%d %H:%M:%S.%f' if fmt is None else fmt)
@staticmethod
def strptime(string, fmt = None):
return datetime.strptime(string, '%Y-%m-%d %H:%M:%S.%f' if fmt is None else fmt)

def cdzsh(dir):
chdir(path)
Popen(('screen', 'zsh'))

def getrows_ordered(db):
c = db.cursor()
ret = {}
for row in c.execute('SELECT id, added, path FROM Paths'):
id, now, path = row
ret[Sdatetime.strptime(now)] = id, path
keys = ret.keys()
keys.sort(reverse = True)
for i in xrange(len(keys)):
key = keys[i]
id, value = ret[key]
yield i, id, key, value

db = Connection(join(environ['HOME'], '.path.db'))
db.execute('CREATE TABLE IF NOT EXISTS Paths(id INTEGER PRIMARY KEY AUTOINCREMENT, added CHAR(48), path VARCHAR(255) UNIQUE)')
db.commit()

if len(argv) >= 2:
if len(argv) >= 2 and argv[1] == 'add':
c = db.cursor()
path = getcwd()
if len(argv) >= 3:
path = argv[2]
now = Sdatetime.now()

try:
c.execute('INSERT INTO Paths(added, path) VALUES(?, ?)', (now.strftime(), path))
db.commit()
except IntegrityError:
print >>stderr, 'Path already in database:', path
elif len(argv) >= 2 and argv[1] == 'del':
c = db.cursor()
ids = set([int(arg) for arg in argv[2:]])
rows = list(getrows_ordered(db))
for id in ids:
try:
c.execute('DELETE FROM Paths WHERE id = ?', (rows[id][1],))
db.commit()
except IndexError:
print >>stderr, 'Invalid index:', id
elif len(argv) >= 2 and argv[1] == 'delall':
c = db.cursor()
c.execute('DELETE FROM Paths')
db.commit()
elif len(argv) >= 2:
c = db.cursor()
ids = [int(arg) for arg in argv[1:]]
rows = list(getrows_ordered(db))
for id in ids:
row = rows[id]
now = Sdatetime.now()
c.execute('UPDATE PATHS SET added = ? WHERE id = ?', (now.strftime(), row[1]))
path = rows[id][3]
cdzsh(path)
db.commit()
else:
print >>stderr, 'Usage: %s [ [ path# | add [ path ] | del path# | delall ] ]' % argv[0]
exit(1)
else:
for i, id, key, value in getrows_ordered(db):
print '%d:' % i, value
This script is essentially a cache for directories that the user wants to keep accessing often, and reorders the entries by date every time:Programs % cwork
0: /home/neil/Programs/CSE444/2009-05-07:Project3
1: /home/neil/Programs/CSE481
Programs % cwork add
Programs % cwork
0: /home/neil/Programs
1: /home/neil/Programs/CSE444/2009-05-07:Project3
2: /home/neil/Programs/CSE481
Programs % cwork 0

The last command opens up a new GNU Screen window with a shell in the directory requested.