ID:
PW:

     0 분
     16 분

엔지니어 돌종
  dolljong
프로그래밍 Tips
프로그래밍에 관한 Tip을 공유하는 곳입니다.


[python](엔지니어를 위한) 파이썬 시작하기[6] 함수
이석종  2022-08-23 17:31:50, 조회 : 582, 추천 : 66
- Download #1 : engpython06.png (17.8 KB), Download : 16

- Download #2 : stressmax.py (600 Byte), Download : 37

(엔지니어를 위한) 파이썬 시작하기[6]

 

내용 : 함수

참조 :  https://wikidocs.net/24

 

0.시작하며

수학에서 함수는 어떤 입력값을 주면 결과를 만들어준다는 개념이 있다. 프로그램에서도 동일하다. 지금까지 우리는 이미 많은 함수를 썼다. 화면에 내용을 출력해주는 print(‘hello world’)이런 것도 함수였고 파일을 열 때 사용한 open()도 함수였다.

 

엔지니어들에게 함수는 익숙하다. 수학을 통해서도 익숙했고, 이미 엑셀에서도 셀들의 합을 구하기 위해서 =sum(A1:A10)을 사용하거나 최대값을 찾기 위해서 =max(A1:A10) 이런 것도 써봤을 것이다. 모두 함수다.

 

코딩에서 함수는 엑셀의 함수보다 범위가 좀 넓다. 어떤 값을 돌려주는 것 외에도 많은 일을 시킬 수 있다. 코딩에서 함수는 코드들을 묶어 놓은 하나의 블럭처럼 사용하기도 한다. 100줄이 넘는 코드들을 묶어서 함수로 만들어 이름을 주고 그 함수를 불러다 쓰면(코딩에서 함수에게 일을 시키는 것을 호출(call)한다고 한다) 코드를 보기 편한 것이다. 예를 들어 1000줄짜리 코드가 있다면 100줄씩 묶어서 이름을 정해서 함수로 만들고 10개의 함수를 차례로 호출한다면 1000줄의 코드를 10줄로 관리할 수 있기 때문에 이해하기 더 쉬워질 것이다. 수정이 필요하다면 각각의 함수들을 수정하면 된다.

 

예를 들어 하루 일과를 코딩으로 한다면 일어나기, 샤워하기, 아침먹기, 출근하기, 오전일하기, 점심먹기, 오후일하기, 퇴근하기, 저녁먹기, 티비보기, 잠자리 들기 등으로 나눌 수 있을 것이다. 만일 이런 구분 없이 모든 행위를 나열하면 정리가 안되어 관리하기도 힘들 것이다.    

 

1. 함수 정의

함수는 정의하는 부분과 불러오는 부분으로 나뉜다. 정의해야 불러다 쓸 수 있다. 지금까지 썼던 print() 등의 함수는 파이썬에 기본적으로 내장된 함수다. (내장된 함수는 다음 강좌에서 공부한다). 기본적으로 정의가 되어있다는 것이다. 우리가 다룰 것은 사용자 지정 함수다.

 

def  

함수를 정의하는 키워드다. 함수 정의는 아래와 같이 def키워드를 이용해서 한다.

 

def 함수명(매개변수):

  문장

  문장

  return(돌려줄값)

 

함수명은 사용자가 원하는대로 정하면 된다.

매개변수는 함수 안에서 쓰여질 변수를 전달받는 변수 것이다. 그리고 문장들은 함수 안에서 해야될 일을 기술한 문장들이다.

return(돌려줄값)은 함수의 결과로 돌려줄 값을 써준다.

여기서 주의해야 할 것은 def 아래의 문장들은 들여쓰기가 되어있어야 한다는 것이다. 그리고 def문 마지막에 :이 있는 것도 주의하자.

 

예제: 함수 정의 예를 들어보자. 아래 그림과 같은 I형 거더가 있다고 하자. 이 거더의 제원을 알려주면 단면적(A), 단면2차모멘트(I), 단면계수(Z), 상부연단거리(yt) 등을 구해주는 함수를 정의해보자.

 

각 부재의 제원들과 구하는 값들을 나타내는 변수는 아래와 같이 정했다. 변수명은 코딩하는 사람이 마음대로 정하면 되지만 변수가 의미하는 것을 잘 나타내도록 정하는 것이 좋다.

hg : 거더높이,  hw: 웹높이, tf : 플랜지두께, tw: 웹두께, bf: 플랜지 폭. 

A : 단면적, I : 단면2차모멘트, Z:단면계수, yt : 상연 연단거리

변수명을 정했는데 여기서 hw와 hg 둘 중 하나가 정해지면 나머지는 정해지는 값이다. 따라서 입력에서는 둘중 하나만 입력하면 된다. 보통은 거더 전체 높이를 입력하는 것이 일반적이다. 그래서 hg를 입력하는 것으로 하겠다.

 

함수이름은 spop_igirder라고 지었다. section property, I-girder 이런 단어들을 적당히 조합해서 만든 함수명이다.

 

