Re[8]: Литература по дизайну
От: Gaperton http://gaperton.livejournal.com
Дата: 19.11.07 11:10
Оценка:
Здравствуйте, thesz, Вы писали:

G>>Также любопытен подход CRC Cards — обязателен к изучению для любого проектировщика и архитектора. Это единственный подход, который позволяет описать объектную систему с высоты "птичьего полета" — пренебрегая несущественными деталями, и оставляя суть. Набор CRC-карт для вашей системы — это квинтэссенция ее дизайна. Это выше уровнем, чем модели UML и OMT. Мы ее применяли как для языка, описывающего дизайн на раннем этапе, так и как лучшее средство документирования кода (CRC-карты писались в коде в комментариях к основным классам — единственно возможный подход не потерять информацию о дизайне при эволюции системы).


T>They are soooo 80-sh: The name CRC comes from <b>Class</b>, Responsibilities, and Collaborators which the creators found to be the essential dimensions of object oriented modeling.


So what? They are still beautiful. And still, they actually are not bound to OO and classes, cause in reality they don't have any notion of "aggregation" and encapsulated state. You don't think in term of "state" operating with CRC cards, you think in term of functions and responsibilities. So, they can be perfectly used to describe purely functional system as well, no matter how they are decomposed. О чем вряд-ли думали Кент Бек и компания, когда делали свой доклад на OOPSLA.

Так бывает. Эта штука более обща чем ООП — это квинтэссенция дизайна. Я, к примеру, вчера с успехом описал при помощи CRC-карт дизайн функционально чистой подсистемы работы с временными рядами для Эрланга, и весьма доволен результатом — самому понятно стало.
Re[2]: [Haskell] Решение задачи К
От: Gaperton http://gaperton.livejournal.com
Дата: 20.11.07 09:46
Оценка:
Здравствуйте, geniepro, Вы писали:

G>Я вот тут подумал, а что если ввести в эту электронную таблицу логические операции && || и операции сравнения > < >= <= == /= ... Что это даст? Можно ли будет с их помощью вычислить такие вещи, фибоначчи, факториал. аккермана и простые числа? Ведь макросов нету, циклов нету, циклические ссылки отбраковываются... Как их вычислять-то в таких условиях? А как вычислить их в Экселе, не пользуясь макросами?


В Экселе так не принято. Там принято делать рекурентные формулы. Пример. Скажем, у нас есть список расходов, и надо добавить к нему колонку, где будет их сумма нарастающим итогом. Тогда делается так.

Name Price Total
a 10 =b2
b 6 =c2+b3
c 7 =c3+b4

и так далее. Формула в total ссылается на свой предыдущий результат в ячейке выше, и прибавляет к нему ячеку слева. Таким образом можно определить произвольную рекуррентную формулу.

Кроме того, в Экселе есть оператор IF, который на самом деле эквивалент condition ? then : else, где все три выражения — формулы. Кроме того, в Экселе есть функции, оперирующие диапазонами даных. Например SUM(range).

Короче говоря, настоящая сила Экселя состоит как раз в том, что в нем без программирования можно делать достаточно навороченные вещи, пользуясь только набором предопределенных операций. Скажем, в нем можно запросто вести бухалтерию, составить бизнес-план и провести анализ сценариев, или выполнить статистическую обработку данных. Эксель — пожалуй, единственное средство, которое позволяет с легкостью применять компьютер для вычислений не программистами — им с легкостью может пользоваться бухгалтер, финансист, секретарша, менеджмент, и прочие. Более того — я видел и достаточно сложные системы на Экселе — например, систему управления производством (правда — уже со скриптами на бейсике, которые производят рассчет нарядов и планирование).

Что касается применений в программировании — мы применяли Эксель для обработки и анализа данных замеров производительности профайлером, для планирования трудозатрат, для анализа метрик и составления отчетов. Короче, крутая штука Эксель.
Re[3]: [Haskell] Решение задачи К
От: Курилка Россия http://kirya.narod.ru/
Дата: 20.11.07 09:50
Оценка: 13 (1)
Здравствуйте, Gaperton, Вы писали:

G>Короче говоря, настоящая сила Экселя состоит как раз в том, что в нем без программирования можно делать достаточно навороченные вещи, пользуясь только набором предопределенных операций. Скажем, в нем можно запросто вести бухалтерию, составить бизнес-план и провести анализ сценариев, или выполнить статистическую обработку данных. Эксель — пожалуй, единственное средство, которое позволяет с легкостью применять компьютер для вычислений не программистами — им с легкостью может пользоваться бухгалтер, финансист, секретарша, менеджмент, и прочие. Более того — я видел и достаточно сложные системы на Экселе — например, систему управления производством (правда — уже со скриптами на бейсике, которые производят рассчет нарядов и планирование).


