펼치기&접기 지원 ver 3.1R


Python 9x9 구구단표 출력코드

"""
Nine Times Table
"""

# print row 1
print(end='* ')
for col1row in range(2, 10):
print(f'{col1row:3d}', end=' ')

# print row 2-9
print()
for row in range(2, 10):
print(row, end=' ')
for col in range(2, 10):
print(f'{row * col:3d}', end=' ')
print()

결과 :

디바이스 카메라를 이용해 맥박과 시간 당 호흡비율을 측정하는 새로운 방법이 개발되어 원격 헬스케어에 도움을 줄 수 있을 것 Randomly Delivered

원문 : https://www.sciencedaily.com/releases/2021/04/210402084246.htm


디바이스 카메라를 이용해 맥박과 시간 당 호흡비율을 측정하는 새로운 방법이 개발되어 원격 헬스케어에 도움을 줄 수 있을 것


요약 : 연구팀은 개인용 스마트폰 또는 컴퓨터의 카메라로 찍은 사용자의 실시간 동영상을 이용해 맥박 및 시간 당 호흡 비율을 측정하는 방법을 개발해냈다.


본문 : 코로나19로 인해 직접적 접촉이 최소화됨에 따라, 의사들이 지속적으로 헬스케어를 제공하는 데에 있어 원격 헬스케어는 현재 중대한 기로에 놓여있다. 하지만 휴대폰이나 줌 원격대면 약속으로는 의사가 환자에게 중요한 생체 신호(맥박, 호흡률)를 즉각적으로 받아내기 어려운 것이 사실이다.


워싱턴 대학이 이끄는 연구팀은 개인용 스마트폰 혹은 컴퓨터의 카메라를 이용하여 얼굴이 나오는 실시간 동영상으로부터 사용자의 맥박과 호흡 신호를 포착하는 방법을 개발하는 데에 성공했다. 연구자들은 이 최첨단 시스템을 지난 12월의 Neural Information Processing System(신경 정보 처리 시스템)컨퍼런스에서 공개하였다.


현재 연구팀은 이러한 생리적 신호들을 측정할 수 있는 더 나은 시스템을 목표로 하고 있다. 현재 성과상, 카메라의 종류, 수광 조건 혹은 피부 색깔 등의 외형적 얼굴 특징의 차이에 따른 오류가 발생할 확률은 낮다. 연구진은 오는 4월 8일에 열리는 ACM 컨퍼런스의 건강부문에서 이러한 성과들을 공개할 예정이다.


“머신 러닝은 이미지들을 구분하기에 아주 좋은 기술이다. 만약 당신이 다양한 고양이 사진들을 입력하고 거기서 다른 여러가지로부터 고양이를 찾아내라고 한다면, 머신 러닝은 이를 수행할 수 있을 것이다. 그러나 여기에 더해 머신 러닝을 이용함으로써 원격 건강을 체크하는 데에 더욱 도움이 될 수 있을 것이며, 우리는 생리적 정보의 가장 강력한 정보(예를 들면, 맥박)원을 가진 영상에 대한 관심 영역(ROI, Region of Interest)를 구분하고 이들을 모두 측정할 수 있는 시스템이 필요하다.” 워싱턴 대학의 Paul G. Allen School  컴퓨터 사이언스&엔지니어링 박사 과정을 밟고 있는 Xiu Liu가 말했다.


“모든 사람은 서로 다르다.” Liu가 말했다. “그러므로 이 시스템은 개개인의 생김새, 주변 환경 등 다양한 변형들로부터 고유한 생리적 특징에 대해 신속하게 적응하고 분리해낼 수 있어야 할 것이다.”


연구진의 시스템은 클라우드가 아닌 고유 장비에서 돌아감으로써 프라이버시를 침해하지 않으며, 혈류의 변화와 상관성이 있는 얼굴의 빛 반사량에 대한 미묘한 변화를 잡아내는 데에 머신러닝을 사용한다. 그리고 이러한 변화들을 맥박과 시간 당 호흡비율 정보로 전환시킨다.


이 시스템의 최초 버전에서는 사람들의 얼굴과 “실측”정보(현장에서 측정 기기를 이용하여 개인의 맥박과 시간 당 호흡비율을 측정한 것)가 모두 포함된 영상 데이터셋으로 훈련되었다. 그리하여 이 시스템은 맥박과 시간 당 호흡비율을 계산하는 영상의 공간적, 시간적 정보를 사용하게 되었다. 이 시스템은 피실험자들이 움직이고 말하는 영상에 대해서 다른 유사한 머신러닝 시스템보다 더 나은 결과를 보여주었다.


일부 데이터셋에서 최초 버전의시스템은 잘 작동했지만, 아직 다른 사람들, 배경, 측광이 포함된 영상에서는 여전히 고전을 면치 못했다. 이 것은 “오버피팅(과過학습)”이라 불리는 공통적인 문제라고 연구팀은 말했다.


연구진은 이 시스템을 각 개인에게 맞춤화된 머신 러닝 모델을 만듦으로써 강화시켰다. 특히, 이는 얼굴에 적용된 여러가지 조건들(피부 톤, 수광 조건, 주변 환경) 사이에서 혈류의 변화와 관련된 생리적 특징들을 포함한 것으로 추정되는 비디오 프레임에서 중요한 영역을 식별하는 것을 가능케 했다. 이로써, 영상 내에서 필요한 의미를 가진 영역에 주목하고 맥박과 시간 당 호흡 비율을 측정할 수 있게 되었다.


해당 시스템이 이전의 시도들을 상회하는 결과(특히 어두운 피부 톤을 가진 사람들에 대해서)를 보여줬음에도 불구하고, 아직 할일이 많다고 연구팀은 전했다.


“피실험자의 피부가 어두울 때의 결과가 아직 열악한 편임을 우리는 인정한다.”, Liu가 말했다. “부분적인 이유로는 어두운 피부에는 빛 반사가 다르게 적용되어, 카메라가 잡아내기에는 좀 약한 신호를 내는 것이 원인이다. 우리 팀은 실제로 이러한 한계를 해결할 새로운 방법들을 개발하고 있다.”


연구진은 또한 이 시스템이 병원에서 어떻게 사용될지를 보기 위해 의사들과의 다양한 협력하에 있다.


“원격으로 맥박이나 시간 당 호흡비율을 감지하는 능력은 무조건적으로 원격 환자 케어 및 원격 의료를 위한 새로운 기회들을 제공한다. 이러한 기회로는 셀프 케어, 후속 조치 또는 중증 분류 또한 포함될 것이며, 특히 거동이 불편하여 진료를 받기 어려운 사람들에게 더더욱 효과적일 것이다.” Allen School과 전기, 컴퓨터 공학부 교수 Shwetak Patel(수석 저자)이 말했다. “사람들이 이미 가지고 있는 가전 기기들을 이용해 이러한 결과를 내는 데에 학술 공동체가 새로운 알고리즘적 접근에 착수하는 과정을 보는 것은 흥분되기 그지없는 일이다.”


내용의 출처 : 워싱턴 대학. 원고는 Sarah McQuate가 작성.



광섬유가 초전도 양자 컴퓨터들의 파워를 증진시킬 수 있을 것이다. Randomly Delivered

원문 : https://www.sciencedaily.com/releases/2021/03/210324135438.htm


광섬유가 초전도 양자 컴퓨터들의 파워를 증진시킬 수 있을 것이다.


요약 : 광섬유 덕분에, 막대한 계산능력을 가진 초전도 양자 컴퓨터 제작의 비밀은 평범한 전자통신 기술이 될지도 모른다. 물리학자들은 금속 전선 대신 광전도 섬유를 이용해서 초전도 양자 비트(qubit)를 측정 및 통제하는 데에 성공함으로써, 양자 컴퓨터로 겨우 몇 천개가 아닌 백 만개 규모의 큐빗들을 엮어내는 방법에 도달하고 있다.


본문 :

NIST(National Institute of Standards and Technology)의 물리학자들이 금속 전선 대신 광전도 섬유를 이용해서 초전도 양자 비트(qubit, 큐빗)를 측정 및 통제하는데 성공함으로써, 양자 컴퓨터로 겨우 몇 천개가 아닌 백만개 규모의 큐빗들을 엮어내는 방법에 도달하고 있다. 해당 실험내용은 3월 25일 기고된 Nature 논문지에 나와있다.


초전도 회로기술은 양자 컴퓨터들을 만들기 위해 필요한 선행 기술인데, 이는 초전도 회로의 신뢰도가 높고 대량생산이 쉽기 때문이다. 하지만 이러한 회로들은 반드시 극저온에서 운영되어야 하며, 상온에서 회로를 이어내는 전자공학 기술의 경우 복잡할 뿐만 아니라 큐빗들을 말그대로 과열시키기가 쉽다. 보통 양자 컴퓨터는 모든 형태의 문제들이 해결 가능하다는 관점 아래, 백만 큐빗정도는 처리가 가능해야 된다고 본다. 기존에 전선으로 연결된 극저온 실험 장치(초냉각 희석 냉동기)는 최대 몇 천개의 큐빗만을 지원하는 데에 그쳤다.


전자통신망의 중추가 되는 광섬유는 대량의 광신호를 열전도 없이 전달할 수 있는 유리 혹은 플라스틱 코어를 가지고 있다. 하지만 초전도 양자 컴퓨터들은 정보의 저장 및 처리를 위해 전자파 펄스들을 사용한다. 결국 전달된 빛은 반드시 전자파로 변환되어야 한다.


이 문제를 해결하기 위해서 NIST 연구진은 광섬유에 빛을 변환, 전달, 각각의 입자 혹은 양자들의 레벨을 측정하는 약간의 평범한 부품요소들을 조합했는데, 이로써 입자 또는 양자들은 전자파로 쉽게 전환될 수 있다. 이러한 시스템은 전선 연결시에도 작동했으며 안정시키기 어려운 양자 상태들을 유지하는 데 성공하였다.


“제가 생각하기에 이번 진보는 강력한 임팩트를 가질 것인데, 이는 곧 광자기술과 초전도 큐빗들이라는 두가지의 전혀 다른 기술을 조합해서 아주 중요한 문제를 해결한 것이기 때문입니다.” NIST 연구진 John Teufel이 말했다. “광섬유는 또한 기존의 전송선로에 비교했을 때, 더 많은 데이터들을 훨씬 작은 두께의 선로로 전송할 수 있습니다.”


일반적으로, 연구자들은 전자파 펄스를 상온에서 발생시킨 후 동축금속케이블을 통해 극저온으로 유지된 초전도 큐빗을 전달한다. 그러나 금속 대신 광섬유를 이용하여 광신호를 극저온 광감지기로 유도해낸 NIST의 새로운 결과물에 의해, 해당 신호는 다시 전자파로 변환되었고 큐빗으로 전달되었다. 일단 비교실험 목적으로써 전자파는 광자선로와 동축선로를 모두 경유하였다.


이번 광섬유 실험에 사용된 “트랜스몬” 큐빗은 조셉슨 접합(Josephson junction)을 이용한 3차원적 저장소(reservoir) 혹은 가속관(cavity)으로 알려진 장치였다. 이 접합은 두개의 절연분할된 초전도 금속으로 이루어져 있다. 고정된 조건 하에서 전류는 조셉슨 접합을 통과할 수 있으며, 양방향으로 왔다갔다하기도 할 것이다. 특정한 전자파 진동수를 적용함으로써, 연구진은 해당 큐빗을 낮음-초과 상태 사이에서 제어할 수 있었다. 이는 곧 디지털 컴퓨팅에서의 1과 0 개념으로 연결될 수 있다. 이러한 상태들은 쿠퍼쌍의 개수에 기반한 것이다. 쿠퍼쌍이란 전자들의 정반대 속성들에 의한 결합 전자쌍을 말하는데, 연구진의 결과는 곧 조셉슨 접합 사이에서 터널 효과가 발생했음을 의미한다.


양자선로를 이용하여 NIST팀은 해당 큐빗의 전자파 펄스를 발생시키는 두종류의 실험을 수행했는데, 하나는 측정된 양자 상태의 전자파 펄스이고, 나머지 하나는 제어된 양자 상태의 전자파 펄스이다. 이 방법은 두가지의 관계에 기반한 것인데, 우선 첫 번째로, 공명 진동이라 불리는 진동수에서 전자파는 조셉슨 접합 가속관내부를 앞뒤로 왔다갔다 하는 성질이 있으며, 이는 해당 큐빗 상태에 기반한다. 그리고 두 번째로, 이러한 해당 큐빗의 전환 상태에 대한 공명 진동수는 가속관 내부의 양자 갯수에 따라 정해지는 것이다.


연구진은 전자파 발생기로 해당 실험들을 시작했다. 해당 큐빗의 양자 상태를 제어하기 위해, 전자-광 변조기기로 불리는 장치들이 전자파들을 빠른 주기를 가지는 광점멸 신호로 변환했다. 이러한 광신호들은 광섬유를 통해 상온에서 절대온도 4K(=섭씨 -269도)에서 20밀리K(=섭씨 -273.13도)에 이르는 곳의 고속 반도체 광감지기까지 전송되며, 이렇게 도착한 광신호는 전자파로 변환되었고 결국 양자 회로로 보내졌다.


이번 실험에서, 연구진은 신호들을 해당 큐빗의 고유 공명 진동수로 전송하여 보내고자 한 의도적 양자 상태를 전달한 것이다. 이 큐빗은 바닥-초과 상태 사이를 적당한 레이저 세기로 왔다갔다하였다.


양자들의 상태를 측정하는 과정에서, 연구진은 전자-광 변조기기, 섬유 및 광감지기들을 통해 특정한 세기의 빛을 발사시켜 해당 가속관의 공명 진동수를 측정하기 위해 적외선 레이저를 이용하였다.


연구진은 맨 처음 해당 큐빗의 낮음-초과상태간 진동을 처음으로 발생시킬 때 제어된 적외선 레이저를 이용함으로써, 미약한 전자파 펄스를 가속관으로 전달하기 위해 광자 선로를 사용하는 데 성공했다. 해당 가속관의 진동수는 실험 중 98%의 확률로 정확하게 해당 큐빗의 상태를 표시하였으며, 일반적으로 사용되는 동축케이블 선로와 같은 정확도를 가졌다.


해당 연구진은 몇 천개 단위 신호의 송수신 용량을 가지는 각 광섬유를 통해서, 빛이 이러한 큐빗의 신호를 전달하고 받는 양자 처리기를 꿈꾸고 있다.


내용의 출처 : NIST



[Android] 외부 라이브러리 테스트 클래스가 계속 Unresolved Reference상태라면 Android Report

이 글에서는 Room라이브러리를 예시로 들고 있지만, 문제의 원인에 대해서는 해당 라이브러리와 전혀 상관없음을 미리 일러둔다.

안드로이드 공식 docs를 따라 테스트코드를 짜던 도중, MigrationTestHelper클래스에 대해 다음과 같은 Unresolved Reference 에러를 마주치게 되었다.


MigrationTestHelper는 Room라이브러리의 MigrationTest와 관련된 클래스인데, docs에서 다음과 같이 종속성을 gradle에 명시해주면 사용할 수 있다고 하여 믿고 그렇게 했었다.


