Я говорю то же самое как другие парни, таким образом, общее корректное, я просто пытаюсь сделать его более ясным.
@@IDENTITY
возвраты идентификатор последней вещи, которая была вставлена соединением Вашего клиента с базой данных.
Большую часть времени это хорошо работает, но иногда триггер пойдет и вставит новую строку, о которой Вы не знаете, и Вы получите идентификатор от этой новой строки вместо той, которую Вы хотите
SCOPE_IDENTITY()
, решает эту проблему. Это возвращает идентификатор последней вещи, которую Вы вставили в код SQL , Вы отправили к базе данных. Если триггеры пойдут и создадут дополнительные строки, они не заставят неправильное значение быть возвращенным. Ура
IDENT_CURRENT
возвраты последний идентификатор, который был вставлен любым. Если некоторое другое приложение, окажется, вставит другую строку в unforunate время, Вы получите идентификатор той строки вместо Вашей.
, Если Вы хотите избежать рискованных действий, всегда используйте SCOPE_IDENTITY()
. Если Вы будете придерживаться с @@IDENTITY
, и кто-то решает добавить триггер позже, весь Ваш код повредится.
Если вы делаете это только разово, зачем вообще возиться с Python? Excel или OpenOffice Calc откроет вам два файла CSV, после чего вы можете просто вырезать и вставить столбец из одного в другой.
Если два списка идентификаторов не совсем одинаковы, то простой макрос VB сделает это за вас.
Когда у вас есть списки CSV, один из простых способов заменить столбец в одной матрице другим - это транспонировать матрицы, заменить строку, а затем транспонировать обратно отредактированную матрицу. Вот пример с вашими данными:
csv1 = [['1', 'a', '10'], ['2', 'b', '20'], ['3', 'c', '30']]
csv2 = [['1', 'a', '50'], ['2', 'b', '70'], ['3', 'c', '90']]
# transpose in Python is zip(*myData)
transposedCSV1, transposedCSV2 = zip(*csv1), zip(*csv2)
print transposedCSV1
>>> [['1', '2', '3'], ['a', 'b', 'c'], ['10', '20', '30']]
csv1 = transposedCSV1[:2] + [transposedCSV2[2]]
print csv1
>>> [['1', '2', '3'], ['a', 'b', 'c'], ['50', '70', '90']]
csv1 = zip(*csv1)
print csv1
>>> [['1', 'a', '50'], ['2', 'b', '70'], ['3', 'c', '90']]
Использование SICP с Common Lisp возможно и весело
Вы можете использовать Common Lisp для изучения с SICP без особых проблем. Подмножество схем, которое используется в книге, не очень сложно. SICP не использует макросы и не использует продолжения. Есть DELAY и FORCE, которые можно записать на Common Lisp в несколько строк.
Также для новичков, использующих (функция foo)
и (funcall foo 1 2 3)
на самом деле лучше (IMHO!), потому что код становится понятнее при изучении частей функционального программирования. Вы можете видеть, где вызываются / передаются переменные и лямбда-функции.
Оптимизация хвостового вызова в Common Lisp
Есть только одна большая область, в которой использование Common Lisp имеет недостаток: Оптимизация хвостового вызова (TCO). Common Lisp не поддерживает TCO в своем стандарте (из-за нечеткого взаимодействия с остальным языком, не все компьютерные архитектуры поддерживают его напрямую (подумайте о JVM), не все компиляторы поддерживают его (некоторые Lisp Machine), он делает некоторую отладку / трассировку / шагая сильнее, ...).
Есть три способа смириться с этим:
Лично я бы рекомендовал 2 или 3.
Common Lisp имеет отличные и простые в использовании компиляторы с поддержкой TCO (SBCL, LispWorks, Allegro CL, Clozure CL, ...), а в качестве среды разработки используются либо встроенные, либо GNU Emacs / SLIME.
] Для использования с SICP я бы порекомендовал SBCL , поскольку он всегда компилируется по умолчанию, по умолчанию имеет поддержку TCO, а компилятор обнаруживает множество проблем с кодированием (необъявленные переменные, неправильные списки аргументов, множество ошибок типов , ...). Это очень помогает во время обучения. Обычно убедитесь, что код скомпилирован, поскольку интерпретаторы Common Lisp обычно не поддерживают TCO.
Иногда также может быть полезно написать один или два макроса и предоставить некоторые имена функций Scheme, чтобы код выглядел немного более похожим на Scheme. Например, у вас может быть макрос DEFINE в Common Lisp.
Для более продвинутых пользователей: есть старая реализация Scheme, написанная на Common Lisp (называемая Pseudo Scheme), которая должна запускать большую часть кода в SICP.
Моя рекомендация: если вы хотите пройти лишнюю милю и использовать Common Lisp, сделайте это.
] Чтобы упростить понимание необходимых изменений, я добавил несколько примеров - помните, ему нужен компилятор Common Lisp с поддержкой оптимизации хвостовых вызовов :
Пример
Давайте посмотрим на этот простой код из SICP:
(define (factorial n)
(fact-iter 1 1 n))
(define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product)
(+ counter 1)
max-count)))
Мы можем использовать его непосредственно в Common Lisp с макросом DEFINE
:
(defmacro define ((name &rest args) &body body)
`(defun ,name ,args ,@body))
Теперь вы должны использовать SBCL, CCL, Allegro CL или LispWorks. Эти компиляторы поддерживают TCO по умолчанию.
Давайте использовать SBCL:
* (define (factorial n)
(fact-iter 1 1 n))
; in: DEFINE (FACTORIAL N)
; (FACT-ITER 1 1 N)
;
; caught STYLE-WARNING:
; undefined function: FACT-ITER
;
; compilation unit finished
; Undefined function:
; FACT-ITER
; caught 1 STYLE-WARNING condition
FACTORIAL
* (define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product)
(+ counter 1)
max-count)))
FACT-ITER
* (factorial 1000)
40238726007709....
Другой пример: символическое дифференцирование
SICP имеет пример схемы для дифференциации:
(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp)
(if (same-variable? exp var) 1 0))
((sum? exp)
(make-sum (deriv (addend exp) var)
(deriv (augend exp) var)))
((product? exp)
(make-sum
(make-product (multiplier exp)
(deriv (multiplicand exp) var))
(make-product (deriv (multiplier exp) var)
(multiplicand exp))))
(else
(error "unknown expression type -- DERIV" exp))))
Выполнить этот код в Common Lisp очень просто:
число?
равно числоp
в CL CL: COND
использует T
вместо иначе
CL: ERROR
использует строки формата CL Давайте определим имена схем для некоторых функций. Код Common Lisp:
(loop for (scheme-symbol fn) in
'((number? numberp)
(symbol? symbolp)
(pair? consp)
(eq? eq)
(display-line print))
do (setf (symbol-function scheme-symbol)
(symbol-function fn)))
Наш макрос define
сверху:
(defmacro define ((name &rest args) &body body)
`(defun ,name ,args ,@body))
Код Common Lisp:
(define (variable? x) (symbol? x))
(define (same-variable? v1 v2)
(and (variable? v1) (variable? v2) (eq? v1 v2)))
(define (make-sum a1 a2) (list '+ a1 a2))
(define (make-product m1 m2) (list '* m1 m2))
(define (sum? x)
(and (pair? x) (eq? (car x) '+)))
(define (addend s) (cadr s))
(define (augend s) (caddr s))
(define (product? x)
(and (pair? x) (eq? (car x) '*)))
(define (multiplier p) (cadr p))
(define (multiplicand p) (caddr p))
(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp)
(if (same-variable? exp var) 1 0))
((sum? exp)
(make-sum (deriv (addend exp) var)
(deriv (augend exp) var)))
((product? exp)
(make-sum
(make-product (multiplier exp)
(deriv (multiplicand exp) var))
(make-product (deriv (multiplier exp) var)
(multiplicand exp))))
(t
(error "unknown expression type -- DERIV: ~a" exp))))
Давайте попробуем его в LispWorks:
CL-USER 19 > (deriv '(* (* x y) (+ x 3)) 'x)
(+ (* (* X Y) (+ 1 0)) (* (+ (* X 0) (* 1 Y)) (+ X 3)))
Пример потоков из SICP в Common Lisp
См. код книги в главе 3.5 в SICP. Мы используем дополнения к CL сверху.
SICP упоминает delay
, the-empty-stream
и cons-stream
, но не реализует его. Мы предоставляем здесь реализацию на Common Lisp:
(defmacro delay (expression)
`(lambda () ,expression))
(defmacro cons-stream (a b)
`(cons ,a (delay ,b)))
(define (force delayed-object)
(funcall delayed-object))
(defparameter the-empty-stream (make-symbol "THE-EMPTY-STREAM"))
Теперь идет переносимый код из книги:
Попробуйте следующее:
from __future__ import with_statement
import csv
def twiddle_csv(file1, file2):
def mess_with_record(record):
record['90mdist'] = 2 * int(record['90mdist']) + 30
with open(file1, "r") as fin:
with open(file2, "w") as fout:
fields = ['ID', 'transect', '90mdist']
reader = csv.DictReader(fin, fieldnames=fields)
writer = csv.DictWriter(fout, fieldnames=fields)
fout.write(",".join(fields) + '\n')
reader.next() # Skip the column header
for record in reader:
mess_with_record(record)
writer.writerow(record)
if __name__ == '__main__':
twiddle_csv('file1', 'file2')
Пара предостережений: