블로그 이미지
초딩입맛제주아재
하고 싶은 것만 하며 살고 싶다

calendar

1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31
2007. 5. 22. 15:38 Programing/Smalltalk

tempStr := 'e:\ccc\ddd\Adobe_Acrobat7_Pro_KOR_SN.txt'. "파일명 추출"
tempStr rightString: (tempStr reverse findString: '\') - 1. "디렉토리명 추출"
tempStr leftString: (tempStr size - (tempStr reverse findString: '\')).

tempStr leftString: 4.   "왼쪽에서 4글자"
tempStr reverse. "뒤집기"
tempStr rightString: 6. "오른쪽에서 6글자"
tempStr isLiteral. "리터럴인가?"
tempStr isString."문자열인가?"
tempStr subStrings: '\'. "문자열 나누기(배열) = explode"
tempStr midString: 3 from: 2.  "문자열 추출 = substr"
tempStr findString: '\'. "문자열 위치 찾기 = strpos"
tempStr findString: 'l' startingAt: 5. "문자열 위치 찾기 + 시작위치 설정"
tempStr first: 5. "처음부터 inteager 만큼 추출"
tempStr hash.
tempStr includes: $\.
tempStr indexOfAnyOf: 'smallt' startingAt: 1.
tempStr subStrings.
tempStr replaceFrom: 2 to: 3 with: 'bc' startingAt: 1.

'Programing > Smalltalk' 카테고리의 다른 글

Smalltalk의 TDD  (0) 2006.12.28
Smalltalk의 편리함과 백업의 중요성  (1) 2006.12.28
가계부 만들기 - 짧은숙제  (0) 2006.11.16
가계부 만들기 - 08  (0) 2006.11.16
가계부 만들기 - 07  (0) 2006.11.16
posted by 초딩입맛제주아재
2006. 11. 16. 22:24 Programing/Smalltalk
>1. Class Browser로 HouseKeepingBookShell 의 "Views/New..." 명령을 내려 새 View를 만들어 줍니다. View의 이름을 물어보면 'view 2'라고 입력합니다. View Composer를 보면 기존에 만들었던 View와 똑같이 생긴 View가 있음을 볼 수 있습니다. 이 View는 기존의 'Default view'라고 불리는 기본 View와는 별개의 복사본 View입니다. 그 View를 아무리 수정해도(심하면 망가먹어도), 'Default view'는 여전히 잘 동작하게 됩니다. 그러니, 마음 푹 놓으시고 수정하기 바랍니다. 폰트를 바꾼다거나 창의 크기나 색깔등등 마음껏 바꾼 다음 창을 띄워봅니다.

>\설명이 길었죠? 이제 문제입니다. Workspace에서 HouseKeepingBookShell 를 띄울 때 showOn: 를 썼었습니다. view 2 창으로 띄워보려면 어떤 매쏘드를 써야할까요? 찾아보세요.

>힌트: showOn:과 아주 비슷한 이름의 매쏘드입니다


show: aResourceNameString on: aModel

HouseKeepingBookShell show: 'view2' on:  testBook

>2. View Composer로 view 2를 편집해 봅시다. 기존에 있던 list box를 삭제합니다.(삭제하기 전에 그것의 name을 기억해 둡시다) list box가 있던 자리에 ListPresenter.Enhanced list view를 추가해 넣습니다. 그리고 name을 지운 list box의 것으로 고칩니다. 창을 다시 열어봅니다. 열린 모습을 캡처해서 답으로 제출!!




>3. list box 와는 다르게 list view 계열은 복수 컬럼을 지원하기에 알맞는 형태로 되어 있습니다. 추가한 list view를 선택하면 속성으로 columnsList가 보입니다. Collection형태로 되어 있어 list view의 컬럼을 추가 삭제 편집할 수 있습니다. 가계부 항목의 속성은 이름, 가격, 날짜입니다.

>3개의 컬럼을 만들어 가계부 항목의 내용이 표시될 수 있도록 수정헤요.

>힌트: List Box에서 했던 것과 매우 유사합니다.



HouseKeepingBookItem >>

displayItemString
^self name.

displayPriceString
^self value.

displayDateString

 |stream|

 stream := String writeStream.
 self date printOn: stream format: 'yyyy-MM-dd'.
^stream contents.


'Programing > Smalltalk' 카테고리의 다른 글

Smalltalk의 TDD  (0) 2006.12.28
Smalltalk의 편리함과 백업의 중요성  (1) 2006.12.28
가계부 만들기 - 08  (0) 2006.11.16
가계부 만들기 - 07  (0) 2006.11.16
가계부 만들기 - 06  (0) 2006.11.16
posted by 초딩입맛제주아재
2006. 11. 16. 22:19 Programing/Smalltalk
1. HouseKeepingBookCategoriesDialog 클래스를 만듭니다. 대략 다음과 같은 형태로 뷰를 디자인합니다.

분류 이름들로 이루어진 콤보박스 하나.

그 콤보박스에 바싹 붙은 버튼 세 개(각각, 추가, 삭제, 편집)

분류이름 콤보박스에 선택된 분류의 항목이름이 나열된 리스트박스 하나.

그 리스트박스에 바싹 붙은 버튼 세 개(각각, 추가, 삭제, 편집)




2. 콤보박스에 현재 존재하는 모든 분류를 표시하게 한다.


createComponents

  super createComponents.

  categoryName := self add: ListPresenter new name: 'category name'.
  categoryItem := self add: ListPresenter new name: 'category item'
.

model: aHouseKeepingBoolCategory

   super model: aHouseKeepingBoolCategory.

  categoryName model: (ListModel on: aHouseKeepingBoolCategory categories ).

"categoryName 의 model을 변경하면서 추가한 메서드"

Association >> stringTheCombobox >>

  ^self value.

위 메서드를 새로 만들어준다음 HouseKeepingBookCategoryDialog의 view에서

콤보박스(category name)의 getTextBlock속성에 #stringTheCombobox를 입력해줍니다.



3. 분류이름 콤보박스의 선택이 바뀌면, 항목이름 리스트박스가 그에 맞게 초기화 되도록 이벤트를 달아 줍니다.

model: aHouseKeepingBoolCategory

   categoryName when: #selectionChanged send: #changeItem to: self.




4. 분류 추가 버튼을 누르면, Prompter를 띄워 문자열을 받아 그 이름의 분류를 추가하는 기능을 넣습니다.

설명: Prompter는 Dialog의 일종으로서 보편적으로 많이 사용되는 문답 형태의 Dialog를 표준화시킨 객체입니다. 사용법은 비슷합니다.

addCategoryName

  |newCategoryName|
  newCategoryName := Prompter prompt: '추가할 카테고리 이름을 입력하세요.' caption: '카테고리 추가'.


   newCategoryName ifNotNil: [:value |
       categoryName model add: #()->value.
       categoryName selectionByIndex: categoryName  model  size.
  ].


5. 분류 삭제 버튼을 누르면, 콤보박스에서 그 항목을 삭제합니다. (항목이름 리스트박스는 텅 비게 되겠죠?)

deleteCategoryName

  |index|
   index := categoryName selectionByIndex.
   categoryName selectionByIndex: 1.
   categoryName model removeAtIndex: index.


queryCommand: aCommandQuery

  super queryCommand: aCommandQuery.

  (#(#deleteCategoryName) includes: aCommandQuery command) ifTrue: [
       aCommandQuery isEnabled: categoryName hasSelection].


6. 분류 편집 버튼을 누르면, 4번과 마찬가지로 Prompter를 띄워 현재 분류의 이름을 바꾸는 기능을 넣습니다.

editCategoryName

  |newCategoryName|
   newCategoryName := Prompter on: categoryName selection value  prompt: '원하시는 카테고리명을 입력해주세요.' caption: '카테고리 수정'.
   newCategoryName ifNotNil: [:value | (categoryName  model at: categoryName selectionByIndex) value: value ].

queryCommand: >>

(#(#editCategoryName) includes: aCommandQuery command) ifTrue: [
aCommandQuery isEnabled: categoryName hasSelection].


7. 4~6번과 마찬가지로 리스트박스에 대해서도 항목 추가, 삭제, 편집 버튼을 구현해 줍니다.

"항목 추가"

addCategoryItem

  newcategoryItem categoryNameModel|
  newCategoryItem := Prompter prompt: '추가할 항목을 입력하세요.' caption: '항목 추가'.
  categoryNameModel := (categoryName model select: [:each | each value = categoryName selection value ] ) at:1.

   newCategoryItem ifNotNil: [:value |
       categoryNameModel key: (categoryNameModel key,(Array with: value)).
       self changeItem.
    ].


"항목 삭제"

deleteCategoryItem

  |categoryNameModel|
   categoryNameModel := (categoryName model select: [:each | each value = categoryName selection value ]) at: 1.
   categoryNameModel key: (categoryNameModel key select: [:each | each ~= categoryItem selection]).

   self changeItem.

"항목 편집"

editCategoryItem

  |newCategoryItem categoryNameModel|
   newCategoryItem := Prompter on: categoryItem selection prompt: '원하시는 항목을 입력해주세요.' caption: '항목 수정'.

  categoryNameModel := categoryName  model at: categoryName selectionByIndex.
 
newCategoryItem ifNotNil: [:value |
       categoryNameModel key: ((categoryNameModel key select: [:each | each ~= categoryItem selection]) , (Array with: value)).
       self changeItem.
  ].


queryCommand >>추가

(#(#addCategoryItem) includes: aCommandQuery command) ifTrue: [
aCommandQuery isEnabled: categoryName hasSelection].

#(deleteCategoryItem editCategoryItem) includes: aCommandQuery command) ifTrue: [
aCommandQuery isEnabled: categoryItem hasSelection].


8.
HouseKeepingBookShell에 editCategories라는 메뉴를 만들어 HouseKeepingBookCategoriesDialog 을 띄울 수 있게 합니다.

editCategory

  |newCategories|

  newCategories := HouseKeepingBookCategoriesDialog showModalOn: self model categories.

  newCategories ifNotNil: [:value | self model categories: value].




9. HouseKeepingBookShell에 showItemCategory라는 메뉴를 만들어 선택한 항목의 분류를 MessageBox로 볼 수 있게 합니다.

showItemCategory

  MessageBox notify: (self model categories categoryNameOfItemName:  items selection name).


'Programing > Smalltalk' 카테고리의 다른 글

Smalltalk의 편리함과 백업의 중요성  (1) 2006.12.28
가계부 만들기 - 짧은숙제  (0) 2006.11.16
가계부 만들기 - 07  (0) 2006.11.16
가계부 만들기 - 06  (0) 2006.11.16
Array를 OrderedCollection으로 바꾸기  (0) 2006.11.02
posted by 초딩입맛제주아재
2006. 11. 16. 22:16 Programing/Smalltalk
1. Dialog 클래스 아래 HouseKeepingBookItemDialog라는 클래스를 만들고, View/New 하여 새 뷰를 만든다. 만들어진 뷰는 Shell의 뷰와는 모양이 조금 다를겁니다. 어떻게 다른가요?

Ok와 Cancel 버튼 두개가 만들어져 있습니다.

2. HouseKeepingBookItemDialog는 HouseKeepingBookItem 객체를 모델로 삼아  수정하는 Dialog가 될 것입니다. Shell에서 했던 것과 같은 방법으로 item의 name, value, date를 표현할 컨트롤들을 꾸며봅니다. (화면 캡쳐해주세요)
힌트: 
작성해야 할 매쏘드들 ...  model:   createComponents
사용할 클래스들 ... TextPresenter, DatePresenter, NumberPresenter
주의할 점: Date


createComponents

super createComponents.

namePresenter := self add: TextPresenter new name: 'name'.
valuePresenter := self add: NumberPresenter new name: 'value'.
datePresenter := self add: DatePresenter new name: 'date'.

model: aHouseKeepingBookItem

super model: aHouseKeepingBookItem.

namePresenter model: (self model aspectValue: #name).
valuePresenter model: (self model aspectValue: #value).
datePresenter model: (self model aspectValue: #date).


3. Workspace로 가서 간단한 테스트를 해봅시다.
myItem := HouseKeepingBookItem new.
HouseKeepingBookItemDialog showModalOn: myItem.

Dialog에 뭔가 적당한 값들을 기입해 줍니다. OK버튼을 누릅니다.
myItem의 값이 어떻게 되었나요?

입력한 값으로 바뀌었습니다.


4. Workspace로 가서 간단한 테스트를 해봅시다.
myItem := HouseKeepingBookItem new.
HouseKeepingBookItemDialog showModalOn: myItem.

Dialog에 뭔가 적당한 수정을 해 줍니다.
CANCEL버튼을 누릅니다.
myItem의 값이 어떻게 되었나요?

바뀌지 않았습니다.


5. HouseKeepingBookShell의 newItem매쏘드에서 임시 item을 생성했었죠? 이제, HouseKeepingBookItemDialog 가 있으니까, 정식으로 추가 할 수 있게 되었습니다.

HouseKeepingBookShell의 newItem매쏘드를 수정하여, 사용자가 입력한 값을 새 가계부 항목으로 등록하도록 수정하세요.

newItem
items model add:  (HouseKeepingBookItemDialog showModalOn: HouseKeepingBookItem new)


6. 5번 문제에서 사용자가 Cancel을 눌러버린다면? item을 추가하면 안되겠죠? newItem 매쏘드를 수정하여 그 기능을 추가하세요.

newItem

(HouseKeepingBookItemDialog showModalOn: HouseKeepingBookItem new)
ifNotNil: [:value | items model add: value].


7. IT에서 추가와 편집은 큰 차이가 없습니다. HouseKeepingBookShell에 편집메뉴명령을 추가하고 editItem 이라는 매쏘드에 그 기능을 구현하세요. 합산과 흑/적 상태가 바르게

바뀌도록 하세요. deleteItem과 마찬가지로 선택된 것이 없으면 수정할 수 없에 커맨드비활성화하는 것도 잊지마시고요.

queryCommand: aCommandQuery

super queryCommand: aCommandQuery.

#(deleteItem editItem) includes: aCommandQuery command)

  ifTrue: [aCommandQuery isEnabled: items hasSelection].

 

editItem

(HouseKeepingBookItemDialog showModalOn: ( items model at: items selectionByIndex ))
ifNotNil: [:value | items model updateItem: value]


model: 이벤트 추가

items model when: #item:updatedAtIndex: send: #refreshSumAndStatus to: self.


8. 추가와 수정이 아무리 흡사하더라도, 사용자가 구별할 수 있게 해줘야겠죠? 추가일 때는 Dialog의 제목이 '가계부 항목 추가'로, 수정일 때는 '가계부 항목 수정'으로 표시되게 하세요.
힌트: createOn:   caption:   showModal


HouseKeepingBookShell > newItem,editItem 메서드 수정

newItem

((HouseKeepingBookItemDialog createOn: HouseKeepingBookItem new) caption: '가계부 항목 추가'; showModal)
ifNotNil: [:value | items model add: value ].

editItem

((HouseKeepingBookItemDialog createOn: ( items model at: items selectionByIndex )) caption: '가계부 항목 수정'; showModal )
ifNotNil: [:value | items model updateItem: value].

'Programing > Smalltalk' 카테고리의 다른 글

가계부 만들기 - 짧은숙제  (0) 2006.11.16
가계부 만들기 - 08  (0) 2006.11.16
가계부 만들기 - 06  (0) 2006.11.16
Array를 OrderedCollection으로 바꾸기  (0) 2006.11.02
객체를 배열로 만들어주는 Array with:  (0) 2006.10.30
posted by 초딩입맛제주아재
2006. 11. 16. 22:10 Programing/Smalltalk
1. 가계부의 원금란을 수정하면, 합산을 표시하던 NumberPresenter와 흑자/적자를 표시하던 TextPresenter가 자동으로 갱신되도록 하세요. createSchematicWiring라는 매쏘드를 만들어서 두 Presenter사이의 관계를 지어주면 됩니다.

힌트: Shell의 상위 클래스인 Presenter 클래스에는 createSchematicWiring이라는 매쏘드가 있습니다. 이 매쏘드는 창이 처음 열릴때 한 번만 호출되며, 창 자신을 포함한 모든 하위창들 사이의 메세지 핸들링을 초기화합니다. 다른 사람들이 작성한 createSchematicWiring 매쏘드를 Method Browser로 검색해보시면, 대강 감이 오실 겁니다. 잘 모르겠으면, 메신저로 연락주세요. 추가 힌트 나갑니다.


createSchematicWiring

   super createSchematicWiring.

   pocketMoney when: #valueChanged send: #refreshSumAndStatus to: self.


2. View Composer를 열어서 HouseKeepingBookShell에 메뉴바를 추가합니다.

Item/New 메뉴를 만듭니다. (메뉴속성에서 command는 #newItem로 합니다)

showOn: 해서 메뉴를 테스트해봅니다. 메뉴의 상태가 어떻습니까?

힌트: View Composer를 열어서 Modify메뉴의 Menu Bar... 라는 명령을 실행합니다.


"New"항목이 비활성화 상태입니다...


3. Class Browser로 HouseKeepingBookShell에 newItem이라는 매쏘드를 만들어 줍니다.

showOn: 해서 메뉴를 테스트해봅니다. 메뉴의 상태가 어떻게 달라졌습니까?

"New"항목이 활성화 되었습니다.



4. 3번 문제에서 만든 newItem은 HouseKeepingBookShell의 메뉴가 선택되면 불리는 매쏘드 입니다. 이 매쏘드를 편집하여 '임시'라는 이름을 가진, 가격은 30인, 날짜는 오늘인 항목하나를 추가하게 합니다. 맞게 하셨다면, 항목추가와 함께 합산과 흑/적자 표시도 동시에 갱신됨을 확인하실 수 있습니다.

제약조건: 리스트컨트롤을 직접 제어하면 안되며, HouseKeepingBookShell의 모델을 수정한 다음, Shell로 하여금 재초기화 하도록 해야 함.

newItem 정의를 답으로 제출하세요.


newItem

items model add: (
  HouseKeepingBookItem new
   name: '임시';
   value: 30;
   date: Date today
).



5. View Composer를 열어서 Item/Delete 메뉴를 만듭니다. (메뉴속성에서 command는 #deleteItem로 합니다)

HouseKeepingBookShell에 deleteItem매쏘드를 두어, 리스트에 선택된 항목들을 지우게끔 하세요. 4번과 마찬가지로, 합산과  흑/적자 표시가 갱신될겁니다.

deleteItem 매쏘드를 답으로 제출하세요.

힌트:  selection , remove: , model:


deleteItem

items model removeAtIndex: items selectionByIndex.


4~5번 관련하여 이벤트를 통한 자동갱신을 위하여 model: 메서드를 수정하였습니다.

model:>>

items model: (ListModel on: aHouseKeepingBook items).
items model when: #item:addedAtIndex: send: #refreshSumAndStatus to: self.
items model when: #item:removedAtIndex: send: #refreshSumAndStatus to: self.

6. View Composer를 열어서 PushButton을 하나 추가해서, 클릭하면 4번과 같은 동작을 하게끔 하세요.

힌트: 클래스 소스는 일절 수정할 필요가 없습니다. 오로지 View Composer만으로 해낼 수 있습니다.

어떤 방법으로 해냈는지 설명하는 글을 답으로 제출하세요.

View Composer의 우측 하단 속성창에서

commandDescription > command: #newItem





7. View Composer를 열어서 PushButton을 하나 추가해서, 클릭하면 5번과 같은 동작을 하게끔 하세요.

힌트: 클래스 소스는 일절 수정할 필요가 없습니다. 오로지 View Composer만으로 해낼 수 있습니다.

어떤 방법으로 해냈는지 설명하는 글을 답으로 제출하세요.


commandDescription > command: #deleteItem




8. 가계부 item을 삭제하면, 리스트에서 다른 item을 선택하지 않은 채, 또 삭제를 시도해 보세요. 에러가 나죠?

에러가 나지 않게, 선택한 item이 없을 때는 메뉴를 비활성화 해야 합니다. queryCommand:라는 매쏘드를 작성하면 됩니다.

queryCommand: 를 검색해서 다른 사람들은 어떻게 작성했는지 참고하세요.

힌트:  isEnabled:  를 사용하면 됩니다.


queryCommand: aCommandQuery

   super queryCommand: aCommandQuery.

   (#(deleteItem) includes: aCommandQuery command)

       ifTrue: [aCommandQuery isEnabled: items hasSelection].



9. 8번에서 작업한 것이 버튼에 어떤 영향을 미쳤는지 보고하세요.

프로그램을 실행하면 삭제 버튼이 비활성화 되있습니다.

posted by 초딩입맛제주아재
2006. 10. 11. 11:00 Programing/Smalltalk
1. Shell 클래스 아래 HouseKeepingBookShell 클래스를 만듭니다.(이것은 MVP에서 P인 Presenter에 해당합니다)

Workspace에서 HouseKeepingBookShell showOn: testBook 을 실행해 봅니다.


창이 새로 열리죠? 그것을 캡쳐해서 올려주세요.






2. Class Browser의 클래스트리에서 HouseKeepingBookShell 의 팝업메뉴 View... / New를 합니다. (이것은 MVP에서 V인 View에 해당합니다) 이름은 그냥 기본으로 있는 Default View로 엔터누릅니다. View Composer가 열렸죠. 1번 문제에서 봤던 창이 있을 겁니다. 이 창을 편집한다는 소리죠. View Composer로 왼쪽에 뷰툴박스를 열어서 ListPresenter.Default View를 찾아 이 창에다 추가해줍니다.(끌어다놓기하면 됩니다) 오른쪽 하단의 속성창에서 name이라는 항목을 찾아 문자열로 book list 라고 이름 지어줍니다. View Composer를 저장하고 닫습니다.


Workspace에서 HouseKeepingBookShell showOn: testBook 을 실행해 봅니다.


창이 새로 열리죠? 그것을 캡쳐해서 올려주세요.


/



3. HouseKeepingBookShell 에 items라는 객체변수를 만듭니다. createComponents라는 매쏘드를 검색(Definitions of...)해 봅니다. 그 매쏘드들을 보고 흉내내서 ListPresenter를 만들어 items변수에 대입하세요. View Composer로 지어줬던 이름을 정확히 문자열로 제공해야 한다는 점을 유의하세요. 작성하신 createComponents 매쏘드를 답으로 제출해 주세요.


createComponents
super createComponents.

items := self add:  ListPresenter new name: 'book list'.


Workspace에서 HouseKeepingBookShell showOn: testBook 해서 다시 창을 열어봅니다. 리스트가 추가 되었나요? 캡쳐해서 답으로 제출하세요.


/



4. 그런데 리스트박스가 비어있군요. 내용을 표시해야 합니다.
HouseKeepingBookShell에 model: 이라는 매쏘드를 추가합니다. 이것도 역시 3번 문제와 마찬가지로 model:의 정의를 참고합니다. model: 매쏘드는 이 GUI객체(Shell)에 모델을 넘길 때, 그것을 받아들이는 매쏘드입니다. 문제 3번에서 추가한 리스트는 Shell의 하위창이었죠? 이 하위창도 역시 MVP구조로 되어있기 때문에 모델을 공급해줘야 제대로 동작합니다. 무엇을 넘겨주면 좋을까요?

items model: ????????????????


HouseKeepingBookShell>>model: 매쏘드를 작성한 것을 답으로 제출하세요.


model: aHouseKeepingBook
items model: aHouseKeepingBook items.


Workspace에서 HouseKeepingBookShell showOn: testBook 를 캡쳐해서 답으로 제출하세요.




5. 이제 하위 창을 하나 더 추가 하겠습니다. 방법은 2번~4번에서 했던 것과 마찬가지로 진행하시면됩니다. 객체변수 pocketMoney를 만듭니다. Class Composer의 클래스트리에서 팝업메뉴 View/Edit···· 해서 View Composer를 엽니다. 뷰툴박스에서 NumberPresenter.Default View를 추가하고 이름을 pocket money로 짓고 저장한다음, HouseKeepingBookShell에서 createComponents매쏘드와 model:매쏘드를 수정해서 새 객체변수 pocketMoney도 items처럼 수정해줍니다.


수정된 createComponents매쏘드와 model:매쏘드를 답으로 제출하세요.


pocketMoney := self add: TextPresenter new name: 'pocket money'.


pocketMoney model: aHouseKeepingBook pocketMoney.



Workspace에서 HouseKeepingBookShell showOn: testBook 를 하여 원금과 가계부 항목이 잘 표시된 모습을 캡쳐해서 답으로 제출하세요.





6. 리스트에 아마 an HouseKeepingBookItem이라고만 표시되고 있을 겁니다. 그것은 리스트에게 받은 객체들을 어떤 형태로 표현할 지 말해주지 않았기 때문에 기본적으로 표시되는 문자열만 뵤여주고 있기 때문입니다. 다시 View Composer를 열어서 book list라는 리스트를 선택하면 오른쪽에서 속성으로 getTextBlock이라고 있습니다. selector에 #displayString이라고 되어 있을 겁니다. 그걸 #stringInTheListBox'라고 고쳐주고 저장한다음 View Composer를 닫습니다. 그런 다음 다시 showOn:해서 창을 열어봅니다. 에러가 날 겁니다. 디버거로 매쏘드를 추가하는 방법 기억하시죠? 그 방법으로 HouseKeepingBookItem에 매쏘드를 만들어줍니다. 방금 만든 그 매쏘드는 리스트가 자신의 아이템들인 HouseKeepingBook객체들에게 표시할 문자열을 요구하는 매쏘드입니다. HouseKeepingBookItem의 name과 value를 문자열로 답하는 매쏘드를 작성해보세요.(숙제하는 사람 마음대로) 다시 showOn:합니다.


HouseKeepingBookItems>>stringInTheListBox 매쏘드를 답으로 제출하세요.


stringInTheListBox
^self name,' : ',self value printString


showOn: 하여 리스트에 항목들이 제대로 표시된 모습을 캡처해서 제출하세요.





7. 합산을 표시하는 작은 창도 만들어 보겠습니다. View Composer를 열어 NumberPresenter.Default View를 추가하여 sum이라고 이름 짓습니다.
HouseKeepingBookShell에 sum이라는 객체변수를 만들고 createComponents와 model: 매쏘드를 다시 수정합니다. 모델인 HouseKeepingBook객체에게 sum을 물어서 그 것을 HouseKeepingBookShell의 sum에게 모델로 넘겨주면 되겠군요.


createComponents, model: 를 답으로 제출하세요.


sum := self add: NumberPresenter new name: 'sum'.

sum model: aHouseKeepingBook sum.


합산이 잘 표시된 창을 캡처해서 답으로 제출하세요.




8. 흑자와 적자를 표시하는 창도 만들어 보겠습니다. View Composer를 열어 TextPresenter.Stati text를 추가하여 status이라고 이름 짓습니다.
HouseKeepingBookShell에 status이라는 객체변수를 만들고 createComponents와 model: 매쏘드를 다시 수정합니다. 모델인 HouseKeepingBook객체에게 흑자인지 적자인지 문자열로 답해주는(그런 매쏘드가 있었지요?) 그것을 HouseKeepingBookShell의 status에게 모델로 넘겨주면 되겠군요.


createComponents, model: 를 답으로 제출하세요.


status := self add: TextPresenter new name: 'status'.

status model: aHouseKeepingBook statusString.



흑자/적자가 잘 표시된 창을 캡처해서 답으로 제출하세요.



posted by 초딩입맛제주아재
2006. 10. 9. 10:15 Programing/Smalltalk

payroll := OrderedCollection new.

attendanceDate := Date fromString: '2006-10-1'.
attendanceTime := Time fromString: '10:00'.
attendanceDateTime := TimeStamp date: attendanceDate time: attendanceTime.

finishDate := Date fromString: '2006-10-1'.
finishTime := Time fromString: '19:00'.
finishDateTime := TimeStamp date: finishDate time: finishTime.


날짜와 시간으로 출근시간과 퇴근시간에 해당하는 timestamp 를 만들어서
patroll 에 한쌍으로 묶어서 넣으려고 하는데 들어가질 않습니다.

자동완성이 되지 않아 직접 타이핑으로
payroll add: #(attendanceDateTime finishDateTime).
입력을 했더니 입력은 됐으나 이상한 형태로 되었더군요.

#(#attendanceDateTime #finishDateTime)

어떠한 형태의 객체도 다 포함하는 줄 알았던 컬렉션 객체가 말썽을 부리니
멍해지네요 -_-;;

달룟님의 답변

지적하신 부분은 "어떠한 객체도 다 담을 수 있다."와는 상관이 없습니다. Smalltalk문법에서 #(변수명, 변수명) 는 허용되지 않는 표현입니다. #(표현식, 표현식) 역시 마찬가지입니다. #()속에는 literal만 올 수 있습니다. 이 부분은 Ruby에 비해서 불편한 점으로, Smalltalker들 중에는 이 문법을 고치자는 주장도 나오고 있습니다.
파란글씨로 표시된 것처럼, Symbol객체 2개로 된 배열로 인식됩니다. 컴파일된 소스색깔을 보시면 변수명이 아니라 literal로서 컴파일 되었음을 알 수 있습니다.

원하시는 표현은 Array with: attendanceDateTime with: finishDateTime 입니다.


#()는 Array객체를 간략한 표현으로 생성하는 문법입니다. #()로 OrderedCollection객체를 만들 수는 없습니다. 변환은 가능하죠.

#(1 2 3) asOrderedCollection.

혹은

OrderedCollection withAll: #(1 2 3).

with:with:는 Collection 클래스에 있는 매쏘드이기 때문에 Array, OrderedCollection모두 쓸 수 있습니다.

OrderedCollection with: attendanceDateTime with: finishDateTime.

이라고 하면 되죠.



이렇게 하니 된다.

payroll add: (Array with: attendanceDateTime with: finishDateTime).
payroll size. > 1
(payroll at: 1) size. > 2


Collection >> OrderedCollection,Array,SortedCollection...

'Programing > Smalltalk' 카테고리의 다른 글

사용자의 실수를 막아주는 queryCommand:  (0) 2006.10.28
가계부 만들기 - 05  (0) 2006.10.11
가계부 만들기 - 04  (0) 2006.10.08
가계부 만들기 - 03  (0) 2006.10.08
가계부 만들기 - 02  (0) 2006.10.08
posted by 초딩입맛제주아재
2006. 10. 8. 15:21 Programing/Smalltalk
- GUI 만들기 -


1.
Shell 클래스 아래 HouseKeepingBookShell 클래스를 만듭니다.(이것은 MVP에서 P인 Presenter에 해당합니다)

Workspace에서 HouseKeepingBookShell showOn: testBook 을 실행해 봅니다.


창이 새로 열리죠? 그것을 캡쳐해서 올려주세요.






2. Class Browser의 클래스트리에서 HouseKeepingBookShell 의 팝업메뉴 View... / New를 합니다. (이것은 MVP에서 V인 View에 해당합니다) 이름은 그냥 기본으로 있는 Default View로 엔터누릅니다. View Composer가 열렸죠. 1번 문제에서 봤던 창이 있을 겁니다. 이 창을 편집한다는 소리죠. View Composer로 왼쪽에 뷰툴박스를 열어서 ListPresenter.Default View를 찾아 이 창에다 추가해줍니다.(끌어다놓기하면 됩니다) 오른쪽 하단의 속성창에서 name이라는 항목을 찾아 문자열로 book list 라고 이름 지어줍니다. View Composer를 저장하고 닫습니다.


Workspace에서 HouseKeepingBookShell showOn: testBook 을 실행해 봅니다.


창이 새로 열리죠? 그것을 캡쳐해서 올려주세요.




3. HouseKeepingBookShell 에 items라는 객체변수를 만듭니다. createComponents라는 매쏘드를 검색(Definitions of...)해 봅니다. 그 매쏘드들을 보고 흉내내서 ListPresenter를 만들어 items변수에 대입하세요. View Composer로 지어줬던 이름을 정확히 문자열로 제공해야 한다는 점을 유의하세요. 작성하신 createComponents 매쏘드를 답으로 제출해 주세요.


createComponents
super createComponents.

items := self add:  ListPresenter new name: 'book list'.


Workspace에서 HouseKeepingBookShell showOn: testBook 해서 다시 창을 열어봅니다. 리스트가 추가 되었나요? 캡쳐해서 답으로 제출하세요.




4. 그런데 리스트박스가 비어있군요. 내용을 표시해야 합니다.
HouseKeepingBookShell에 model: 이라는 매쏘드를 추가합니다. 이것도 역시 3번 문제와 마찬가지로 model:의 정의를 참고합니다. model: 매쏘드는 이 GUI객체(Shell)에 모델을 넘길 때, 그것을 받아들이는 매쏘드입니다. 문제 3번에서 추가한 리스트는 Shell의 하위창이었죠? 이 하위창도 역시 MVP구조로 되어있기 때문에 모델을 공급해줘야 제대로 동작합니다. 무엇을 넘겨주면 좋을까요?

items model: ????????????????


HouseKeepingBookShell>>model: 매쏘드를 작성한 것을 답으로 제출하세요.


model: aHouseKeepingBook
items model: aHouseKeepingBook items.


Workspace에서 HouseKeepingBookShell showOn: testBook 를 캡쳐해서 답으로 제출하세요.





5. 이제 하위 창을 하나 더 추가 하겠습니다. 방법은 2번~4번에서 했던 것과 마찬가지로 진행하시면됩니다. 객체변수 pocketMoney를 만듭니다. Class Composer의 클래스트리에서 팝업메뉴 View/Edit···· 해서 View Composer를 엽니다. 뷰툴박스에서 NumberPresenter.Default View를 추가하고 이름을 pocket money로 짓고 저장한다음, HouseKeepingBookShell에서 createComponents매쏘드와 model:매쏘드를 수정해서 새 객체변수 pocketMoney도 items처럼 수정해줍니다.


수정된 createComponents매쏘드와 model:매쏘드를 답으로 제출하세요.


pocketMoney := self add: TextPresenter new name: 'pocket money'.


pocketMoney model: aHouseKeepingBook pocketMoney.



Workspace에서 HouseKeepingBookShell showOn: testBook 를 하여 원금과 가계부 항목이 잘 표시된 모습을 캡쳐해서 답으로 제출하세요.





6. 리스트에 아마 an HouseKeepingBookItem이라고만 표시되고 있을 겁니다. 그것은 리스트에게 받은 객체들을 어떤 형태로 표현할 지 말해주지 않았기 때문에 기본적으로 표시되는 문자열만 뵤여주고 있기 때문입니다. 다시 View Composer를 열어서 book list라는 리스트를 선택하면 오른쪽에서 속성으로 getTextBlock이라고 있습니다. selector에 #displayString이라고 되어 있을 겁니다. 그걸 #stringInTheListBox'라고 고쳐주고 저장한다음 View Composer를 닫습니다. 그런 다음 다시 showOn:해서 창을 열어봅니다. 에러가 날 겁니다. 디버거로 매쏘드를 추가하는 방법 기억하시죠? 그 방법으로 HouseKeepingBookItem에 매쏘드를 만들어줍니다. 방금 만든 그 매쏘드는 리스트가 자신의 아이템들인 HouseKeepingBook객체들에게 표시할 문자열을 요구하는 매쏘드입니다. HouseKeepingBookItem의 name과 value를 문자열로 답하는 매쏘드를 작성해보세요.(숙제하는 사람 마음대로) 다시 showOn:합니다.


HouseKeepingBookItems>>stringInTheListBox 매쏘드를 답으로 제출하세요.


stringInTheListBox
^self name,' : ',self value printString


showOn: 하여 리스트에 항목들이 제대로 표시된 모습을 캡처해서 제출하세요.





7. 합산을 표시하는 작은 창도 만들어 보겠습니다. View Composer를 열어 NumberPresenter.Default View를 추가하여 sum이라고 이름 짓습니다.
HouseKeepingBookShell에 sum이라는 객체변수를 만들고 createComponents와 model: 매쏘드를 다시 수정합니다. 모델인 HouseKeepingBook객체에게 sum을 물어서 그 것을 HouseKeepingBookShell의 sum에게 모델로 넘겨주면 되겠군요.


createComponents, model: 를 답으로 제출하세요.


sum := self add: NumberPresenter new name: 'sum'.

sum model: aHouseKeepingBook sum.



합산이 잘 표시된 창을 캡처해서 답으로 제출하세요.




8. 흑자와 적자를 표시하는 창도 만들어 보겠습니다. View Composer를 열어 TextPresenter.Stati text를 추가하여 status이라고 이름 짓습니다.
HouseKeepingBookShell에 status이라는 객체변수를 만들고 createComponents와 model: 매쏘드를 다시 수정합니다. 모델인 HouseKeepingBook객체에게 흑자인지 적자인지 문자열로 답해주는(그런 매쏘드가 있었지요?) 그것을 HouseKeepingBookShell의 status에게 모델로 넘겨주면 되겠군요.


createComponents, model: 를 답으로 제출하세요.


status := self add: TextPresenter new name: 'status'.

status model: aHouseKeepingBook statusString.



흑자/적자가 잘 표시된 창을 캡처해서 답으로 제출하세요.




'Programing > Smalltalk' 카테고리의 다른 글

가계부 만들기 - 05  (0) 2006.10.11
변수 이름으로 배열 만들기 - Array with: 변수명 with: 변수명  (0) 2006.10.09
가계부 만들기 - 03  (0) 2006.10.08
가계부 만들기 - 02  (0) 2006.10.08
가계부 만들기 - 01  (0) 2006.10.08
posted by 초딩입맛제주아재
2006. 10. 8. 15:16 Programing/Smalltalk

1. Class Browser로 Object의 하위 클래스로 HouseKeepingBookItem 클래스를 만드세요.
    객체변수는 name value date 3개입니다.
    아무런 매쏘드도 없는 빈 껍데기 클래스입니다.

Object subclass: #HouseKeepingBookItem
instanceVariableNames: 'name value date'
classVariableNames: ''
poolDictionaries: ''
classInstanceVariableNames: ''


2. 다음을 실행하세요

testItem := HouseKeepingBookItem new.
testItem name: '스포츠신문'.

에러가 납니까? 당연합니다! HouseKeepingBookItem에 name: 이라는 매쏘드를 안만들어 줬으니까요. "Debug"버튼을 누릅니다. 디버깅 창의 왼쪽 상단 리스트에 팝업메뉴를 불러 "implement·······"메뉴를 고릅니다. 어떤 클래스에다 만들지 물어보네요. 답해줍니다.
임시 매쏘드가 만들어졌을 겁니다. 객체변수 name에 인자를 저장하는 매쏘드로 바꿔주고 accept(Ctrl+S)해줍니다.

testItem name: '스포츠신문'.를 다시 한번 해봅니다. 에러가 납니까?

name: aString

name := aString.


3.
다음의 문장들도 하나씩 실행하고 2번과 같이 매쏘드를 만들어줍니다.

testItem value: 500.
testItem date: Date today.
testItem name.
testItem value.
testItem date.

name
^name

value: anInteger
value := anInteger.

value
^value

date: aDate
date := aDate.

date
^date


4.
기존에 Workspace에 housekeepingbook에 저장되어있던 항목들(OrderedCollection type)을 전부 HouseKeepingBookItem 객체로 대체합니다.

housekeepingbook := housekeepingbook collect: [:item| ?????????? ].
??????????에 들어갈 적당한 표현식을 찾으세요.

housekeepingbook := housekeepingbookcollect: [ :each |
         HouseKeepingBookItem  new
                name: (each at: 1);
                value: (each at: 2);
                date: (each at: 3)
].


5.
숙제 1과 2의 문제들을 다 다시 작성해보세요.^^(놀라지 마시고 살짝씩만 바꿔주면 됩니다.) 기존에 OrderedCollection을 쓸 때와 비교했을 때 어떤 점이 달라졌는지 느낌 점을 말씀해주세요.

원하는 값에 바로 접근이 가능해진것 같아요...
마치 연관배열처럼 키값에 의한 access 같은...좀더 편해졌다고 할까요..


6. Class Browser로 Object의 하위 클래스로 HouseKeepingBook 클래스를 만드세요.
    객체변수는 pocketMoney items 2개 입니다.
    아무런 매쏘드도 없는 빈 껍데기 클래스입니다.

Workspace에 있는 변수들 pocketMoney와 housekeepingbook을 각각 testBook의 pocketMoney와 items에 담습니다. 2번과 같은 방법으로 하시면 됩니다.

Object subclass: #HouseKeepingBook
instanceVariableNames: 'pocketMoney items'
classVariableNames: ''
poolDictionaries: ''
classInstanceVariableNames: ''

items: aItem
items := aItem.

items
^items.

pocketMoney: aInteger
pocketMoney := aInteger.

pocketMoney
^pocketMoney.


7. HouseKeepingBook 에 sum 이라는 매쏘드를 만들어서 금액의 총합을 리턴하게 하세요. (원금을 포함하도록 하세요)

sum

^self items inject: pocketMoney into: [
:sum :item |
sum + (item value)
]


8. HouseKeepingBook 에 본인이 흑자인지 물어보는 isSurplus라는 매쏘드를 만드세요. true/false를 리턴해야 합니다. 7번 문제의 sum 매쏘드를 사용해야 합니다.

isSurplus

^(self sum > 0)


9. HouseKeepingBook 에 statusString라는 매쏘드를 만들어, 흑자면, '아싸! 흑자' 적자면 '에고... 적자'라는 문자열을 답하게 하세요. 8번 문제의 isSurplus를 사용해야 합니다.

statusString

self isSurplus ifTrue: [^'아싸!흑자'] ifFalse: [^'에고...적자']


10.
HouseKeepingBook 에 itemsOfYear: 라는 매쏘드를 만들어, 그 해의 항목들을 답하도록 하세요. 숙제 2의 답을 활용하세요.

itemsOfYear: aYear

^self items select: [:each | each date year = aYear]



11. HouseKeepingBook 에 sumOfYear: 라는 매쏘드를 만들어, 그 해 항목들의 합을 답하도록 하세요. itemsOfYear: 매쏘드를 활용하세요. (원금은 포함하지 않습니다)

sumOfYear: aYear

^(self itemsOfYear: aYear) inject: 0 into: [:sum :item | sum + (item value)]

posted by 초딩입맛제주아재
2006. 10. 8. 15:13 Programing/Smalltalk

WorkSpace 에서 끄적거리기 두번째....

select: 의 활용

housekeepingbook := OrderedCollection  new.

housekeepingbook
add: #('복권' -5000 '2005-09-21') asOrderedCollection;
add: #('복권당첨' 50000 '2006-09-21') asOrderedCollection;
add: #('두부' -500 '2006-09-22') asOrderedCollection;
add: #('피자' -15000 '2006-09-23') asOrderedCollection;
add: #('보너스' 100000 '2004-09-24') asOrderedCollection;
add: #('화장지' -7000 '2006-09-24') asOrderedCollection;
add: #('전기세' -25000 '2006-09-24') asOrderedCollection;
add: #('키보드' -15000 '2005-09-25') asOrderedCollection;
add: #('화장품' -55000 '2006-09-25') asOrderedCollection;
add: #('전구' -500 '2004-09-26') asOrderedCollection.

"1.housekeepingbook의 3번째 원소를 Date객체로 바꾸기"
housekeepingbook do: [:each | each at: 3 put: (Date fromString: (each at: 3))].

"2.2004년 항목만 추출"
housekeepingbook select: [:each | (each at: 3) year = 2004].

"3.2004년의 금액 합계"
(housekeepingbook select: [:each | (each at: 3) year = 2004]) inject: 0 into: [:sum :item|  sum + (item at: 2) ].

"4.각 항목들의 요일"
housekeepingbook collect: [:each | (each at: 3) weekday].


"5.category 객체 생성 & 전기세의 항목 이름"
categories := OrderedCollection new.
categories
add: #('두부' '피자' '김치') -> '식료품';
add: #('복권' '복권당첨' '적금') -> '투자';
add: #('월급' '보너스') -> '급여';
add: #('전기세' '수도세') -> '생활요금';
add: #('화장지' '키보드' '화장품' '전구') -> '소모품'.

(categories detect: [:each | each key includes: '전기세']) value.

"6.각 항목의 분류"
housekeepingbook collect: [:item | (categories detect: [:each | each key includes: (item at: 1) ]) value].

"7.소모품으로 분류되는 항목의 합"
(housekeepingbook select: [:each | (categories detect: [:cat | cat value = '소모품']) key includes: (each at: 1) ])
inject: 0 into: [:sum :item | sum + (item at: 2)].

"8.2006년의 소모품의 합"
((housekeepingbook select: [:each | (categories detect: [:cat | cat value = '소모품']) key includes: (each at: 1) ])
select: [:each | (each at: 3) year = 2006]) inject: 0 into: [:sum :item | sum + (item at: 2) ].

"9.원금"
pocketMoney := 4000000.
housekeepingbook inject: pocketMoney into: [:sum :item | sum + (item at: 2) ].

'Programing > Smalltalk' 카테고리의 다른 글

가계부 만들기 - 04  (0) 2006.10.08
가계부 만들기 - 03  (0) 2006.10.08
가계부 만들기 - 01  (0) 2006.10.08
변수와 메세지 그리고 이벤트...  (0) 2006.05.15
재밌다...  (0) 2006.05.07
posted by 초딩입맛제주아재
prev 1 2 next