Nie napisałem, że w Pythonie się bardziej myśli, tylko łatwiej się myśli (łatwiej przetłumaczyć sobie myśli na kod pythona).
Teraz tutaj Model drzewka jaki sobie ostatni stworzyłem:
Kod
from sqlobject import *
from connection import *
from string import join
from exceptions import KeyError
class Node(SQLObject):
name = StringCol(length=100)
parent = ForeignKey('Node', default=None)
features = MultipleJoin('Feature')
content = ForeignKey('Content', default=None)
children = MultipleJoin('Node', joinColumn='parent_id')
parentNameInd = DatabaseIndex('parent', 'name', unique=True)
parentInd = DatabaseIndex('parent')
def _get_path(self):
nodes = []
r = self
while r is not None:
nodes.append(r.name)
r = r.parent
nodes.append('')
nodes.reverse()
return join(nodes, '/')
def __getitem__(self, key):
for f in self.features:
if f.name == key:
return f.value
raise KeyError('Feature %s not found!' % key)
def __setitem__(self, key, val):
for f in self.features:
if f.name == key:
f.value = val
return
Feature(name=key, value=val, node=self)
def __delitem__(self, key):
for f in self.features:
if f.name == key:
f.destroySelf()
return
raise KeyError('Feature %s not found!' % key)
class Feature(SQLObject):
node = ForeignKey('Node')
name = StringCol(length=20)
value = StringCol(length=100)
nodeIdNameInd = DatabaseIndex('node', 'name', unique=True)
class Content(SQLObject):
content = StringCol()
nodes = MultipleJoin('Node')
Jestem ciekawy ile zajęłoby stworzenie podobnego modelu w PHP i czy byłby kiedykolwiek tak funkcjonalny.
Tutaj algorytm dzielenia pliku z napisami na trzy części - w php chyba trzeba by się z tym bardziej pomęczyć, co?
Kod
import string, datetime
fpr=open("lotr3.txt")
fpw1=open("lotr3_1.txt", "w")
fpw2=open("lotr3_2.txt", "w")
fpw3=open("lotr3_3.txt", "w")
dts=[[fpw1, datetime.datetime(2000, 1, 1, 0, 0)]
, [fpw2, datetime.datetime(2000, 1, 1, 1, 25)]
, [fpw3, datetime.datetime(2000, 1, 1, 2, 35)]]
dts.reverse()
dt0=datetime.datetime(2000, 1, 1, 0, 0)
for l in fpr.xreadlines():
arr=l.split(":")
ddt=dt0+datetime.timedelta(hours=int(arr[0]), minutes=int(arr[1]), seconds=int(arr[2]))
for try_ in dts:
if ddt>=try_[1]:
try_[0].write((dt0+(ddt-try_[1])).strftime("%H:%M:%S:")+string.join(arr[3:], ":"))
break
fpr.close()
fpw1.close()
fpw2.close()
fpw3.close()
Tutaj dalej mała klasa implementująca nowy język do robienia porównań
Kod
# author: Adam Wieckowski <mail>
# date: 07.01.2007
from re import compile
from fnmatch import *
class StringConstraint:
def __init__(self, op, pattern):
# 0 - equals caseinsensitive, 1 - equals casesensitive
# 2 - fnmatch, 3 - fnmatchcase, 4 - regexp
if op[0] == "!":
self.__passMap = {True: False, False: True}
op = op[1:]
else: self.__passMap = {True: True, False: False}
match = {"==":0, "=*":1, "likei":2, "like":3, "=~":4}[op.lower()]
self.__match = match
self.__pattern = (match == 4) and compile(pattern) or pattern
# /def __init__(self, pattern, op):
def Evaluate(self, str):
# # the readable way (long way/wrong way)
# if self.__match == 0:
# retVal = str.lower() == self.__pattern.lower()
# elif self.__match == 1:
# retVal = str == self.__pattern
# elif self.__match == 2:
# retVal = fnmatch(str, self.__pattern)
# elif self.__match == 3:
# retVal = fnmatchcase(str, self.__pattern)
# elif self.__match == 4:
# retVal = not self.__pattern.match(x) == None
# return self.__passMap[retVal]
# the one-statement-one-eval way
return self.__passMap[ \
[ (lambda x: x.lower() == self.__pattern.lower()) \
, (lambda x: x == self.__pattern) \
, (lambda x: fnmatch(x, self.__pattern)) \
, (lambda x: fnmatchcase(x, self.__pattern)) \
, (lambda x: not self.__pattern.match(x) == None)] \
[self.__match](str)]
# # the one-statement-all-eval way
# return self.__passMap[ \
# [ str.lower() == self.__pattern.lower() \
# , str == self.__pattern \
# , fnmatch(str, self.__pattern) \
# , fnmatchcase(str, self.__pattern) \
# , type(self.__pattern) is not type("") and not self.__pattern.match(str) == None or False] \
# [self.__match]]
# /def Evaluate(self, str):
# /class StringConstraint:
def StringConstraintParse(str):
for op in ["likei", "like", "=~", "=*", "=="]:
parts = str.split(op, 1)
if len(parts) == 2: break
if len(parts) == 1: raise Exception("Unknown operator.")
if parts[0][-1] == "!": # negation
op = "!" + op
parts[0] = parts[0][:-1]
if parts[0][-1] == "\\": # lets be able to escape the operator
s, p = StringConstraintParse(parts[1])
parts[0] = parts[0] + op + s
else: p = StringConstraint(op, parts[1].strip())
return (parts[0].strip(), p)
# /def StringConstraintParse(str):
def StringConstraintEvaluate(str): # shortcut
str, p = StringConstraintParse(str)
return p.Evaluate(str)
# /def StringConstraintEvaluate(str):
Polecam głównie linijkę 35 - tak apropo programowania funkcjonalnego.
Te trzy przykłady to różne możliwości zastosowania Pythona, które pokazują mam nadzieję główne różnice w zastosowaniu w przeciwieństwie do PHP. Jeżeli chodzi o zdanie z funkcjonalnym programowanie to jest opinia subiektywna - osobiście po prostu nabardziej lubię to podejście do programowania. Mam nadzieję, że podane przykłady unaoczniają jak można w Pythonie zaimplementować algorytmy w kilku dosłownie linijkach.
Pozdrawiam. I weźcie poprawkę, że to są wszystko subiektywne opinie.