그러나 에러는 여전히 계속되었고, docs에 따르면 실제로 androidx.room.testing에 MigrationTestHelper정의가 있었기 때문에
import androidx.room.testing.MigrationTestHelper 를 명시해주면 해당 Unresolved Reference에러가 사라져야 정상임에도 불구하고 고 그렇게 되지 않았다.


이러한 상황이 발생한 이유는 바로 androidTest에 대해서는 gradle의 종속성 명시가 되지 않았기 때문이었다.
안드로이드의 테스트패키지는 기본적으로 UI테스트와의 구분을 위해 androidTest, test로 나뉘어져있다. 그리고 테스트 관련 종속성을 gradle파일에 명시해주면 해당 종속성에 기반한 테스트 라이브러리 요소를 사용할 수 있다는 것 까지는 기본적으로 알고있던 사실이었다. 그러나

testImplementation 선언은 오직 test 패키지에만,
androidTestImplementation 선언은 오직 androidTest 패키지에만 영향을 미친다.

고로, docs에 명시된 대로 testImplementation으로 gradle파일에 종속성을 선언해주고 Sync하더라도, androidTest패키지에서는 적용되지 않은 것 마냥 처리했던 것이다.
결국 다음과 같이 바꿔주고나서야 androidTest 패키지에서는 더이상 MigrationTestHelper에 대한 Unresolved Reference에러를 발생시키지 않게되었다.


이글루에서 소스코드넣고 글쓰는 방법에 대해서 Programming Theories

파이썬 관련 글을 쓰면서 소스코드를 넣는 과정에서 겪은 우여곡절이 나름 가치있는 경험이라 생각되어 문서화 하게 되었다.


도직입적으로 내가 찾아낸 방법부터 설명하자면


이곳에서 복사하고 직접 html째로 복사해서 넣는게 제일 나았던 것 같다.

사용 방법 :
1. 소스는 IDE에서 작성하고 복사해서

2. http://colormycode.herokuapp.com/의 Source code칸에 붙여넣기,
Language는 적절하게 Style은 그럴듯해보이는걸로 골라본다.

3. 2번까지 했으면 Highlight!버튼을 눌러 Style이 정말 그럴듯해보이는지 하단의 Preview로 확인한다.

4. Preview가 맘에들면 HTML소스를 처음부터 끝까지 잡고 복사해서

5. html입력으로 들어가 넣을만한 적절한 지점에 복사한다.

결과 :
#include<iostream>

class Test {
public:
int var = 0;
};

void adding(int *addingnum) {
int newnum = 0;
addingnum = &newnum;
}

void adding(Test *para) {
para->var = 10;
}

void main() {
Test *a = new Test();

adding(a);
printf("a.var : %d", a->var);
}

profit.



======================

여기서부터는 써볼려다가 실패한 것들이다.


ui도 훨씬 깔끔하고 기능도 많고, 막 되게 좋은데

포스팅 도중에 여기에다 Color Scripter(사진에선 Code로 오타냄;)에서 복사한걸 붙여넣기하면

"포스팅할 글로 테스트를 하기가 좀"부분이 아래쪽으로 팍 내려가버렸다.
이전에는 소스코드 삽입부분 아래쪽에 적은 글들이 소스코드 중간즈음에 겹쳐서 나오기도 했었다.

html의 상태는 이렇다.

음... 아마 pre태그부분을 수정하면 되지않을까 싶은데,
그말은 즉슨 소스코드를 넣을때마다 저상태의 html코드 일부를 수정해줘야 한다는 것.
Code Scripter페이지 내의 옵션들을 다 검토해봤지만 해결방법을 찾지 못했다.
옵션중에 'HTML태그 자체 복사'라는 옵션이 있긴 했는데, 별다른 효과나 변화는 없었기에 포기.

이글루가 문제인가 싶어 티스토리에서도 확인해봤는데 동일한 문제가 발생하였다.
(발생하지 않았으면 이글루 에디터에 충격먹고 이민갔을것..)



적용결과는 뭔가 다른데서 자주 본 그런 느낌이다.
2015년부터는 딱히 관리안되는것같지만..


이글루는 자바스크립트를 막아놓았다. 포기.
다만 티스토리같이 자바스크립트를 지원하고 서버에 스크립트파일 업로드가 가능한 환경이라면
초기설정을 해놓고나서, 포스팅중에 html에서 소스코드부분을 pre 혹은 script태그로 감싸기만 하면 된다.
이글루가 아니라면 고려해볼만한 선택지인듯.

Python - 변수의 특징(mutable, immutable)과 전달(Call by ?) Python Report

파이썬의 변수는 진짜, 독특하다.

진짜 독특한 나머지 변수의 특성을 제대로 알지 못하면
이후에 나오는 개념이나 예시에서 

`아니 시X 이게 왜?`
혹은 `왜 이건 되고 이건 안되고 대체 무슨 기준인지...`

하는 상황을 자주 맞게 되도록 되어있다.

1. 파이썬의 모든 변수는 객체로 간주된다.

모든 변수는 어떤 메모리 공간으로의 참조, 즉 레퍼런스를 가진 것으로 간주된다.

