2014-11-28 1 views
0

IDL 8.4를 사용하고 있습니다. read_csv()로 읽은 입력 타입을 결정하기 위해 isa() 함수를 사용하고 싶다./정수,/정수,/float 및/문자열을 일부 필드로 사용하고 싶습니다. 부동 소수점 숫자를 정수로 지정하고 다른 숫자는 상관하지 않으려합니다. 나는 이렇게 할 수는 있지만 인간의 눈에는별로 읽을 수 없다.idl : 동적으로 키워드를 구조를 테스트하는 isa 함수에 전달합니다. read_csv

str = read_csv(filename, header=inheader) 
; TODO check header 
if not isa(str.(0), /integer) then stop 
if not isa(str.(1), /number) then stop 
if not isa(str.(2), /float) then stop 

'/ 정수'문자 그대로대로 나는, 내가 위에서

expected_header = ['id',  'x',  'val'] 
expected_type = ['/integer', '/number', '/float'] 
str = read_csv(filename, header=inheader) 
if not array_equal(strlowcase(inheader), expected_header) then stop 
for i=0l,n_elements(expected_type) do 
    if not isa(str.(i), expected_type[i]) then stop 
endfor 

이 작동하지 않음과 같은 일을 할 수있는 희망, 그리고 난라는 이름의 구조를 찾고있다() ISA를 같아요. 비슷한 것을 어떻게 할 수 있습니까?

이상적으로 파일에서 읽은 헤더를 기반으로 예상되는 유형을 선택하므로 헤더가 예상 필드를 지정하는 한 스크립트는 계속 작동합니다.

편집 :

내 임시 해결책은 ISA에 대한 래퍼를 작성하는 것입니다(). 별로 예쁘지는 않지만 내가 원하는 것을 수행합니다 ... 깨끗한 해결책이 있다면 알려주세요.

또한 read_csv는 long, long64, double 및 string 중 하나만 반환하도록 정의되어 있으므로이 제한으로 테스트 할 함수를 작성할 수 있습니다. 하지만 나는 다른 비슷한 경우에 그들을 재사용 할 수 있도록 일반적으로 작동하도록 만들고 싶었습니다.

function isa_generic,var,typ 
; calls isa() http://www.exelisvis.com/docs/ISA.html with keyword 
; if 'n', test /number 
; if 'i', test /integer 
; if 'f', test /float 
; if 's', test /string 
    if typ eq 'n' then return, isa(var, /number) 
    if typ eq 'i' then then return, isa(var, /integer) 
    if typ eq 'f' then then return, isa(var, /float) 
    if typ eq 's' then then return, isa(var, /string) 
    print, 'unexpected typename: ', typ 
    stop 
end 

답변

1

IDL는 일부 제한된 반사 능력, 당신이 원하는 것을 정확히 할 것 같습니다

expected_types = ['integer', 'number', 'float'] 
expected_header = ['id',  'x',  'val'] 
str = read_csv(filename, header=inheader) 
if ~array_equal(strlowcase(inheader), expected_header) then stop 
foreach type, expected_types, index do begin 
    if ~isa(str.(index), _extra=create_struct(type, 1)) then stop 
endforeach 

을이에 "읽기 쉽게"정말 있다면 그것은 논쟁의 여지가있어 당신의 테스트 할 세 가지 사례가 있기 때문에 500 건의 사례가있는 경우 500 개의 약간 다른 줄을 작성하는 것보다 훨씬 더 깨끗합니다.

이 다소 난해한 IDL 기능을 사용, 그래서 나를 조금 무슨 일이 일어나고 있는지 설명하자 냈다 :

expected_types들이 사용되어야한다 순서 (문자열) 키워드 단지 이름 목록입니다. type 변수와 반복에 키워드 문자열을 넣어 expected_types 이상

foreach 부분의 반복은, index으로 계산합니다.

for index = 0, n_elements(expected_types) - 1 do를 사용하고 IMHO 읽기 쉽게 대신 typeexpected_types[index]을 사용하지만 foreach 루프는 동일하다. 참조 here.

