Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 7, 2009 18:58:22

Ferroman
От:
Зарегистрирован: 2006-11-16
Сообщения: 2759
Репутация: +  1  -
Профиль   Отправить e-mail  

Поделитесь тестовым заданием по Python

dmydry
Нет, просто сравнил качество кода. У Кузнецова явно лучше. Если между 2-мя выбирать то ему предпочтение.
Но Андрею, по поводу твистеда, видней конечно. У меня, как я уже говорил, с twisted опыта нету, так что архтектруно я оценивать не могу.

Офлайн

#2 Апрель 7, 2009 21:20:17

dmydry
От:
Зарегистрирован: 2009-03-30
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

Поделитесь тестовым заданием по Python

Ferroman
я имел ввиду откуда Вы знаете какой код Кузнецова? Знакомы? Я имен тут не оглашал.



Офлайн

#3 Апрель 7, 2009 21:23:00

cutwater
От:
Зарегистрирован: 2009-01-08
Сообщения: 444
Репутация: +  19  -
Профиль   Отправить e-mail  

Поделитесь тестовым заданием по Python

Обратите внимание на копирайт в коде



Офлайн

#4 Апрель 7, 2009 21:33:01

dmydry
От:
Зарегистрирован: 2009-03-30
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

Поделитесь тестовым заданием по Python

cutwater
упс ) спасибо, и правда не обратил внимание..



Офлайн

#5 Апрель 7, 2009 23:25:27

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

Поделитесь тестовым заданием по Python

dmydry, я с твистед не работал (Андрею виднее), но по тому, как человек оформляет код, можно многое о нём сказать. Как и по тому, как он пишет/говорит. Так что я полностью согласен с Ferroman'ом: берите Кузнецова. У него тоже ляпов хватает, но по сравнению с первым… В общем выбирать не приходится.

P.S. И добавляйте код в тег code, а то читать не удобно.
P.P.S. Тест и правда странный… Может мне приколоться пройти? Так, для себя, чисто поржать…



Офлайн

#6 Май 6, 2009 12:01:37

dmydry
От:
Зарегистрирован: 2009-03-30
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

Поделитесь тестовым заданием по Python

прошу прокомментировать выполненное задание
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()
client.py:

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()



Офлайн

#7 Май 6, 2009 14:10:48

Archer
От:
Зарегистрирован: 2009-05-04
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Поделитесь тестовым заданием по Python

Доброе время суток!

Недавно проходил собеседование(тест) на 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)
dmydry, надеюсь у Вас не будет никаких обид за это сообщение?



Отредактировано (Май 6, 2009 14:12:12)

Офлайн

#8 Май 6, 2009 15:09:39

dmydry
От:
Зарегистрирован: 2009-03-30
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

Поделитесь тестовым заданием по Python

какие обиды, даже хорошо, что выложили сюда, я ещё до вашего задания не дошел просто

пусть народ прокомментирует задания, а так будем смотреть



Офлайн

#9 Май 6, 2009 15:36:49

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

Поделитесь тестовым заданием по Python

dmydry, я не знаю, как там с твистед, но если Archer только начал разбирать питон, то ему моё "9" по десятибальной шкале.
Archer, а на чём рагьше писал?



Офлайн

#10 Май 6, 2009 15:51:32

Archer
От:
Зарегистрирован: 2009-05-04
Сообщения: 6
Репутация: +  0  -
Профиль   Отправить e-mail  

Поделитесь тестовым заданием по Python

ZZZ
dmydry, я не знаю, как там с твистед, но если Archer только начал разбирать питон, то ему моё "9" по десятибальной шкале.
Archer, а на чём рагьше писал?
На работе в основном Delphi, Oracle.
Из личных предпочтений была Java пока не познакомился с Python.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version