여기서부터 독특하다.

C나 Java를 배웠다면 int형 변수와 배열 변수를 함수에 넘겨보면서
Call by value, Call by reference개념을 익혀본 적이 있을 것이다.

보통 변수를 `레퍼런스를 가지는가`(동적) 아니면 `값을 가지는가`(정적) 에 따라 두종류로 나누는데

파이썬은 그런게 없다. int고 뭐고 전부 다 객체로써 레퍼런스를 가진다.
모든 종류의 변수가 일종의 랩핑된 객체이기때문에 오버헤드를 가지기도 한다.
(C의 int형이 4바이트, 파이썬에서 32767 이하의 숫자를 가지는 변수가 차지하는 크기 14바이트)

다만 `모든게 레퍼런스`임으로 생기는 차이를 쉽게 실감하진 않는다.

메모리를 이용하는 이상 변수가 어딘가를 가리키고있다는 사실은 당연한 것이며

int형 변수에 사칙연산을 수행한다던지, print 함수로 출력한다던지, 비교를 한다던지 할때는
레퍼런스가 아닌, 값을 가진 변수처럼 느껴지도록 잘 되어있기 때문에 당장에는 이 차이를 실감하기 어렵다.

당장에는.

※ 변수의 종류를 둘로 구분하는 언어의 경우
정적 변수는 스택, 동적 변수는 이라는 고유 공간에 올라가는데
둘을 구분하지 않는 파이썬은 이를 어떻게 처리할까?

답 :

파이썬 가상머신님께서 놓고싶은 곳으로 놓아주신다고 한다.
CPython은 전부 에 올리는데 이는 CPython만의 특징이므로 다른 파이썬(ex. pypy, Jython 등)에서는 다르게 동작할 수 있다.

2. MutableImmutable

개인적으로 이런저런 구글링도중 이런저런 프로그래밍 영단어들을 마주쳤지만
파이썬을 시작하기 전에 mutable이라는 단어를 마주친적은 많진 않았던 것 같다.
있었어도 기억이 안날정도로 의식할 필요가 없었을 수도 있고.

그러나 파이썬을 접한 이후 mutable, immutable은 파이썬 관련 doc을 보는데 필요한 필수 영단어중 하나이다.

`이건 되고 이건 안되고`의 구분 기준이 변수형(type)과 관련있다면
해당 변수가 mutable이냐 immutable이냐 로 완벽하게 구분되는 경우가 많은 것 같다.

mutable의 뜻은 보시다시피 변할 수 있다는 것이다. 가변적.
immutable은 당연히 안변한다는 뜻이 되겠다.

여기서 논하는 `변할지 말지의 대상`은 변수의 레퍼런스가 가리키는 값을 말한다.
고로 immutable변수가 가리키는 값은 상수(Constant)라 볼 수 있겠으나 그렇다고 해당 변수의 값을 못바꾸는건 아니다.

mutable로 간주되는 타입 : list, dictionary, set(집합), bytearray, user-defined class(사용자가 직접 정의한 클래스)
immutable로 간주되는 타입 : int, float, complex, decimal, bool, string, tuple, range, frozenset, bytes

mutable이 의미하는 바를 알아보기 위해 list의 경우를 예로 들어보자면, 다음과 같이 선언된 리스트가 있다고 치자.

a = [1, 2, 3, 4]

우리는 a[0] = 0 등의 여러 문법을 활용해서 a가 가리키는 컨테이너의 내부원소 값을 바꿀 수 있다.
레퍼런스가 가리키는 데이터의 값을 변경할 수 있기때문에 mutable이다.

immutable이 의미하는 바를 알아보기 위해 string의 경우를 예로 들어보자면, 다음과 같이 선언되어 있을 때

str = "immutable"

마치 C의 포인터에 문자열을 할당한 것 처럼, str의 문자 하나하나를 바꾸는 것은 불가능하다. 에러난다.
레퍼런스가 가리키는 데이터의 값을 변경할 수 없으므로 immutable이다.

값을 변경할 수 없다는데 str에 통째로 새로운 문자열을 입력하는 것은 에러없이 잘 수행된다.
위의 문 다음에

str = "ismutable?"

이런 문장을 작성하고 실행시키면 에러 없이 잘 돌아간다.

마찬가지로 int, float과 같은 숫자형 변수들도 값을 통째로 바꾸는게 가능하다.

a = 10; a = 20

문제없이 실행된다.

..

엄연히 값이 바뀌고있다.

string은 일부 변경이 안되기라도 하지
int나 float은 애초에 단일한 값을 가지고있는데 이게 바뀌면 안바뀌는게 뭐가 있단말인가?

는 사실 다른 언어와 비교하면 사기처럼 보이겠다 싶을 수준의 메카니즘 때문이다.

C언어에서 &변수명 문으로 해당 변수의 주소를 가져올 수 있듯, 파이썬에서는 id(객체)로 객체의 id를 가져올 수 있다.
(메모리상의 위치를 뜻하는 주소와 달리 id는 VM상에서의 위치를 의미하기 때문에 주소가 아닌 id로 칭한다.)

길게말할 것 없이 다음의 코드 수행결과로 실체가 드러난다.

a = 200
print(id(a))
a = 300
print(id(a))
a = 200
print(id(a))
a = 300
print(id(a))

수행 결과:
1617683744
54975696
1617683744
54975696

주소에 해당하는 격의 id를 내놓은 결과물이므로 수행환경에 따라 값은 다르게 나타날 수 있지만
a가 같은 값을 가질 때 같은 id를 가진다는 사실은 동일하게 나올 것이다.

그림을 곁들여서 이 상황을 설명해보자면

a = 200 부분만 실행했을때의 상태이다. 여기까진 괜찮다.


이 다음 a = 300을 실행했을때 C언어였다면 다음과 같이 되었을 것이다.
a가 가리키는 곳(1617683744번지)의 값이 200에서 300으로 바뀌었을 것이다.


But 우리 파이썬은 여기에서 다음과 같이 처리하는 것이다.

새로운 수치값이 나오면 그 값이 저장될 새로운 공간을 할당하고 해당 값(300)을 저장,
변수 a가 가리키는 곳을 새로 할당한 공간으로 재배정한다.


a = 200문을 다시 실행한다면
이미 200이 저장된 곳으로 a가 가리키는 id값만 바뀌는 것이다.

a = 301 등으로 새로운 값을 넣는다면
새로운 값을 채우기 위해 새로운 메모리 공간을 사용하고
이전의 값을 가지고 있던 공간은 후일을 도모하기 위해 그 값을 가진 채 그대로 잔류한다.
이 값은 가비지콜렉션에 정리되기 전까지 메모리에 계속 잔류한다.


메모리 사용량이 어떻게 되던간에 주제로 돌아와서 보자면
변수가 가리키는 부분이 바뀔지언정, 변수가 가리키는 부분의 값이 바뀌지 않으니까 immutable인것이다.

값이 바뀌지 않는다고해서 다른 프로그래밍 언어처럼 값을 다루는데에 기능상의 문제는 없다.(ex. 사칙연산, 문자열 이어붙이기 등..)
오히려 다 잘되니까 이런 배경사정이 잘 느껴지지 않는 것 아닐까.


다만, 위에서 설명한 모든 특징이 결합되어
함수의 인자가 Call by Value/Reference 옵션들 중 어떻게 전달되는지에 영향을 끼친다.

3. 파이썬의 Call by Value? Reference?

Call by Value와 Call by Reference의 정의를 간략하게 짚고넘어가자면

Call by Value : 함수에 들어온 매개변수가 함수에 넣었던 인자의 값에 대한 복사본

예시 코드(C) :

void adding(int addingnum) {
addingnum++;
}
void main() {
int a = 0;
printf("현재 a변수값 : %dn", a);
adding(a);
adding(a);
adding(a);
printf("adding3회의 결과 a변수값 : %dn", a);
}

결과 :
현재 a변수값 : 0
adding 3회의 결과 a변수값 : 0


해석 : 변수 a는 adding함수에 자신의 복사본을 넘겨주었기 때문에
adding함수에선 변수 a와는 별개로 존재하는(같은 값을 가진 상태로 초기화됬을 뿐인) 매개변수 addingnum을 건드리는 것임으로
addingnum을 아무리 바꾼다고 한들, 변수 a에서는 아무 일도 일어나지 않는다.

Call by Reference : 매개변수가 인자의 레퍼런스에 대한 복사본

예시코드(Java) :

public class Test {
void function(Test[] paras) {
paras = new Test[5];
}

public static void main(String[] args) {
Test a[] = new Test[3];

System.out.println("a의 크기 : " + a.length);

for(int i = 1; i <= 3; i++)
a[i - 1] = new Test();

a[0].function(a);

System.out.println("a의 function메소드 실행 후 크기 : " + a.length);
}
}

결과 :
a의 크기 : 3
a의 function메소드 실행 후 크기 : 3


해석 : 변수 a는 function메소드에 자신의 레퍼런스 복사본을 넘겨주었기 때문에
function함수에서는 변수 a와는 별개로 존재하는(같은 값을 가진 상태로 초기화됬을 뿐인) 매개변수 paras를 건드리는 것임으로
변수 paras에 새로운 레퍼런스를 준다고 한들, 변수 a는 여전히 같은 레퍼런스를 가진다.

예시코드2(Java) :

public class Test {
public int variablenum = 0;

void function(Test para) {
para.variablenum++;
}

public static void main(String[] args) {
Test a = new Test();

System.out.println("a의 variablenum값 : " + a.variablenum);
a.function(a);
a.function(a);
a.function(a);
System.out.println("function메소드 실행 후 a의 variablenum값 : " + a.variablenum);
}
}

결과 :
a의 variablenum값 : 0
function메소드 실행 후 a의 variablenum값 : 3


해석 : 변수 a는 function메소드에 자신의 레퍼런스 복사본을 넘겨주었기 때문에
function함수에서는 변수 a와 같은 레퍼런스를 가짐으로써 a와 같은 객체를 para가 가리키게 되므로
para의 변수(variablenum)을 조작하는 것은 a의 variablenum을 조작하는 것과 같다.

(쓰기전엔 예상 못했는데.. 막상 적어보니 그렇게 간략하진 않게되었다..)


