배고파배고파배고파 점심으로 꼬마김밥 5줄 먹었으니까 고플만했다.... 그땐 불렀어

 

아 오늘 뭐 했지

 

어제 했었던 SwiftData(현재 자료 별로 없음) 실습 강사님 하시는 거 보고 따라 했다. 영어 울렁증을 좀 어떻게 해야 가혹한 애플 생태계에서 살아남을 수 있을 것 같다. 뭐 문법 바뀌는 속도가 통장잔고 바닥나는 속도여...

 

배가 너무 고파서 글이 안 써진다... 드립이 안쳐진다... 드립 치지 말고 공부한 걸 쓰라고 젠장

 

교재가 Swift Cookbook으로 바뀌어서 강의 초반에 배운 기능들 실습하면서 복습도 하고 그랬다. 역시 많이 써보는 게 이해하는데 가장 쉬운 것 같다. 

 

코드랑 주석이랑 다 노션에 정리해 놨더니 글쓰기가 애매하다... 저번에 그냥 긁어왔더니 그냥 레이아웃이 작살이 났던 슬픈... 과거가 있어요

 

아 어제 멘토링했는데 알고리즘 문제 푸는 거는 함수 메서드 같은 거 신경 쓰지 말고 일단 풀어보고 다른 코드 보고 하라고 하셨다. 프로그래머스... 다른 코드 보기로 내 코드 까발려지는 게 싫어서 손이 더 안 갔었는데, 역시 안 하는 것보단 죽이 돼도 하는 게 맞다. 

 

 

뭔가 영양가 있는 글을 쓰지를 않으니까 조건 돼도 광고 수익 신청하면 안 될 거 같다... 양심의 문제인가

뭐 어차피 볼 사람도 없는 광곤데 뭐 내가 많이 보...기 싫어...

아 진짜 오늘 늦잠 자서 모자 뒤집어쓰고 오전 강의 듣다가 오후 수업 10분 전에 내가 실습팀 팀장인 거 보고 머리만 후딱 감고 왔다... 

팀플을 많이 해봤다고는 못하지만 조금 해봤다고도 못하는데 이렇게 아무것도 못해보고 팀장을 점지당한 건 처음인 듯

 

레포지토리도 오랜만에 만들어보고... 권한 설정도 해보고... 아 뭐 2단계 인증 업그레이드 하고 처음 한 거라 앱으로 인증받으라는 건 좀 신기했다. 

 

오늘의 실습은 계산기 만들기.

 

할 줄을 몰라서 버튼 다 노가다해서 찍었는데 강사님이 이중배열 for문 돌려버리시는 거 보고 이마를 탁 쳤다. 

그래도 사랑한단다 내 코드야......

물론 이렇게 두 번 짜고 싶진 않지만

 

일단 오늘까지 만든 건 무식하게 조건 다 때려 박아서 계산이 되긴 하는데, 하나 이상의 연산자를 못 넣는다... 이것만 고치면 난 성불할 수 있을 텐데

 

젠장 팀장이 되어버렸으니 어떻게든 해야 한다... 뭔 말이든 채팅창에 뱉어보고 있다. 

 

크흑 배고파 이만 줄이고 그제 충동구매한 엽떡맛? 포테토칩이나 먹어야지

그리고 검도 갔다 와서 오빠가 저녁 갖고 오면 먹고 안 갖고 오면... 슬프고 ;-;

그리고 프로그래머스 풀고 스듀 하고 자야지라고 생각했는데 왤케 빡세 이거

늘은 17일차

 

오늘부터 프로그래머스에서 문제 풀이를 시작했다!

 

...근데 0단계부터

ㅎ...

1단계 5문제는 풀어야 AI가 문제 추천을 해준다는데, 다 까먹고 0단계도 버벅거리는(사실 스위프트 문법을 몰라서) 나에겐 0단계가 딱인 것이다. 

알고리즘은 알지 그걸 스위프트로 어떻게 써야 하는지를 모르지...

 

우리의 챗GPT ? 친구 : 원수 가 많이 도와줬다. 

 

문제 풀면서 노션에 정리해 놨는데 그냥 복붙 해야겠다ㅎㅎ

 

아 근데 왜 노션 자꾸 그램에서 로그아웃되냐... 맥북은 걍 유지 잘되던데

 

 


  1. https://school.programmers.co.kr/learn/courses/30/lessons/181944

홀짝 출력

 

 

내 코드

import Foundation

let a = Int(readLine()!)!

if a % 2 == 0 {
    print("\\(a) is even")
} else if a % 2 == 1 {
    print("\\(a) is odd")
}

 

다른 코드

import Foundation

let a = Int(readLine()!)!
print(a, "is", a % 2 == 0 ? "even" : "odd")

디테일은 다 달라도 삼항연산자 쓰는 게 좀 더 깔끔해 보인다.

 

 

 

2. 

https://school.programmers.co.kr/learn/courses/30/lessons/181950

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문자열 숫자 입력받아서 숫자 번 만큼 문자열 반복출력

 

 

내 코드

import Foundation

let inp = readLine()!.components(separatedBy: [" "]).map { $0 }
let (s1, a) = (inp[0], Int(inp[1])!)
var resultStr: String = ""

for _ in 0 ..< a {
    resultStr += s1
}

print(resultStr)

 

다른 코드

import Foundation

let inp = readLine()!.components(separatedBy: [" "]).map { $0 }
let (s1, a) = (inp[0], Int(inp[1])!)

print(String(repeating: s1, count: a))

 

- 챗 gpt의 해설

 

이 코드는 사용자로부터 문자열과 숫자를 입력 받아서 입력한 문자열을 입력한 숫자만큼 반복해서 출력하는 기능을 수행합니다.

  1. import Foundation: Foundation 프레임워크를 가져옵니다. 이 프레임워크는 Swift에서 문자열 다루기와 같은 작업을 수행하는 데 도움이 됩니다.
  2. let inp = readLine()!.components(separatedBy: [" "]).map { $0 }: readLine() 함수를 사용하여 사용자로부터 입력을 받습니다. 입력은 공백으로 구분된 문자열과 숫자여야 합니다. components(separatedBy: [" "])를 사용하여 입력된 문자열을 공백을 기준으로 나눕니다. map { $0 }를 사용하여 나눠진 문자열을 배열로 만듭니다.
  3. (s1, a) = (inp[0], Int(inp[1])!): inp 배열의 첫 번째 요소는 문자열이므로 s1에 저장하고, 두 번째 요소는 숫자로 변환하여 a에 저장합니다. 이때 Int() 함수를 사용하여 문자열을 정수로 변환합니다. 사용자가 유효한 숫자를 입력하지 않으면 오류가 발생할 수 있으므로 !를 사용하여 옵셔널 해제를 수행합니다.
  4. String(repeating: s1, count: a): 입력한 문자열 s1을 입력한 숫자 a번 만큼 반복하여 새로운 문자열을 생성합니다.
  5. print(...): 생성된 문자열을 출력합니다.

4번 추가 해설

네, String(repeating: s1, count: a) 부분은 문자열을 반복해서 생성하는 역할을 합니다. 이것은 Swift의 String 클래스의 생성자를 사용하여 수행됩니다.

  • repeating: 반복할 문자열을 지정합니다. 이 경우에는 입력된 문자열 s1이 사용됩니다.
  • count: 반복 횟수를 지정합니다. 이 경우에는 입력된 숫자 a가 사용됩니다.

따라서 String(repeating: s1, count: a)는 입력된 문자열 s1을 입력된 숫자 a번 반복하여 새로운 문자열을 생성합니다. 이후 print 함수를 사용하여 생성된 문자열을 출력합니다.

 

 

 

3. 

https://school.programmers.co.kr/learn/courses/30/lessons/120820

이런 무친 문제

TC에서 시간초과 났다 이게 맞나

그래도 하나... 만 났긴 하다

 

나이 구하기 문제

 

 

실패(1개)한 코드

import Foundation

func solution(_ age:Int) -> Int {
    return 2022 - age + 1
}

 

통과한 코드

import Foundation

func solution(_ age:Int) -> Int {
    return (2022 - age + 1)
}

 

- 왜 위는 되고 아래는 안 됐냐에 대한 챗 gpt의 해설:

두 코드는 사실적으로 동일한 동작을 합니다. 따라서 두 코드 중 하나가 시간 초과되고 다른 하나가 그렇지 않는 것은 기술적으로 설명하기 어렵습니다.

이러한 상황에서 코드의 변경이 시간 초과 문제를 해결했다면, 이는 아마도 다른 요인에 의해 발생한 것이었을 것입니다. 예를 들어, 코드의 컴파일 시간, 테스트 환경의 변경, 또는 다른 부분에서 발생한 영향 등이 그럴 수 있습니다.

이러한 상황에서는 코드의 변경이 실제로 시간 초과 문제를 해결했는지 확인하기 위해 여러 번 실행하여 결과를 확인하는 것이 좋습니다. 그리고 가능하다면 코드의 변경 없이도 문제를 해결할 수 있는지 확인하는 것도 좋은 방법입니다.

  • 챗 gpt의 해결방안

시간 초과 문제를 해결하는 방법은 코드를 최적화하여 실행 시간을 단축하는 것입니다. 이를 위해 다음과 같은 방법을 고려할 수 있습니다.

  1. 효율적인 알고리즘 선택: 시간 복잡도가 낮은 알고리즘을 선택하여 문제를 해결할 수 있습니다. 이를 위해 문제의 특성을 고려하고 효율적인 알고리즘을 구현해야 합니다.
  2. 불필요한 연산 최소화: 코드 내에서 불필요한 연산을 최소화하여 실행 시간을 단축할 수 있습니다. 불필요한 루프나 중복된 연산 등을 피하도록 코드를 작성해야 합니다.
  3. 메모리 사용 최적화: 너무 많은 메모리를 사용하거나 메모리를 불필요하게 할당하는 것도 시간 초과의 원인이 될 수 있습니다. 따라서 메모리 사용을 최적화하여 문제를 해결해야 합니다.
  4. 입출력 최적화: 입력과 출력 작업이 코드 실행 시간에 영향을 줄 수 있습니다. 입력을 한 번에 처리하거나 출력을 최소화하여 실행 시간을 단축할 수 있습니다.
  5. 테스트 및 프로파일링: 코드를 여러 번 실행하고 실행 시간을 측정하여 어떤 부분이 시간을 많이 소비하는지 확인하는 것이 중요합니다. 이를 통해 코드를 개선할 수 있는 지점을 찾을 수 있습니다.

위의 방법들을 고려하여 코드를 최적화하고, 문제를 해결할 수 있을 것입니다. 하지만 가장 효과적인 최적화 방법은 문제의 성격과 코드의 특성을 고려하여 실질적으로 테스트하고 실험하는 것입니다.

 

그냥 운이 없었다고 봐도 될 것 같다. 다만 평균 실행 시간이 간당간당 하다는 거니까 좀 더 효율적인 코드로 바꾸면 좋을 것 같다. 사실 효율적으로 코드를 바꿔달라고 말한 건데 챗gpt가 나한테 짬처리했다. 

 

 

 

4. https://school.programmers.co.kr/learn/courses/30/lessons/120806

‘정수’ 두 개 받고 나눠서 1000 곱하고 정수 부분만 출력

받은 정수를 실수로 만든다는 생각을 못해서 형변환 안 하고 시간낭비 오지게 했다

 

 

내 코드

import Foundation

func solution(_ num1:Int, _ num2:Int) -> Int {
    return Int((Double(num1) / Double(num2)) * 1000)
}

 

다른 코드

import Foundation

func solution(_ num1:Int, _ num2:Int) -> Int {
    return num1*1000/num2
}

 

이건 진짜 보고 감탄했다. 

와 이걸 뻥튀기를 먼저 해서 나눠버리네

 

 

 

5. 

https://school.programmers.co.kr/learn/courses/30/lessons/120829

각도기(각도 별 출력)

 

 

틀린 코드

import Foundation

func solution(_ angle:Int) -> Int {
    switch angle {
        case angle > 0 && angle < 90:
        return 1
        case angle == 90:
        return 2
        case angle > 90 && angle < 180:
        return 3
        case angle == 180:
        return 4
    }
}

 

다시 짰던(틀린) 코드

import Foundation

func solution(_ angle:Int) -> Int {
    switch angle {
        case 1 ..< 90:
        return 1
        case 90:
        return 2
        case 91 ..< 180:
        return 3
        case 180:
        return 4
    }
}

default 안 써서 틀림..

 

성공한(마참내!) 코드

import Foundation

func solution(_ angle:Int) -> Int {
    switch angle {
        case 1 ..< 90:
        return 1
        case 90:
        return 2
        case 91 ..< 180:
        return 3
        case 180:
        return 4
        default: // 예외처리
        return -1
    }
}

고맙다 챗지피티야…

처음에 너무 다른 언어 형식으로 스위치를 짰다... 스위프트 문법은 심플한데 사용자가 이 심플함에 익숙하지 않아서 조진 케이스. 

그래도 계속 쓰다 보면 익숙해지겠지~

 

 


심하게 못 푼 문제 거나 내가 한 것보다 더 간단한 코드라 배우고 싶은 문제만 정리했다. 오랜만에 프로그래머스(쉬운 것만) 푸니까 재밌었다... 빨리 단련해서 올해 안에 3단계 까지는 가고 싶다. 

'231205~ > 240325~240913 [iOS]' 카테고리의 다른 글

#26 #014 21일차던가 240423  (0) 2024.04.23
#25 #013 실습_계산기 240418  (0) 2024.04.18
#23 #011 16일차 240416  (0) 2024.04.16
#22 #010 14일차 Timer 실습 240412  (0) 2024.04.12
#21 #009 13일차 240411  (0) 2024.04.11

갈수록... 글 쓰는 걸 빼먹어서 실제 일차와 번호의 괴리가 커진다. 

어젠 너무 쓰고 싶었지만 멘토링이 거의 11시에 끝나서... 수업-검도-멘토링 3 연타에 져버리고 만 것이엇던(변명컷

 

오늘은 오전에 구조체 열거형 배열 딕셔너리 친구들을 배웠다. 아 클래스와 구조체의 차이도. 

프로퍼티 래퍼는 따로 공부 더해봐야 할 것 같다... 이해가 잘 안 됨

 

어제 노션에 코드 넣는 방법 배웠는데 유용하게 잘 써먹고 있다. 실습코드 바로 넣어버리고

 

점심에 너무 졸려서 30분만 자고 일어나서 밥 먹어야지 했는데 일어나 보니 오빠 놈이 지는 양념삼겹살 혼자 꿔 처먹고 나한테는 웬 치즈떡이나 먹으라 그래서 어이가 돌아가실 뻔했다. 니는 오빠인 거에 감사해라 동생이었음 허리를 거꾸로 접어버렸을

 

오후에는 실습을... 했다. 헬난이도

챗 gpt 멱살을 붙들고 오류 대파티를 벌였는데, 얘도 인간이 참 답답했을 것이다. 인간시대의 끝이 도래했다고 하면 어쩌지. 물론 얘는 3.5라 아직 멍청해서 못할 것이다. 

원래 실습 시간에 강사님이 보여주시면 따라 치곤 했는데, 오늘은 짜놓은 코드랑 너무 달라져서 그냥 보기만 했다... 아니 실습 설명에 파일 따로 만들라그래서 다 분리해 놨는데 합쳐서 보여주시면 저는 어떡하나요(억울)

 

내일은 오후에 실습 대신 UI 강의가 있다고 한다. 내일은 점심시간에 자지 말고 커피 사 와야겠다... 집 근처 1리터 아메리카노는 2,000원인데 포장하면 500원 할인해서 1,500원이다. 엄마한테 얘네는 이렇게 팔아서 뭐 먹고살지 하니까 엄마가 모든 사람들이 너처럼 커피만 먹지는 않는다고 했다. 그리고 옆에 있던 동생 "난 생딸기라떼만 먹는데" 생딸기라떼는 5,500원이다. 그래 너가 1리터의 희망이다. 

 

 

어제 멘토링에서는 현직자이신 멘토님께 질문 폭격을 했다. 물론 나 말고 다른 멘티분들이... 궁금한 게 참 많기도 하다 싶었다. 그래서 나도 안 하면 아쉬울 거 같아서 그냥 코테나 기술면접 같은 거 여쭤봤다. 코테 준비는 무엇보다 꾸준함이 중요하다 하셨고, 기술면접은 swift 문법을 아는 게 중요하다고 하셨던 것 같다 < ? 어제 적은 거 노션에 있으니 그쪽 참고

그래서 거의 11시에 끝났고... 멘토님도 멘토링 초반에 이렇게 질문 많은 건 처음이시라고. 물론 질문은 많은 게 좋다고 하셨다. 

앞으로 강의 열심히 들으면서 멘토링도 열심히 하는 걸로...

 

아 그리고 더는 미룰 수 없다 너의 알고리즘

내 프로그래머스 계정이... 있나...? 휴면 메일 왔던 거 같은데(눈물

 

 

+) 요즘 쉬는 시간 점심시간에 자면 자꾸 일어나서 수업 들어야 되는 꿈 꾼다... 테러블 호러블 

아니 쉬는 시간엔 10분도 못 자는데 왜 이런 꿈을 꾸는 거야

오늘은 GeometryReader를 마지막으로 기초?를 마치고 Timer 실습을 했다. 

 

강사님이 만드신 코드를 고치는 거였는데, 다들 버튼 짱짱하게 하고 애니메이션 넣고 해서 살짝 기죽을 뻔 했지만...

그치만 난 심플한게 좋아... 글자 싫어 only 도형 그림

 

클론 받아서 한게 아니라 풀리퀘가 바로 안돼서 자랑은 못했지만(어차피 소심한 관종이라 안했을것) 여기에는 내새끼 올리고 일하러 가야지

 

오늘부터 그냥 강의 중간 실습 하고 남는 시간에 미리 올릴 만한 내용을 적어두기로 했다.

주중, 특히 수요일 같이 한 주의 중간에 있는 날 쉬는 것은 언제나 환영이지만, 그만큼 목요일 아침이 두 배로 버겁다. 월요일 같은 기분이랄까. 그래도 내일이 금요일이지 하면서 버텨야지 뭐.

아무튼 (이번 주) 규칙적인 생활 다시 시작이다 ._. 그래도 오늘 빼면 하루 남았다 야호

아니 강사님이ㅋㅋㅋㅋ 휴일동안 타이머 앱을 하나 만들어 오셨다. 기존 실습 시간 타이머는 상용 앱(이 표현 맞나)이라 커다랗고 화면 이동하면 가려지고 그랬는데 작아서 화면 잘 보이고 계속 플로팅 하고… 그렇다. 역시 앱 개발 강사님은 클라스가 다르다……

오늘 배운 건 디스클로저 뷰, 스크롤 뷰, 아웃라인, 내비게이션 타이틀 등등…

 

  1. 디스클로저 뷰
  • 10개까지만 지원되고 스크롤 안됐지만 repeat each 구문이 도입되고 사라진 걸로 안다는 타 수강생의 제보가 있었음
  • 접었다 폈다 가능
  1. 스크롤 뷰
  • 말 그대로 스크롤 가능한 뷰. 수직 수평 다 된다.
  • 내용물이 작으면 스크롤이 사이드에 안있고 가운데에 있는데 이거 어떻게 해야 되는지 찾아볼 것
    • 챗gpt한테 물어봤는데 스크롤 뷰 너비를 맞추고 스크롤 바를 옮기면 된다고 한다. 해보진 못했다
  1. 아웃라인
  • 윈도우 폴더 계층구조 같은 것
  • 자료구조 자체가 복잡하다. 자료구조라는 단어를 몇 년 만에 쓰는 건지 기억도 안 나는데 클났네;
  • 옵셔널을 써서 마지막 계층을 선언할 때 id만 쓸 수 있게.. 이거 예제없으면 설명하기 힘들다
  1. 내비게이션 스택
  • 원래 내비게이션 뷰였는데, 바뀌었다고 함
  • 화면 전환 with navigationlink

 

 

... 까지가 수업 중간중간 정리한 내용... 더 있긴 한데 못 적었다. 시간 없다! 나중에 마저 정리함

근데 노션에서 그대로 복붙 하니까 번호 저따구로 되네 실화인가

오늘은 사용자 반응 버튼과 텍스트 필드를... 배웠다. 

그리고 멘토링... 하......

멘토링 날짜가 정해져서 팀원분들이랑 어떤 방향으로 진행할지 회의를...^^ 어제에 이어서 1시간 정도...?

아 심심한 귀를 위해 스듀 영상 틀어놨더니 하고 싶어 져서 끄고 왔다. 더 이상 미룰 수 없다 너의 복습

 

 

1. 버튼

- 버튼 모양은 텍스트 뷰, 라벨 슈 또는 이미지 뷰와 함께 다양한 수정자로 커스터마이징 할 수 있음

- 세그먼트 컨트롤: 여러 옵션 중 하나를 선택할 수 있도록 하는 iOS 앱의 사용자 인터페이스 요소(출처: 챗 GPT).

- @State 변수를 사용하여 사용자가 선택한 세그먼트를 추적함.

- 버튼 || 세그먼트 컨트롤의 선택에 따라 @State 변수의 값을 변경하여 사용자 인터페이스를 동적으로 업데이트할 수 있음 (<< 이거 되게 신기하더라. 안드로이드 스튜디오 할 때 되게 씨름했던 것 같은데)

- .onChange 수정자로 변경사항에 따라 추가 코드 실행

 

2. 텍스트

- Swift에서 텍스트 수집은 텍스트 필드, 보안 필드, 텍스트 에디터 세 가지 뷰로 이루어짐. 

- 텍스트 필드: 한 줄 입력

- 보안 필드: 입력된 텍스트 마스킹 처리

- 텍스트 에디터: 여러 줄 입력

- 기타 사용할 수 있는 수정자는 책이나 공식문서 참고

 

 

여기까지 쓰고 생각난 게 왜 강의 들으면서 필기한건 안 보고 이러고 있는 거지? 그야 강의 시간엔 코드만 따라쳤..으니까

아니 그래도 쓴 게 있긴 한데 이미 늦었다

 

3. 멘토링

문제의 멘토링... 팀 목표랑 멘토링에서 바라는 점 정하는데 참... 채팅으로만 대화하려니까 힘들었다. 오죽했으면 내가 마이크를 켜고 얘기했을까... 솔직히 답답해 돌아가실 뻔... 그나마 내가 팀장이 아닌 게 다행이지. 사다리는 아직 날 버리지 않았다. 아무튼... 책 5 챕터를 각자 공부하고 최대 일요일까지 정리 자료를 공유하기로 했다 ^o^

 

 

아무래도 실습 위주로 진행 중이라 개념 같은 건 정리하기 애매하다. 저거 강의자료 보고 정리한 건데

그럼 코드를 치면 되지 않느냐? 지금 맥북이 아니라 곤란; 언제쯤 맥북에 프로페셔널 해질까... 뉴비는 오늘도 슬프다. 

히히 내일 쉬는 날이니까 이제 스듀 해야지. 사흘만이다. 

오늘은 어제 조금 했던 앱 빌딩 하고 클로저랑 제네릭+프로토콜 복습도 했다. 

앱이야 뭐... 그냥 강사님 하시는 거 따라 하고 하는 거라 그렇게 부담스럽진 않았다. 다들 기상천외한 에러가 나서 빨리 지나가는 편이 아니라...

 

실행해서 나오는 인터페이스가 늘 내가 쓰던 그거라서 익숙하고 반갑고 그랬다. 

처음으로 빌드 해봤는데 괜히 개발자는 프로 쓰라는게 아니다 싶다. 강사님 컴퓨터는 아직 저기 돌아가는데 나으 새삥 맥북은 이미 완료된 빌드...

역시 개발컴은 좋은게 짱이다 다비켜

 

오늘은 필기한 것도 많고 해서 여기서 정리해 보면 참 좋을 것 같은데 금요일이라 빨리 달려가서 노동을 ._. 해야 한다...

강사님은 저녁 약속 가신다는데 ._, 부럽다

 

오늘 멘토링 팀도 나왔다. 디코로 한다길래 한번 채팅방 들어가 봤는데 먼저 들어가 있던 사람이 나갔다.

....???? 좀 기분 나쁠지도

는 내가 소리 다 꺼놔서 할 말 없는...

 

멘토링... 또 자기소개해야 된단다. 벌써부터 힘들다. 100% I(실화)에겐 팀빌딩이고 뭐고 다 가혹한 것이다. 그럼에도 내가 신청해서 하는 거니까 견뎌야지 뭐

 

아 그리고 PC 디코 설정에서 알림을 꺼버리고 평화를 찾았다. 역시 설정은 들여다보고 욕을 했어야 했다. 

+ Recent posts