Электронные таблицы — сила, это факт, а вот на лямбде ещё вот такую примочку выложили к экселю.
Re[4]: [Haskell] Решение задачи К
От: Gaperton http://gaperton.livejournal.com
Дата: 20.11.07 10:29
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Здравствуйте, Gaperton, Вы писали:


G>>Короче говоря, настоящая сила Экселя состоит как раз в том, что в нем без программирования можно делать достаточно навороченные вещи, пользуясь только набором предопределенных операций. Скажем, в нем можно запросто вести бухалтерию, составить бизнес-план и провести анализ сценариев, или выполнить статистическую обработку данных. Эксель — пожалуй, единственное средство, которое позволяет с легкостью применять компьютер для вычислений не программистами — им с легкостью может пользоваться бухгалтер, финансист, секретарша, менеджмент, и прочие. Более того — я видел и достаточно сложные системы на Экселе — например, систему управления производством (правда — уже со скриптами на бейсике, которые производят рассчет нарядов и планирование).


К>Электронные таблицы — сила, это факт, а вот на лямбде ещё вот такую примочку выложили к экселю.


Интересно, надо разобраться.
Re: [Haskell] Решение задачи К
От: haskell_beginner  
Дата: 27.11.07 18:40
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>поскольку каждый архитектор должен построить дом, подписать письмо четырёх и решить задачу К, я тоже не выдержал. см. http://www.haskell.org/haskellwiki/Ru/Problem_K


А не проще ли было как-то поимперативнее? Я хаскель знаю слабо, но вот в духе потока сознания родилось следующее:

import Control.Monad
import Data.Array.IO
import Data.IORef
import Data.List
import Data.Char
import Text.ParserCombinators.Parsec
import Control.Exception
import Prelude hiding (catch)

--------------------------------------------------------------------------------------

data Table = Table
           { tWidth  :: Int
           , tHeight :: Int
           , tData   :: IOArray (Int,Int) Cell
           }

data Cell  = CEmpty
           | CNumber Integer
           | CText   String
           | CExpr   Expr
           | CError  String

data Expr  = ESimple Term
           | EBinary Expr Op Term

data Term  = ENumber Integer
           | ERef    Int Int

data Op    = OPlus
           | OMinus
           | OMul
           | ODiv
           deriving Eq

numOps = [(OPlus, (+)), (OMinus, (-)), (OMul, (*)), (ODiv, div)]

evalOp (CNumber n1, op, CNumber n2) = CNumber $ n1 `f` n2 where Just (_,f) = find ((== op).fst) numOps
evalOp _                            = errEval

errParse    = CError "#Parse"
errEval     = CError "#Eval"
errIdx      = CError "#Index"
errExpr     = CError "#Expr" -- unevaluated

instance Show Cell where
  show CEmpty      = ""
  show (CNumber n) = show n
  show (CText   t) = t
  show (CExpr   e) = show errExpr
  show (CError  e) = e

--------------------------------------------------------------------------------------

parseTable :: String -> IO Table
parseTable input = do
  case lines input of
    []     -> error "invalid input"
    (l:ls) -> do let [h,w] = map toInt . split $ l
                 dat <- newArray ((0,0),(h-1,w-1)) CEmpty :: IO (IOArray (Int,Int) Cell)
                 forM_ (zip [0..] ls) $ \(i,l) ->
                   forM_ (zip [0..] $ split l) $ \(j,x) ->
                     writeArray dat (i,j) $ parseCell x
                 return Table { tWidth = w, tHeight = h, tData = dat }
  where toInt = read :: String -> Int
        split = lines . map (\c -> if c == '\t' then '\n' else c)

parseCell :: String -> Cell
parseCell ""                = CEmpty
parseCell ('\'':s)          = CText s
parseCell ('=' :s)          = case parse expr "" s of
                                Right e -> CExpr e
                                Left  _ -> errParse
parseCell s | all isDigit s = CNumber (read s)
            | otherwise     = errParse

expr   = do { t <- term; rest $ ESimple t }
rest e = do { eof; return e }
     <|> do { o <- op; t <- term; rest $ EBinary e o t }

op    = foldl1 (<|>) $
        map (\(ch,op) -> do { char ch; return op })
        [('+',OPlus), ('-', OMinus), ('*', OMul), ('/', ODiv)]