다른 언어에서는 보통 이 둘의 기준으로
인자에 Primitive(원시)변수가 오냐, Object(객체)변수가 오냐 로 구분을 한다.
Primitive변수는 주로 int, bool등의 기본 자료형같은 것들을 지칭하고
Object변수객체, 객체로된 컬렉션같은것들을 지칭한다.

프로시저(Procedure)에 인자로 넘어갈 때 Primitive변수는 Call by Value, Object변수는 Call by Reference로 넘어간다.
(예외적으로 C는 정적 변수는 Call by Value, 동적 변수(설령 객체 타입이더라도)는 Call by Reference로 넘어간다.)

Call by Value와 Call by Reference의 구분이 필요한 가장 중요한 이유로는
어떤 프로시저에 인자로 넘겨준 내용이 원본과 단절되느냐 마느냐를 결정하기 때문일 것이다.

Call by Value는 인자를 복사하여 따로 받은 매개변수를 아무리 조작해도 원본 인자와는 단절되어있기 때문에
프로시저 바깥 영역에 (프로시저 입력값을 이용한)영향을 주는 것은 불가능하지만
Call by Reference는 인자로 받은 레퍼런스가 가리키는 영역이 프로시저 바깥에서도 조작하고 있던, 프로시저와 공유되는 영역이기에
프로시저 바깥 영역에 (프로시저 입력값을 이용한)영향을 줄 수 있다.
각각 구분되는 일종의 위험성과 편리성을 가진 중요한 특징이다.

자. 이번 글에서 맨 처음으로 시작한 내용.

파이썬의 모든 변수객체로 간주된다.

파이썬에서는 위의 이유로, 변수가 인자로 넘어갈 때 모든 경우에서 Call by Reference로 넘어간다.
모든 경우에서 인자의 레퍼런스를 프로시저에 복사해 가는 것이다.
고로 모든 경우에서 프로시저는 레퍼런스가 가리키는 영역을 프로시저 바깥과 공유하게 된다.


그런데 이런 특징이 immutable변수의 특징과 결합되면 뭔가 이상한 형태가 된다.

결론만 먼저 말하자면
immutable변수를 인자로 받은 프로시저에서 무슨 짓을 해도 해당 인자의 원본 값에 영향을 줄 수가 없는
마치 immutable변수가 Call by Value로 전달 된 것 처럼 작동한다는 것이다.

값을 변경하는 조작(manipulation)연산의 모든 경우를 묶어서 다음과 같이 구분해보자.
삽입, 삭제, 갱신.

삽입은 완전히 새로운 값을 입력(연산자 =와 함께하는 것들에 해당)
삭제는 기존의 값을 삭제(더이상 해당 값을 조작할 수 없고 참조도 불가능한 접근 불가 상태)
갱신은 기존의 값에 기반한 수정(수치형의 사칙연산, 배열등의 컬렉션에 내부 원소 추가 등).
이외의 조작연산은 없다.

파이썬의 immutable변수를 갱신하는 연산은 위에서 얘기했던 대로 다음과 같이 이루어진다.
당신이 수치형 변수에 사칙연산을 한 결과를 넣던, 절충되거나 연장된 문자열을 할당하던간에
파이썬은 그 모든 과정을 다음과 같이 해당 변수에게 레퍼런스를 입력시켜주고 끝낸다.
새로운 값(ex. a = 200)을 넣어줘도 해당 값의 데이터를 가진 메모리 주소(id)를 연결시켜주고
뭔가 계산된 값(ex. a = a + 100)을 넣어줘도 해당 결과값의 데이터를 가진 메모리 주소(id)를 연결시켜줄 뿐이다.
삽입연산과 갱신연산을 같은 과정으로 볼 수 있겠다.

`변수 a를 인자로써 어떤 function프로시저영역에게 para라는 매개변수로 전달해줬을때의 상황`을 그림으로 가정해보자.

※ Call by Reference에서 매개변수는 인자의 원본이 아닌 복사본임을 인지하고 둘을 구분하는 것이 중요하다.

function프로시저영역에서 변수 a의 레퍼런스를 가졌던 para가 가리키는 값을
다른 값(다른 레퍼런스)으로 바꾼 결과는 다음과 같을 것이다.
para의 값을 그 어떤 날고 기는 방법으로 function영역 내에서 수정한다고 해도
function영역 바깥의 변수 a가 값 400을 가리키는 부분을 어찌 바꿔놓을 수 없다. 단절되어있다고 볼 수 있겠다.

삭제연산은 어떨까?
function프로시저 내에서 del para문을 실행했을 때의 상황을 가정해본 것이다.
a와는 별개의 레퍼런스 변수를 날려버린 것이기에 a는 버젓이 살아서 400을 가리키고있다.
값 400에 대한 원본 변수의 참조를 날려버릴 수 없는 이 상황 또한 원본과 단절되어있다고 볼 수 있겠다.

※ mutable변수의 del을 통한 삭제의 경우에도 위의 상황은 동일하게 일어난다.
del로 복사본 변수만 날려버려서 단절된다는 의미인데, mutable변수 또한 프로시저에게 인자로 전달될 때 복사본을 전달하기 때문.


