Форум сайта python.su
dmydry
Нет, просто сравнил качество кода. У Кузнецова явно лучше. Если между 2-мя выбирать то ему предпочтение.
Но Андрею, по поводу твистеда, видней конечно. У меня, как я уже говорил, с twisted опыта нету, так что архтектруно я оценивать не могу.
Офлайн
Ferroman
я имел ввиду откуда Вы знаете какой код Кузнецова? Знакомы? Я имен тут не оглашал.
Офлайн
Обратите внимание на копирайт в коде
Офлайн
cutwater
упс ) спасибо, и правда не обратил внимание..
Офлайн
dmydry, я с твистед не работал (Андрею виднее), но по тому, как человек оформляет код, можно многое о нём сказать. Как и по тому, как он пишет/говорит. Так что я полностью согласен с Ferroman'ом: берите Кузнецова. У него тоже ляпов хватает, но по сравнению с первым… В общем выбирать не приходится.
P.S. И добавляйте код в тег code, а то читать не удобно.
P.P.S. Тест и правда странный… Может мне приколоться пройти? Так, для себя, чисто поржать…
Офлайн
прошу прокомментировать выполненное задание
server.py:
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
from twisted.python import log, logfile
from twisted.application.internet import TimerService
import sys
"""Server, that listens given port (8000 is default) and writes received data to log.
usage: server.py port_number"""
fl = logfile.LogFile("time.log", ".")
class LogProtocol(Protocol):
def dataReceived(self, data):
try:
log.msg(data)
self.transport.write("successful")
except:
self.transport.write("unsuccessful")
#print data
class LoggingFactory(Factory):
protocol = LogProtocol
def __init__(self):
log.startLogging(fl,setStdout=False)
def RotateLogFile():
"""Rotates logfile every minute """
log.rotate
def main():
"""Program's start point."""
if len(sys.argv)>1:
port = int(sys.argv[1])
else:
port = 8000
f = LoggingFactory()
timer = TimerService(60, fl.rotate)
timer.startService()
reactor.listenTCP(port, f)
reactor.run()
timer.stopService()
if __name__ == '__main__':
main()
from twisted.internet import protocol, reactor
from time import sleep, asctime
"""
Simple client for sending packet number
and time to server every 10 seconds on
8000 port.
"""
class TimeSend(protocol.Protocol):
"""Time send protocol"""
num = 0
def connectionMade(self):
self.transport.write("%3i %s" % (self.num,asctime()))
def dataReceived(self, data):
sleep(10)
self.num += 1
self.transport.write("%3i %s" % (self.num,asctime()))
def connectionLost(self, reason):
print "connection lost:", reason
class TimeSendFactory(protocol.ClientFactory):
"""TimeSend factory"""
protocol = TimeSend
def clientConnectionFailed(self, connector, reason):
"""Called when failed to connect to server. Prints detailed information."""
print "connection failed: ", reason
reactor.stop()
def clientConnectionLost(self, connector, reason):
"""Called when connection with server aborts. Prints detailed information about reasons."""
print "connection lost: ", reason
reactor.stop()
def main():
m = TimeSendFactory()
reactor.connectTCP("localhost", 8000, m)
reactor.run()
if __name__ == "__main__":
main()
Офлайн
Доброе время суток!
Недавно проходил собеседование(тест) на Junior Python Developer.
Несколько дней тому назад выслал выполненное тестовое задание, ответа о качестве его выполнения пока не получил. Решил из любопытства вбить текст задание в google, и к моему удивлению нашел эту тему на форуме :)
Своего выполненного задания в этой теме не обнаружил. Возможно, я чем-то не подошел или не настала очередь моего задания.
Решил выложить в этой теме свое выполненное задание. Пожалуйста, оцените и его. Мне нравится конструктивная критика, даже если она жесткая - это помогает совершенствоваться.
В программировании новичком не являюсь, но Python - новый язык для меня, изучал сам. Просто в восторге от Python, как от самого языка и подхода, так и от увиденных фреймворков (даже на аватарку питона поставил :) ). Разумеется, мои выводы основаны на простых написанных программах, но учитывая нарастающую популярность этого языка думаю, что на больших проектах он тоже не подкачает.
Ниже выкладываю свое выполненное тестовое задание в том виде, в котором выслал его работодателю(хотя сейчас я бы внес некоторые изменения):
Сервер:
#!/usr/bin/python
#I use logging for debugging purposes. I think it's unnecessary to implement
#unit testing for this task because I'm applying for Junior Python Developer
#position
#I named created simple protocol as Msg
from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor, threads
from twisted.protocols.basic import LineReceiver
from twisted.python import usage
import msg_utils
log = msg_utils.createDefaultModuleLogger("SERVER_EVENTS")
def checkPortParam(port_str):
"""Checks if valid port number is specified. Raises ValueError exception
with explaining message for incorrect port number"""
try:
port = int(port_str)
except ValueError:
raise ValueError("Port must be integer")
PORT_MAX = 65535
PORT_MIN = 1
if port < PORT_MIN or PORT_MAX < port:
raise ValueError("Port is not in valid range")
program_options.listen_port = port
class ProgramOptions(usage.Options):
"""Class for parsing command line arguments"""
listen_port = 1234
optParameters = [["port", "p", listen_port, "Port to listen", checkPortParam]]
#Variable that stores command line arguments must accessed wherever needed
program_options = ProgramOptions()
def createMessageLogger(log_filename = "msg.log"):
"""Creates and rerurns client's messages logger. Log file is rotated every minute"""
import logging.handlers
rotatingHandle = logging.handlers.TimedRotatingFileHandler(log_filename ,
when = 'M', interval =1, backupCount = 6)
rotatingHandle.setFormatter(logging.Formatter('%(asctime) s: %(message)s'))
msg_logger = logging.getLogger("CLIENT_MSG")
msg_logger.setLevel(logging.DEBUG)
msg_logger.addHandler(rotatingHandle)
return msg_logger
msg_logger = createMessageLogger()
def processMessage(msg):
"""Processes message reveiced from client. Processing is successful if no
exceptions are raised"""
try:
#Processing message is just writing it to log file
msg_logger.info(msg)
except:
log.exception("Processing error")
raise
class MsgProtocol(LineReceiver):
""""Implements Msg protocol"""
def __init__(self):
self.delimiter = "\n"
def connectionMade(self):
#IP, port and protocol of client's connection are stored for the logging purpose
self.__client_info = str(self.transport.getPeer())
log.info("Client connected. Client info: %s" % self.__client_info)
MSG_WELCOME = "Weclome to MSG SERVER"
self.sendLine(MSG_WELCOME)
def connectionLost(self, reason):
log.info("Client disconnected. Client info: %s Reason: %s" % (self.__client_info, reason))
def lineReceived(self, line):
log.debug("Msg received. Client info: %s" % self.__client_info)
#Starting message processing in a separate thread
deferedProcessing = threads.deferToThread(processMessage, line)
deferedProcessing.addCallback(self.sendSuccessResult)
deferedProcessing.addErrback(self.sendFailtureResult)
def sendSuccessResult(self, result):
"""Sends notofication about successfull message processing to client"""
log.info("Message processed")
MSG_PROCESS_SUCCEEDED = "Your message has been successfully processed"
self.sendLine(MSG_PROCESS_SUCCEEDED)
def sendFailtureResult(self, failture):
"""Sends notofication about NOT successfull message processing to client"""
log.error("Message processing failed. Reason: %s" % str(failture))
MSG_PROCESS_FAILED = "Your message has NOT been successfully processed"
self.sendLine(MSG_PROCESS_FAILED)
def createServer():
"""Main unit's function. Creates server."""
MsgFactory = Factory()
MsgFactory.protocol = MsgProtocol
reactor.listenTCP(program_options.listen_port, MsgFactory)
reactor.run()
if __name__ == "__main__":
msg_utils.parseProgramArguments(program_options)
createServer()
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
from twisted.python import usage
import msg_utils
#Creating logger that will be used in this module
log = msg_utils.createDefaultModuleLogger("CLIENT_EVENTS")
def checkPortParam(port_str):
"""Checks if valid port number is specified. Raises ValueError exception
with explaining message for incorrect port number"""
try:
port = int(port_str)
except ValueError:
raise ValueError("Port must be integer")
PORT_MAX = 65535
PORT_MIN = 1
if port < PORT_MIN or PORT_MAX < port:
raise ValueError("Port is not in valid range")
program_options.connect_port = port
class ProgramOptions(usage.Options):
"""Class for parsing command line arguments"""
DEFAULT_HOST = "localhost"
connect_port = 1234
optParameters = [
["host", "h", DEFAULT_HOST, "Host connect to"],
["port", "p", connect_port, "Port connect to", checkPortParam]
]
#Variable that stores command line arguments must accessed wherever needed
program_options = ProgramOptions()
class MsgClientProtocol(LineReceiver):
""""Implements Msg client's protocol"""
__PACKET_FORMAT = "Packet number: %d. Time: %s"
#Package sending interval in seconds
__PACKET_SEND__INTERVAL = 10;
def __init__(self):
self.delimiter = "\n"
#Number of a packet that was sent last lime
self.__packet_number = 0
def lineReceived(self, line):
log.debug("Msg received")
print line
def connectionMade(self):
self.sendMsgPacket()
def sendMsgPacket(self):
"""Sends packet number and time to server. Packets are sent repeatedly
each __PACKET_SEND__INTERVAL seconds"""
self.__packet_number += 1
import time
self.sendLine(self.__PACKET_FORMAT % (self.__packet_number, time.asctime()))
reactor.callLater(self.__PACKET_SEND__INTERVAL , self.sendMsgPacket)
class MsgClientFactory(ClientFactory):
"""Factory that manages Msg protocol. Program is terminated if connection
is lost or impossible. ReconnectingClientFactory can be used if need to
change this later."""
def startedConnecting(self, connector):
log.info("Initiating connect")
print "Initiating connect"
def buildProtocol(self, addr):
log.info("Connected to %s" %addr)
print "Connected"
return MsgClientProtocol()
def clientConnectionLost(self, connector, reason):
log.warning("Connection lost. Reason: %s" % reason)
print "Disconnected"
reactor.stop()
def clientConnectionFailed(self, connector, reason):
log.warning("Connection failed. Reason: %s" % reason)
print "Connection failed"
reactor.stop()
def makeConnection():
"""Main function of this module. Connects to server"""
reactor.connectTCP(program_options["host"], program_options.connect_port, MsgClientFactory())
reactor.run()
if __name__ == '__main__':
msg_utils.parseProgramArguments(program_options)
makeConnection()
def createDefaultModuleLogger(logger_name):
"""Creates, configures and returns default logger for using in modules"""
import logging
log = logging.getLogger(logger_name)
log.setLevel(logging.DEBUG)
logStreamHandler = logging.StreamHandler()
logStreamHandler.setLevel(logging.DEBUG)
logFormatter= logging.Formatter("%(asctime)s - %(module)s - %(levelname)s - %(message)s")
logStreamHandler.setFormatter(logFormatter)
log.addHandler(logStreamHandler)
return log
def parseProgramArguments(program_options):
"""Parses command line arguments. Resuling arguments are held in
program_params variable. If something is wrong with the arguments usage and
error are printed to console."""
from twisted.python import usage
try:
program_options.parseOptions()
except usage.UsageError, errortext:
import sys
print '%s: %s' % (sys.argv[0], errortext)
print '%s: Try --help for usage details.' % (sys.argv[0])
sys.exit(1)
Отредактировано (Май 6, 2009 14:12:12)
Офлайн
какие обиды, даже хорошо, что выложили сюда, я ещё до вашего задания не дошел просто
пусть народ прокомментирует задания, а так будем смотреть
Офлайн
dmydry, я не знаю, как там с твистед, но если Archer только начал разбирать питон, то ему моё "9" по десятибальной шкале.
Archer, а на чём рагьше писал?
Офлайн
ZZZНа работе в основном Delphi, Oracle.
dmydry, я не знаю, как там с твистед, но если Archer только начал разбирать питон, то ему моё "9" по десятибальной шкале.
Archer, а на чём рагьше писал?
Офлайн