이 함수에 주어야 할 정보들 즉 매개변수는 gh, tf, tw, bf 이렇게 4개로 정했다. 각각 gh(girder height), tf(thickness of flange), tw(thickness of web), bf(breadth of flange)의 뜻이다.

함수를 정의해보자 def키워드 뒤에 함수명을 써주고 괄호 열고 매개변수 들을 ,로 구분해서 써주면 된다. 마지막에 :을 잊지 말자.

def spop_igirder(gh, tf, tw, bf):

 

이제 이 함수가 할 일들을 나열해주면 된다. 그 문장들은 이 함수의 소속이므로 들여쓰기를 해야 한다는 걸 기억하자.

 

def sprop_igirder(hg, tf, tw, bf):
  hw = hg -
2*tf
  bnet = bf - tw
  A = hg * bf - bnet * hw
  I = bf*hg**
3/12 - bnet*hw**3/12
  yt = hg /
2.0
  Z = I / yt
 
return({'A' : A, 'I' : I, 'Z' : Z, 'yt' : yt})

 

구해야 하는 값들을 수식을 써서 구했다. I를 구하는 부분에서 **3은 3제곱을 뜻한다. 언어마다 조금씩 다른데 파이썬에서는 x**n 이렇게 써주면 x의 n승을 뜻한다. 아마도 엑셀에서는 x^4 이런식으로 표현했을 것이다.

 

return문을 보자. return(돌려줄값)이라고 했는데 { }를 썼다. 여러개의 값을 돌려주기 위해서 dictionary로 묶어준 것이다. 2번째 강좌에서 다룬 dictionary형을 다시한번 상기해보자. dictionary는 { }로 묶여 있으며 key: value로 구성되어있다고 했다. ‘A’가 key이고 A는 value다. A라는 변수에는 단면적값이 들어있다. 이렇게 하면 여러개의 값들을 돌려줄 수 있다.

 

물론 여러개의 값을 아래와 같이 list로 돌려줄 수도  있다. list는 [ ]로 묶여있다.

return([A, I, Z, yt])

 

그리고 심지어 { }(dictionary)나 [ ](list)로 묶어주지 않고 return할 수도 있다. 아래와 같이 return( ) 괄호 안에 ,로 구분해서 나열만해도 return이 된다.

 

return(A, I, Z, yt)

 

이전 강좌에서 다루지는 않았지만 이렇게 리턴하면 ( )로 묶여서 return이 된다. ( )로 묶여 있는 데이터 형은 튜플형(tuple type)이라고 한다. 이 type은 list와 비슷한데 수정이 안된다는 것만 다르다. 즉 읽기만 가능하다.

 

dictionary로 돌려주는 것과 list로 돌려주는 것, 그리고 그냥 나열해서 돌려주는 것의 차이는 이 함수의 결과를 써먹을 때 차이가 생긴다. 그 부분에 대해서는 함수 호출부분에서 다루겠다.

 

2. 함수호출

앞에서 정의된 함수를 호출할 때는 함수명과 함께 ()안에 인수를 써주면 된다. 예를 들어 앞에서 만든 i-girder의 section property들을 구하기 위해서는 아래와 같이 호출하면 된다.( )안의 인수는 각각 hg, tf, tw, bf였다는 것을 기억하자. 아래와 같이 호출하면 hg=1500, tf=20, tw=12, bf=800인 것이다.

sprop_igirder(1500,20,12,800)

 

()안의 인수들이 각각 어떤 것을 의미하는지 어렵다고 생각하면 아래와 같이 매개변수명을 같이 써줄 수도 있다. 이런 경우에는 변수명을 알려줬기 때문에 순서를 지키지 않아도 된다.