term   = do { n <- number; return $ ENumber n }
     <|> do { a <- letter; n <- number; return $ ERef (fromIntegral n - 1) (ord (toUpper a) - ord 'A') }

number = do { ds <- many1 digit; return (read ds :: Integer) }

--------------------------------------------------------------------------------------

printTable :: Table -> IO ()
printTable (Table w h d) = do
  a <- newArray ((0,0),(h-1,w-1)) "" :: IO (IOArray (Int,Int) String)
  forM_ [(i,j) | i <- [0..h-1], j <- [0..w-1]] $ \(i,j) -> do
    c <- readArray d (i,j)
    t <- evaluate (show c) `catch` (const $ return $ show errEval)
    writeArray a (i,j) t
  maxw <- foldl (\a x -> a `max` length x) 1 `liftM` getElems a
  forM_ [0..h-1] $ \i -> do
    (putStrLn . concat . intersperse "  " . map (pad maxw)) =<< (forM [0..w-1] $ \j -> readArray a (i,j))
  where pad w s = s ++ replicate (w - length s) ' '

--------------------------------------------------------------------------------------

data CState = CInit | CEval | CDone deriving Eq

evalTable :: Table -> IO Table
evalTable (Table w h d) = do
  st <- newArray ((0,0),(h-1,w-1)) CInit :: IO (IOArray (Int,Int) CState)
  d' <- mapArray id d -- copy ("let d' = d" evaluates table in place)
  let eval ij = do
        curst <- readArray st ij
        case curst of
          CDone -> return ()
          CEval -> error "eval"
          CInit -> do writeArray st ij CEval
                      c  <- readArray d' ij
                      c' <- case c of
                              CExpr e -> evalExpr e
                              _       -> return c
                      writeArray d' ij c'
                      writeArray st ij CDone

      evalExpr (ESimple t)     = evalTerm t
      evalExpr (EBinary e o t) = do e' <- evalExpr e
                                    t' <- evalTerm t
                                    return $ evalOp (e', o, t')

      evalTerm (ENumber n)     = return $ CNumber n
      evalTerm (ERef i j)      = if i < 0 || j < 0 || i >= h || j >= w
                                   then return errIdx
                                   else do
                                     tmpst <- readArray st (i,j)
                                     if tmpst == CEval
                                       then return errEval
                                       else do if tmpst == CInit then eval (i,j) else return ()
                                               c' <- readArray d' (i,j)
                                               case c' of
                                                 CNumber _ -> return c'
                                                 _         -> return errEval

  forM_ [(i,j) | i <- [0..h-1], j <- [0..w-1]] eval
  return $ Table w h d'

--------------------------------------------------------------------------------------

main = printTable =<< evalTable =<< parseTable =<< getContents


Наверное, если знать язык получше, можно упростить и сократить.
Re: [Haskell] Решение задачи К
От: Kisloid Мухосранск  
Дата: 29.11.07 17:29
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>поскольку каждый архитектор должен построить дом, подписать письмо четырёх и решить задачу К, я тоже не выдержал. см. http://www.haskell.org/haskellwiki/Ru/Problem_K


А можешь на английский перевести текст задания? Почему-то мне захотелось поделиться со своими коллегами, сам боюсь переводить, шпрехаю плохо
((lambda (x) (list x (list 'quote x))) '(lambda (x) (list x (list 'quote x))))
Re: [Haskell] Решение задачи К
От: Аноним  
Дата: 30.11.07 04:43
Оценка:
Здравствуйте, BulatZiganshin, Вы писали:

BZ>поскольку каждый архитектор должен построить дом, подписать письмо четырёх и решить задачу К


Не будучи архитектором, все же решил для треннировки написать свой эксел. Сумбурный вариант можно найти здесь: Еще одно решение K на Haskell
Не уверен, "легально" ли я использовал Parsec, но писать свой монадный парсер не хотелось
Почему хаскель? Потому что сочетание ленивости, меморизации и монадных комбинаторов делают его, на мой взгляд, идеальным средством для данной конкретной задачи. Возможно я и ошибаюсь, но именно ленивость с меморизацией позволяет "автоматически" разрулить зависимости наиболее эффективным способом без всякой теории графов, а проверка цикличности ссылок с "протаскиванием" ошибок прозрачно и элементарно имплементируется при помощи комбинации StateT, ReaderT и ErrorT. Так что "вычислительная" часть получилась достаточно простой и компактной (код до the коментария).
Возможно кому-то это будет интересно и прошу прощение за отсутствие комментариев равно как и явно очерченного дизайна
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.