삽입연산 = 갱신연산, 삭제연산 모두 immutable변수의 프로시저 내 매개변수 처리과정에서는 원본과 단절되어있는데
이는 다른 언어의 Call by Value와 같은 특징이다.

그러나 immutable변수의 프로시저 전달과정을 Call by Value로 칭할 수는 없다.
immutable변수를 전달할때는 일단 레퍼런스를 전달하는건데,
애초에 Call by Reference와 구분되어 사용되는 Call by Value의 의미 자체
Reference가 아닌 Value만 전달된다는 뜻이니까!

정확하게 설명한다면 

immutable 변수는 Call by Reference로 전달되지만
조작 시에는 Call by Value로 전달된 것 처럼 동작한다

는게 맞을 것이다.

mutable 변수는 조작연산중에도 다른 언어의 Call by Reference와 같은 특징을 띄니까
mutable 변수는 Call by Reference처럼, immutable 변수는 Call by Value처럼 동작한다고 볼 수는 있겠지만
그렇다고 immutable변수 전달을 Call by Value로 칭할수는.. 없는... 그런 상황인 것이다.



개인적으로 구글에서 변수에 대해 뒤지고 뒤진내용을 어느정도 종합하여 정리해보았습니다.
글을 쓴 저 또한 여러가지로 뒤져보고 알아보며 파이썬을 배워가는 입장이므로 틀린 부분이 있을 수 있기에 지적 및 보충 환영합니다.

Report 서론 Python Report

요즘 파이썬을 공부하고 있는데, 이전과는 다른 방식으로 시도해보고있다.

(근 5년내에 산거같긴한데 묵혀둔)파이썬3.2책에 기반하여 진도를 나가되
중간에 나오는 개념에 대해서 인터넷을 매-우 참고하여 확실하게 개념을 잡은 다음
IDE에서 이런저런걸 시험해보고 나온 결과를 합쳐서 노트에 정리하고 있다.

일종의 문서화를 통해 개념을 확실하게 정리하고자 한 것인데
이전의 무작정 뭔가 짜보고 마는 방식보다 확실하게 뭔가 남는 기분이 든다. 기분만 그런건 아닌 것도 같고.

문제점 또한 없지 않았는데

1. 시간과 노력이 많이 들어 이에 대한 스트레스가 엄연히 존재하고 무시할 수 없다는 것
2. 노트에 수기로 정리를 함으로써 오는 많은 애로사항들
.

문제점 1의 시간과 노력은 일단 계속 들여본다 치지만,
문제점 2는 문제점 1에 일종의 오버헤드를 부가시키는 느낌이 없지 않다. 이게 정말 부담으로 느껴지는게

일단 한번 적고나서 후에 수정이 번거롭다는게 문제를 많이 발생시키는 것 같은데

1. 먼저 특정 부분을 정리해 놓은 다음, 나중에 관련 개념이 나올 경우 이를 반영시키기 어렵다는 것
2. 정리도중 잘못된 부분이 있어 이전의 정리내용을 되돌리고자 할때
내용의 크기에 제곱으로 비례하는 느낌으로 다 지우개로 지우고 다시 정리해서 적어야 한다는 것
3. 이렇게 철저하게 잘 적어야 하기때문에,
적을 내용에 대해서 정말 놓친게 없나 꼼꼼하게 확인하고 철저히 정리해서 적어야 한다는 것.
이게 문제가 되는 이유는 진짜 100%에 가까운 완성본을 내놔야 나중에 안귀찮겠지 싶기 때문에 이에대한 부담감이 크기 때문.
섣불리 쓸 수가 없어 계속 어떻게 적어야할지 고민하면서 작성이 지연되는 것이다.
4. 그림, 코드표현이 번거롭고 부담이 간다.(적지 않은 줄 수를 차지하며, 이로 인해 개념하나에 몇 페이지단위로 소모하게 됨)
5. 기타 악필문제, 수정한 뒤 남는 지운 흔적 등등 비주얼이 더러운 문제...



이건 관련 근황.

뭐 막 이런저런 문제점을 느끼고 있다고 판단되고 이로 인해 초안 작성에 대한 부담감이 가중되며 전체 일정이 지연되는 것 같기에

이러한 문제가 개선된 방법을 도출해보기 위해

인터넷에 정리해보고자 한다.

적는 내용의 방향성은 참고 자료 형식을 띄게 할 예정이다.

개인적으로 이전에 C++, Java, C#의 기본문법에 대해서 어느정도 이해를 가진 상태로 파이썬을 시작했기에
언어로 프로그래밍 개념의 기본중 기본이다 싶은 것들(이를테면 변수의 정의라던지..)은 깊게 안따지고 넘어갈 것이며

`이 글을 보고나면 파이썬을 어느정도 다룰 수 있다`는 느낌보단
진짜 참고자료로써 이런 내용도 있었구나 할때의 이런 내용들을 위주로 적어보고자 한다.

물론, `이런 내용`으로 분류되는 기준은 주관적이고
작성자 또한 파이썬을 기초부터 공부하는 단계기 때문에 그리 높은 기준은 아닐 것으로 보인다.

k

1 2