_extra은 마치 키워드 집합 인 것처럼 구조를 전달할 수있는 특수 키워드입니다. 각각의 구조체 태그는 키워드로 해석됩니다. 참조 here.

create_struct 함수는 (문자열) 태그 이름과 (모든 유형) 값 중 하나 이상의 쌍을 취하고 이러한 태그 이름과 값을 가진 구조체를 반환합니다.참조 번호 here.

마지막으로 not (bitwise not)을 ~ (logical not)으로 바꿨습니다. foreachfor과 같은이 단계는 필요하지 않지만 구별이 중요한 일부 코드 유형을 디버깅 할 때 두통을 피할 수 있습니다.

- 이런

반사 능력이 엄청 많이 할, 슈퍼 유용하게 사용할 수 있습니다. 그들은 다른 말로 일하는 말입니다. 그러나 IDL 프로그래머는 그것들을 많이 사용하지 않는 것 같습니다. - (문자열) 태그 이름과 값에서 구조를 만듭니다

  • create_struct 다음은 각각의 문서에 대한 링크 내가 IDL에서 사용하는 일반적인 반사 기능의 빠른 목록이 있습니다.
  • n_tags - 구조의 태그 수를 가져옵니다.
  • _extra, _strict_extra, and _ref_extra - 구조 또는 참조별로 키워드를 전달하십시오.
  • call_function - (문자열) 이름으로 함수를 호출합니다.
  • call_procedure - (문자열) 이름으로 프로 시저를 호출하십시오.
  • call_method - (문자열) 이름으로 메소드 (객체)를 호출합니다.
  • execute - 문자열에 저장된 완전한 IDL 명령을 실행합니다.

참고 : execute 기능을 사용 매우 조심합니다. 그것은 당신 (또는 사용자, 파일, 웹 폼 등)이 그것을 먹이는 IDL 문장을 맹목적으로 실행할 것입니다. IDL execute 기능에 신뢰할 수없는 사용자 또는 웹 사용자 입력을 절대 공급하지 마십시오.

+0

답장을 보내 주셔서 감사합니다! 이 _extra는 제가 찾고 있었던 것 같습니다. create_structure에서 가치 1의 의미는 무엇입니까? 다른 값, 문자열 등으로 시도했지만 무시되는 것 같습니다. 올바른 태그가있는 구조를 만들려면 그냥 자리 표시 자입니까? – yosukesabai

+0

@yosukesabai 값 1이 키워드의 값으로 전달됩니다. IDL은'/ number' 나'/ float'와 같은 슬래시와 함께 키워드를 전달할 때 키워드의 값에 대해 1의 비트 값 (1S)을 16 비트 정수로 전달합니다. 즉,'result = isa (value,/integer) 'IDL 문은'result = isa (value, integer = 1S)'를 작성하기위한 바로 가기입니다. –

+0

감사합니다. 한 가지 더 좋은 점은 알고 있어야합니다. – yosukesabai

0

당신은 확실히 같은 키워드에 액세스 할 수 있지만 유용 할 수 있습니다 ISAtypename 매개 변수가있다. 이 테스트되지 않은,하지만 작동합니다 :

expected_header = ['id', 'x', 'val'] 
expected_type = ['int', 'long', 'float'] 
str = read_cv(filename, header=inheader) 
if not array_equal(strlowcase(inheader), expected_header) then stop 
for i = 0L, n_elemented(expected_type) - 1L do begin 
    if not isa(str.(i), expected_type[i]) then stop 
endfor 
+0

답장을 보내 주셔서 감사합니다. 예, typename을 사용할 수 있다는 것을 알았지 만, 특정 유형의 다양한 유형을 지정해야하므로 사용할 수 있습니다. 예 : isa (x, 'long') 대신 true를 반환합니다. x는 32 비트 부호이고, x는 숫자 형식이면 받아 들여야합니다 ... – yosukesabai