sprop_igirder(tf=20,hg=1500,tw=12,bf=800

 

이렇게만 호출하면 함수의 실행 결과가 어디에도 저장되지 않는다. 그래서 결과를 저장할 변수를 정해서 할당하도록 한다. 이 함수의 결과를 아래와 같이 sprop에 저장했다.

sprop = sprop_igirder(1500,20,12,800)

 

이제 sprop에 접근해서 이 함수의 결과값들을 가져올 수 있다.

 

이제 return을 list로한 경우와 dictionary, tuple로 한 경우의 차이에 대해서 알아보자.

list로 return한 경우에는 return문에서 돌려주는 순서를 알고 있어야 한다. 즉 첫번째는 A 두번째는 I…그래서 I값을 알기 위해서는 두번째니까  1을 인덱스로 써야한다.

Izz = sprop[1]

 

tuple로 return한 경우에도 동일하다.

 

이에 비해서 dictionary인 경우는 key를 이용해서 각각의 결과에 접근할 수있다. 몇번째인지는 몰라도 된다. 단면적을 알고 싶으면 단면적에 해당하는 key인 ‘A’를 이용해서 접근하면 된다.

 

area = sprop['A']

 

지금까지의 내용을 stressmax.py라는 이름으로 저장했다.

def sprop_igirder(hg, tf, tw, bf):
  hw = hg -
2*tf
  bnet = bf - tw
  A = hg * bf - bnet * hw
  I = bf*hg**
3/12 - bnet*hw**3/12
  yt = hg /
2.0
  Z = I / yt
 
#return((A, I, Z, yt))  #list
 
return({'A' : A, 'I' : I, 'Z' : Z, 'yt' : yt}) #dictionary
 
#return([A, I, Z, yt])  #list

sprop = sprop_igirder(
1500,20,12,800)

#sprop=sprop_igirder(tf=20,hg=1500,tw=12,bf=800)
#print(sprop[0])
print(sprop[
'A'])

 

anaconda prompt에서 실행시키면 단면적값이 출력될 것이다.

(base) D:\dev\python>python stressmax.py
49520

 

함수선언부분에 return문이 3개가 있는데 차이를 테스트해보기 위해서 3개를 모두 쓰고 #로 comment처리하면서 테스트 해보자. sprop_igirder함수를 호출하는 방법도 두가지가 있다. 변수병을 생략하는 방법, 변수명을 써주는 방법. 그리고 print문으로 list나 tuple로 return했을 때와 dictionary로 return했을 때의 차이를 테스트해보자.

 

3. 함수를 이용한 최대 응력 구하는 프로그램

이제 함수를 정의하고 불러오는 방법을 배웠으니 실용적인 실습을 해보자. 위에서 단면특성값을 구하는 sprop_igirder함수를 정의했으니 단경간보에 등분포하중이 작용할 때 최대 모멘트를 구해주는 함수를 만들고 최대응력을 구해주는 프로그램을 만들어보자.

 

단경간보의 최대모멘트를 구해주는 공식은 너무 간단해서 함수로 만들 필요까지 없지만 일단 실습을 위해 만들어보자. 등분포 하중 w와 지간 l만 넘겨주면 지간 중앙의 모멘트를 구해주는 간단한 함수다. 함수 이름은 mementcenter라고 지었다.

def momentcenter(w,l):
 
return(w*l**2/8)

 

엔지니어들은 단위에 민감하다. 프로그램에서 단위까지 통제하도록 만들 수 있지만 이 예제에서는 단위를 통일하도록 할 것이다. 예를 들어 응력을 구한다면 최종 값을 MPa단위로 구하고 싶다면 Pa의 정의인 N/m2에 맞춰서 값을 넣어주면 된다. 즉 하중은 N, 길이단위는 m단위로 넣어주자.

 

함수 정의 부분 아래에 응력을 구하는 부분을 코딩하면 된다. 응력을 구하는 공식은  이므로 momentcenter함수로 모멘트를 구하고 sprop_igirder함수로 구한 단면특성치 중에 Z값을 취해서 에 대입하면 응력을 구할 수 있다.

두개의 함수 선언부 아래쪽에 아래의 코드를 추가하면 된다.

 

하중에 해당하는 w와 지간 l은 input함수로 사용자로부터 입력 받았다.  입력받을 때 단위를 알려주는 메시지를 추가했다.

input함수로 받은 결과는 문자열이므로 float함수로 형변환을 해줬다.

momentcenter함수를 호출할 때 사용자로부터 입력받은 w와 l을 전달했고 그 결과는 Mmax변수에 할당했다.

sprop_igirder함수를 호출했다. m단위로 제원을 입력했다. 거더 높이 1.2m, 플랜지 폭은 0.6m다. 단면특성치 함수호출의 결과를 sprop변수에 할당했다. 이 값은 dictionary형이다. 그래서 Z값은 sprop[‘Z’]로 취해서 할당했다. fmax를 계산하고 프린트했다. 프린트문에서 f-formating을 이용했다.

중간에 #로 comment처리된 문장은 확인을 위해서 출력을 했던 것이다. 코딩하는 과정에서 print문을 넣어서 값이 제대로 구해지고 있는지 확인한 것이다.

w = float(input('w(N/m): '))
l = float(input(
'l(m): '))
Mmax = momentcenter(w,l)
#print(f'Mmax: {Mmax}')
sprop = sprop_igirder(
1.2,0.020,0.012,0.600)
Z=sprop[
'Z']
fmax = Mmax/Z
print(
f'Max. Stress(N/m2) :{fmax}'

 

이 파일을 저장하고 실행하면 아래와 같은 결과가 나온다. 밑줄 친 부분은 사용자가 입력한 부분이다. 하중으로 100000N/m를, 지간길이로 20m를 입력했다. 출력 결과에 I(m4) ~ 부분이 있는데 이부분은 I값과 Z값을 확인하기 위해 sprop_igirder함수에 임시로 넣어놓은 출력문이다. 

(base) D:\dev\python>python stressmax.py
w(N/m):
100000
l(m):
20
Mmax:
5000000.0
I(m4):
0.009916096 Z(m3):0.016526826666666668
Max.
Stress(N/m2) :302538418.3452843

 

stressmax.py 전체 코드는 첨부파일로 올려놓겠다.

 

오늘은 함수를 정의하고 불러서 그 결과를 사용하는 방법을 공부했다.

 

다음 시간에는 파이썬에 기본적으로 선언되어있는 내장함수에 대해서 공부하겠다.



  추천하기   목록보기

Copyright 1999-2023 Zeroboard / skin by zero
구조설계의 미래를 준비하는 모임 [구조설계미래포럼]